leds: triggers: add device attribute support
authorUwe Kleine-König <u.kleine-koenig@pengutronix.de>
Mon, 2 Jul 2018 20:05:22 +0000 (22:05 +0200)
committerJacek Anaszewski <jacek.anaszewski@gmail.com>
Thu, 5 Jul 2018 21:21:10 +0000 (23:21 +0200)
As many triggers use device attributes, add support for these in
led_trigger_set which allows simplifying the drivers accordingly.

Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Acked-by: Pavel Machek <pavel@ucw.cz>
Signed-off-by: Jacek Anaszewski <jacek.anaszewski@gmail.com>
drivers/leds/led-triggers.c
include/linux/leds.h

index a8786f4b345315bda9c2ece778a4add57a41394b..3f3e8728d82c860c617cae47532ea58beb3325bb 100644 (file)
@@ -127,6 +127,7 @@ int led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trig)
                led_stop_software_blink(led_cdev);
                if (led_cdev->trigger->deactivate)
                        led_cdev->trigger->deactivate(led_cdev);
+               device_remove_groups(led_cdev->dev, led_cdev->trigger->groups);
                led_cdev->trigger = NULL;
                led_set_brightness(led_cdev, LED_OFF);
        }
@@ -143,6 +144,12 @@ int led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trig)
 
                if (ret)
                        goto err_activate;
+
+               ret = device_add_groups(led_cdev->dev, trig->groups);
+               if (ret) {
+                       dev_err(led_cdev->dev, "Failed to add trigger attributes\n");
+                       goto err_add_groups;
+               }
        }
 
        if (event) {
@@ -156,7 +163,12 @@ int led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trig)
 
        return 0;
 
+err_add_groups:
+
+       if (trig->deactivate)
+               trig->deactivate(led_cdev);
 err_activate:
+
        led_cdev->trigger = NULL;
        write_lock_irqsave(&led_cdev->trigger->leddev_list_lock, flags);
        list_del(&led_cdev->trig_list);
index ba5baaaa43bffa377b9289076a336eb2a4170515..33484a5c74787189585dd2dd56c6424560778bdc 100644 (file)
@@ -262,8 +262,19 @@ struct led_trigger {
 
        /* Link to next registered trigger */
        struct list_head  next_trig;
+
+       const struct attribute_group **groups;
 };
 
+/*
+ * Currently the attributes in struct led_trigger::groups are added directly to
+ * the LED device. As this might change in the future, the following
+ * macros abstract getting the LED device and its trigger_data from the dev
+ * parameter passed to the attribute accessor functions.
+ */
+#define led_trigger_get_led(dev)       ((struct led_classdev *)dev_get_drvdata((dev)))
+#define led_trigger_get_drvdata(dev)   (led_get_trigger_data(led_trigger_get_led(dev)))
+
 ssize_t led_trigger_store(struct device *dev, struct device_attribute *attr,
                        const char *buf, size_t count);
 ssize_t led_trigger_show(struct device *dev, struct device_attribute *attr,