leds: trigger: Store brightness set by led_trigger_event()
authorHeiner Kallweit <hkallweit1@gmail.com>
Mon, 4 Mar 2024 20:57:30 +0000 (21:57 +0100)
committerLee Jones <lee@kernel.org>
Thu, 28 Mar 2024 10:39:49 +0000 (10:39 +0000)
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>
drivers/leds/led-triggers.c
include/linux/leds.h

index 0f5ac30053ad26b5f9c6d2c3dbf019856fd493aa..b1b323b19301d29949f50b0855c5887e7a15e23d 100644 (file)
@@ -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;
 
@@ -387,6 +387,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);
index db6b114bb3d914984e5e11c686beb2b9d79cf29c..7964ee38b2a3a5a379fff207445452a44aa79ac2 100644 (file)
@@ -455,6 +455,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;
 
@@ -508,6 +511,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)
@@ -544,6 +553,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 */