6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Heiner Kallweit hkallweit1@gmail.com
[ Upstream commit 822c91e72eac568ed8d83765634f00decb45666c ]
If a simple trigger is assigned to a LED, then the LED may be off until the next led_trigger_event() call. This may be an issue for simple triggers with rare led_trigger_event() calls, e.g. power supply charging indicators (drivers/power/supply/power_supply_leds.c). Therefore persist the brightness value of the last led_trigger_event() call and use this value if the trigger is assigned to a LED. In addition add a getter for the trigger brightness value.
Signed-off-by: Heiner Kallweit hkallweit1@gmail.com Reviewed-by: Takashi Iwai tiwai@suse.de Link: https://lore.kernel.org/r/b1358b25-3f30-458d-8240-5705ae007a8a@gmail.com Signed-off-by: Lee Jones lee@kernel.org Stable-dep-of: ab477b766edd ("leds: triggers: Flush pending brightness before activating trigger") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/leds/led-triggers.c | 6 ++++-- include/linux/leds.h | 15 +++++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-)
diff --git a/drivers/leds/led-triggers.c b/drivers/leds/led-triggers.c index 081acf1f345b3..38f7896f374f6 100644 --- a/drivers/leds/led-triggers.c +++ b/drivers/leds/led-triggers.c @@ -194,11 +194,11 @@ int led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trig) spin_unlock(&trig->leddev_list_lock); led_cdev->trigger = trig;
+ ret = 0; if (trig->activate) ret = trig->activate(led_cdev); else - ret = 0; - + led_set_brightness(led_cdev, trig->brightness); if (ret) goto err_activate;
@@ -373,6 +373,8 @@ void led_trigger_event(struct led_trigger *trig, if (!trig) return;
+ trig->brightness = brightness; + rcu_read_lock(); list_for_each_entry_rcu(led_cdev, &trig->led_cdevs, trig_list) led_set_brightness(led_cdev, brightness); diff --git a/include/linux/leds.h b/include/linux/leds.h index 6a4973feecd65..d3056bc6f0a1a 100644 --- a/include/linux/leds.h +++ b/include/linux/leds.h @@ -474,6 +474,9 @@ struct led_trigger { int (*activate)(struct led_classdev *led_cdev); void (*deactivate)(struct led_classdev *led_cdev);
+ /* Brightness set by led_trigger_event */ + enum led_brightness brightness; + /* LED-private triggers have this set */ struct led_hw_trigger_type *trigger_type;
@@ -527,6 +530,12 @@ static inline void *led_get_trigger_data(struct led_classdev *led_cdev) return led_cdev->trigger_data; }
+static inline enum led_brightness +led_trigger_get_brightness(const struct led_trigger *trigger) +{ + return trigger ? trigger->brightness : LED_OFF; +} + #define module_led_trigger(__led_trigger) \ module_driver(__led_trigger, led_trigger_register, \ led_trigger_unregister) @@ -563,6 +572,12 @@ static inline void *led_get_trigger_data(struct led_classdev *led_cdev) return NULL; }
+static inline enum led_brightness +led_trigger_get_brightness(const struct led_trigger *trigger) +{ + return LED_OFF; +} + #endif /* CONFIG_LEDS_TRIGGERS */
/* Trigger specific enum */