]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
leds: led-triggers: Improvements for default trigger
authorCraig McQueen <craig@mcqueen.au>
Mon, 17 Mar 2025 02:26:30 +0000 (13:26 +1100)
committerLee Jones <lee@kernel.org>
Tue, 15 Apr 2025 16:57:54 +0000 (17:57 +0100)
Accept "default" written to sysfs trigger attr.
If the text "default" is written to the LED's sysfs 'trigger' attr, then
call led_trigger_set_default() to set the LED to its default trigger.

If the default trigger is set to "none", then led_trigger_set_default()
will remove a trigger. This is in contrast to the default trigger being
unset, in which case led_trigger_set_default() does nothing.

Signed-off-by: Craig McQueen <craig@mcqueen.au>
Reviewed-by: Jacek Anaszewski <jacek.anaszewski@gmail.com>
Link: https://lore.kernel.org/r/20250317022630.424015-1-craig@mcqueen.au
Signed-off-by: Lee Jones <lee@kernel.org>
Documentation/ABI/testing/sysfs-class-led
drivers/leds/led-triggers.c

index 2e24ac3bd7efa4e64d8dc084462cc0ef92dc9202..0313b82644f244ddd046c7b892831368691108c3 100644 (file)
@@ -72,6 +72,12 @@ Description:
                /sys/class/leds/<led> once a given trigger is selected. For
                their documentation see `sysfs-class-led-trigger-*`.
 
+               Writing "none" removes the trigger for this LED.
+
+               Writing "default" sets the trigger to the LED's default trigger
+               (which would often be configured in the device tree for the
+               hardware).
+
 What:          /sys/class/leds/<led>/inverted
 Date:          January 2011
 KernelVersion: 2.6.38
index b2d40f87a5ff22b9fe38bce0a655da72ea385fee..3799dcc1cf07f0bde2d4ed06ecca075bbdc20fcb 100644 (file)
@@ -54,6 +54,11 @@ ssize_t led_trigger_write(struct file *filp, struct kobject *kobj,
                goto unlock;
        }
 
+       if (sysfs_streq(buf, "default")) {
+               led_trigger_set_default(led_cdev);
+               goto unlock;
+       }
+
        down_read(&triggers_list_lock);
        list_for_each_entry(trig, &trigger_list, next_trig) {
                if (sysfs_streq(buf, trig->name) && trigger_relevant(led_cdev, trig)) {
@@ -98,6 +103,9 @@ static int led_trigger_format(char *buf, size_t size,
        int len = led_trigger_snprintf(buf, size, "%s",
                                       led_cdev->trigger ? "none" : "[none]");
 
+       if (led_cdev->default_trigger)
+               len += led_trigger_snprintf(buf + len, size - len, " default");
+
        list_for_each_entry(trig, &trigger_list, next_trig) {
                bool hit;
 
@@ -281,6 +289,11 @@ void led_trigger_set_default(struct led_classdev *led_cdev)
        if (!led_cdev->default_trigger)
                return;
 
+       if (!strcmp(led_cdev->default_trigger, "none")) {
+               led_trigger_remove(led_cdev);
+               return;
+       }
+
        down_read(&triggers_list_lock);
        down_write(&led_cdev->trigger_lock);
        list_for_each_entry(trig, &trigger_list, next_trig) {