[PATCH v2 02/16] leds: triggers: add device attribute support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



As many triggers use device attributes, add support for these in
led_trigger_set which allows to simplify the drivers accordingly.

Signed-off-by: Uwe Kleine-König <u.kleine-koenig@xxxxxxxxxxxxxx>
---
 drivers/leds/led-triggers.c | 12 ++++++++++++
 include/linux/leds.h        | 11 +++++++++++
 2 files changed, 23 insertions(+)

diff --git a/drivers/leds/led-triggers.c b/drivers/leds/led-triggers.c
index 0ab8ff5eb142..2be544bbf565 100644
--- a/drivers/leds/led-triggers.c
+++ b/drivers/leds/led-triggers.c
@@ -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);
 	}
@@ -146,6 +147,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) {
@@ -159,7 +166,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);
diff --git a/include/linux/leds.h b/include/linux/leds.h
index 12c0b0137012..559fde6f799a 100644
--- a/include/linux/leds.h
+++ b/include/linux/leds.h
@@ -264,8 +264,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,
-- 
2.17.0




[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux OMAP]     [Linux MIPS]     [ECOS]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux