If the LED is acquired by a consumer device with devm_led_get(), it is
automatically release when the device is detach.

Signed-off-by: Jean-Jacques Hiblot <jjhib...@ti.com>
---
 drivers/leds/led-class.c | 42 ++++++++++++++++++++++++++++++++++++++++
 include/linux/leds.h     |  2 ++
 2 files changed, 44 insertions(+)

diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c
index 0f67b13b0f1f..521cb76fbaf7 100644
--- a/drivers/leds/led-class.c
+++ b/drivers/leds/led-class.c
@@ -264,6 +264,48 @@ void led_put(struct led_classdev *led_cdev)
 }
 EXPORT_SYMBOL_GPL(led_put);
 
+static void devm_led_release(struct device *dev, void *res)
+{
+       struct led_classdev **p = res;
+
+       led_put(*p);
+}
+
+/**
+ * devm_led_get - Resource-managed request of a LED device
+ * @dev:       LED consumer
+ * @idx:       index of the LED to obtain in the consumer
+ *
+ * The device node of the device is parse to find the request LED device.
+ * The LED device returned from this function is automatically released
+ * on driver detach.
+ *
+ * @return a pointer to a LED device or ERR_PTR(errno) on failure.
+ */
+struct led_classdev *__must_check devm_led_get(struct device *dev,
+                                              int index)
+{
+       struct led_classdev *led;
+       struct led_classdev **dr;
+
+       led = of_led_get(dev->of_node, index);
+       if (IS_ERR(led))
+               return led;
+
+       dr = devres_alloc(devm_led_release, sizeof(struct led_classdev *),
+                         GFP_KERNEL);
+       if (!dr) {
+               led_put(led);
+               return ERR_PTR(-ENOMEM);
+       }
+
+       *dr = led;
+       devres_add(dev, dr);
+
+       return led;
+}
+EXPORT_SYMBOL_GPL(devm_led_get);
+
 static int match_name(struct device *dev, const void *data)
 {
        if (!dev_name(dev))
diff --git a/include/linux/leds.h b/include/linux/leds.h
index 0a71c7cdd191..7fcec566d774 100644
--- a/include/linux/leds.h
+++ b/include/linux/leds.h
@@ -148,6 +148,8 @@ extern void led_classdev_resume(struct led_classdev 
*led_cdev);
 
 extern struct led_classdev *of_led_get(struct device_node *np, int index);
 extern void led_put(struct led_classdev *led_cdev);
+struct led_classdev *__must_check devm_led_get(struct device *dev,
+                                              int index);
 
 /**
  * led_blink_set - set blinking with software fallback
-- 
2.17.1

Reply via email to