From f1e80c07416adacc9ba1d9c5a4635c27b571f0df Mon Sep 17 00:00:00 2001 From: Jacek Anaszewski Date: Wed, 7 Oct 2015 11:10:39 +0200 Subject: leds: core: Add two new LED_BLINK_ flags This patch adds LED_BLINK_BRIGHTNESS_CHANGE flag to indicate that blink brightness has changed, and LED_BLINK_DISABLE flag to indicate that blinking deactivation has been requested. In order to use the flags led_timer_function and set_brightness_delayed callbacks as well as led_set_brightness() function are being modified. The main goal of these modifications is to prepare set_brightness_work for extension of the scope of its responsibilities. Signed-off-by: Jacek Anaszewski Acked-by: Pavel Machek Acked-by: Sakari Ailus --- include/linux/leds.h | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/linux/leds.h b/include/linux/leds.h index fa359c79c825..7b67450234a9 100644 --- a/include/linux/leds.h +++ b/include/linux/leds.h @@ -44,10 +44,12 @@ struct led_classdev { #define LED_BLINK_ONESHOT (1 << 17) #define LED_BLINK_ONESHOT_STOP (1 << 18) #define LED_BLINK_INVERT (1 << 19) -#define LED_SYSFS_DISABLE (1 << 20) -#define SET_BRIGHTNESS_ASYNC (1 << 21) -#define SET_BRIGHTNESS_SYNC (1 << 22) -#define LED_DEV_CAP_FLASH (1 << 23) +#define LED_BLINK_BRIGHTNESS_CHANGE (1 << 20) +#define LED_BLINK_DISABLE (1 << 21) +#define LED_SYSFS_DISABLE (1 << 22) +#define SET_BRIGHTNESS_ASYNC (1 << 23) +#define SET_BRIGHTNESS_SYNC (1 << 24) +#define LED_DEV_CAP_FLASH (1 << 25) /* Set LED brightness level */ /* Must not sleep, use a workqueue if needed */ -- cgit v1.2.3 From 437a4240f26461610cc0d90950b1c88348d9babe Mon Sep 17 00:00:00 2001 From: Jacek Anaszewski Date: Wed, 7 Oct 2015 11:10:40 +0200 Subject: leds: Rename brightness_set_sync op to brightness_set_blocking The initial purpose of brightness_set_sync op, introduced along with the LED flash class extension, was to add a means for setting torch LED brightness as soon as possible, which couldn't have been guaranteed by brightness_set op. This patch renames the op to brightness_set_blocking, which describes its purpose in a more generic way. It is beneficial in view of the prospective changes in the LED core, aiming at removing the need for using work queues in LED class drivers that can sleep or use delays while setting brightness. Signed-off-by: Jacek Anaszewski Acked-by: Andrew Lunn Acked-by: Pavel Machek Acked-by: Sakari Ailus --- drivers/leds/led-class-flash.c | 2 +- drivers/leds/leds-aat1290.c | 2 +- drivers/leds/leds-ktd2692.c | 2 +- drivers/leds/leds-max77693.c | 2 +- drivers/leds/leds.h | 2 +- include/linux/leds.h | 4 ++-- 6 files changed, 7 insertions(+), 7 deletions(-) (limited to 'include') diff --git a/drivers/leds/led-class-flash.c b/drivers/leds/led-class-flash.c index 3b2573411a37..300a2c9007ca 100644 --- a/drivers/leds/led-class-flash.c +++ b/drivers/leds/led-class-flash.c @@ -298,7 +298,7 @@ int led_classdev_flash_register(struct device *parent, led_cdev = &fled_cdev->led_cdev; if (led_cdev->flags & LED_DEV_CAP_FLASH) { - if (!led_cdev->brightness_set_sync) + if (!led_cdev->brightness_set_blocking) return -EINVAL; ops = fled_cdev->ops; diff --git a/drivers/leds/leds-aat1290.c b/drivers/leds/leds-aat1290.c index ac77d36b630c..c56f9a92513f 100644 --- a/drivers/leds/leds-aat1290.c +++ b/drivers/leds/leds-aat1290.c @@ -510,7 +510,7 @@ static int aat1290_led_probe(struct platform_device *pdev) /* Initialize LED Flash class device */ led_cdev->brightness_set = aat1290_led_brightness_set; - led_cdev->brightness_set_sync = aat1290_led_brightness_set_sync; + led_cdev->brightness_set_blocking = aat1290_led_brightness_set_sync; led_cdev->max_brightness = led_cfg.max_brightness; led_cdev->flags |= LED_DEV_CAP_FLASH; INIT_WORK(&led->work_brightness_set, aat1290_brightness_set_work); diff --git a/drivers/leds/leds-ktd2692.c b/drivers/leds/leds-ktd2692.c index feca07be85f5..e37de1434312 100644 --- a/drivers/leds/leds-ktd2692.c +++ b/drivers/leds/leds-ktd2692.c @@ -382,7 +382,7 @@ static int ktd2692_probe(struct platform_device *pdev) led_cdev->max_brightness = led_cfg.max_brightness; led_cdev->brightness_set = ktd2692_led_brightness_set; - led_cdev->brightness_set_sync = ktd2692_led_brightness_set_sync; + led_cdev->brightness_set_blocking = ktd2692_led_brightness_set_sync; led_cdev->flags |= LED_CORE_SUSPENDRESUME | LED_DEV_CAP_FLASH; mutex_init(&led->lock); diff --git a/drivers/leds/leds-max77693.c b/drivers/leds/leds-max77693.c index afbb1409b2e2..9f7240b7dd64 100644 --- a/drivers/leds/leds-max77693.c +++ b/drivers/leds/leds-max77693.c @@ -932,7 +932,7 @@ static void max77693_init_fled_cdev(struct max77693_sub_led *sub_led, led_cdev->name = led_cfg->label[fled_id]; led_cdev->brightness_set = max77693_led_brightness_set; - led_cdev->brightness_set_sync = max77693_led_brightness_set_sync; + led_cdev->brightness_set_blocking = max77693_led_brightness_set_sync; led_cdev->max_brightness = (led->iout_joint ? led_cfg->iout_torch_max[FLED1] + led_cfg->iout_torch_max[FLED2] : diff --git a/drivers/leds/leds.h b/drivers/leds/leds.h index 4238fbc31d35..cf6d44886bcb 100644 --- a/drivers/leds/leds.h +++ b/drivers/leds/leds.h @@ -34,7 +34,7 @@ static inline int led_set_brightness_sync(struct led_classdev *led_cdev, led_cdev->brightness = min(value, led_cdev->max_brightness); if (!(led_cdev->flags & LED_SUSPENDED)) - ret = led_cdev->brightness_set_sync(led_cdev, + ret = led_cdev->brightness_set_blocking(led_cdev, led_cdev->brightness); return ret; } diff --git a/include/linux/leds.h b/include/linux/leds.h index 7b67450234a9..403fa8690295 100644 --- a/include/linux/leds.h +++ b/include/linux/leds.h @@ -59,8 +59,8 @@ struct led_classdev { * Set LED brightness level immediately - it can block the caller for * the time required for accessing a LED device register. */ - int (*brightness_set_sync)(struct led_classdev *led_cdev, - enum led_brightness brightness); + int (*brightness_set_blocking)(struct led_classdev *led_cdev, + enum led_brightness brightness); /* Get LED brightness level */ enum led_brightness (*brightness_get)(struct led_classdev *led_cdev); -- cgit v1.2.3 From 1afcadfcd184c3b52e38bae15c247a5fa4a0e054 Mon Sep 17 00:00:00 2001 From: Jacek Anaszewski Date: Mon, 19 Oct 2015 09:04:01 +0200 Subject: leds: core: Use set_brightness_work for the blocking op This patch makes LED core capable of setting brightness for drivers that implement brightness_set_blocking op. It removes from LED class drivers responsibility for using work queues on their own. In order to achieve this set_brightness_delayed callback is being modified to directly call one of available ops for brightness setting. led_set_brightness_async() function didn't set brightness in an asynchronous way in all cases. It was mistakenly assuming that all LED subsystem drivers used work queue in their brightness_set op, whereas only half of them did that. Since it has no users now, it is being removed. Signed-off-by: Jacek Anaszewski Acked-by: Sakari Ailus --- drivers/leds/led-core.c | 12 +++++++++++- drivers/leds/leds.h | 10 ---------- include/linux/leds.h | 2 +- 3 files changed, 12 insertions(+), 12 deletions(-) (limited to 'include') diff --git a/drivers/leds/led-core.c b/drivers/leds/led-core.c index 3d168592db65..f57a96cb7b7d 100644 --- a/drivers/leds/led-core.c +++ b/drivers/leds/led-core.c @@ -83,6 +83,7 @@ static void set_brightness_delayed(struct work_struct *ws) { struct led_classdev *led_cdev = container_of(ws, struct led_classdev, set_brightness_work); + int ret = 0; if (led_cdev->flags & LED_BLINK_DISABLE) { led_cdev->delayed_set_value = LED_OFF; @@ -90,7 +91,16 @@ static void set_brightness_delayed(struct work_struct *ws) led_cdev->flags &= ~LED_BLINK_DISABLE; } - led_set_brightness_async(led_cdev, led_cdev->delayed_set_value); + if (led_cdev->brightness_set) + led_cdev->brightness_set(led_cdev, led_cdev->delayed_set_value); + else if (led_cdev->brightness_set_blocking) + ret = led_cdev->brightness_set_blocking(led_cdev, + led_cdev->delayed_set_value); + else + ret = -ENOTSUPP; + if (ret < 0) + dev_err(led_cdev->dev, + "Setting an LED's brightness failed (%d)\n", ret); } static void led_set_software_blink(struct led_classdev *led_cdev, diff --git a/drivers/leds/leds.h b/drivers/leds/leds.h index 8e252a2f8662..683a605fd33c 100644 --- a/drivers/leds/leds.h +++ b/drivers/leds/leds.h @@ -16,16 +16,6 @@ #include #include -static inline void led_set_brightness_async(struct led_classdev *led_cdev, - enum led_brightness value) -{ - value = min(value, led_cdev->max_brightness); - led_cdev->brightness = value; - - if (!(led_cdev->flags & LED_SUSPENDED)) - led_cdev->brightness_set(led_cdev, value); -} - static inline int led_set_brightness_sync(struct led_classdev *led_cdev, enum led_brightness value) { diff --git a/include/linux/leds.h b/include/linux/leds.h index 403fa8690295..b35e0f5b8d6c 100644 --- a/include/linux/leds.h +++ b/include/linux/leds.h @@ -158,7 +158,7 @@ extern void led_blink_set_oneshot(struct led_classdev *led_cdev, * * Set an LED's brightness, and, if necessary, cancel the * software blink timer that implements blinking when the - * hardware doesn't. + * hardware doesn't. This function is guaranteed not to sleep. */ extern void led_set_brightness(struct led_classdev *led_cdev, enum led_brightness brightness); -- cgit v1.2.3 From 13ae79bbe4c214047f51623304d83b46eb02897d Mon Sep 17 00:00:00 2001 From: Jacek Anaszewski Date: Wed, 7 Oct 2015 11:10:43 +0200 Subject: leds: core: Drivers shouldn't enforce SYNC/ASYNC brightness setting This patch removes SET_BRIGHTNESS_ASYNC and SET_BRIGHTNESS_SYNC flags. led_set_brightness() now calls led_set_brightness_nosleep() instead of choosing between sync and async op basing on the flags defined by the driver. From now on, if a user wants to make sure that brightness will be set synchronously, they have to use led_set_brightness_sync() API. It is now being made publicly available since it has become apparent that it is a caller who should decide whether brightness is to be set in a synchronous or an asynchronous way. Signed-off-by: Jacek Anaszewski Acked-by: Sakari Ailus --- drivers/leds/led-class-flash.c | 4 ---- drivers/leds/led-class.c | 2 -- drivers/leds/led-core.c | 32 +++++++++++++++++++------------- drivers/leds/leds.h | 13 ------------- include/linux/leds.h | 19 ++++++++++++++++--- 5 files changed, 35 insertions(+), 35 deletions(-) (limited to 'include') diff --git a/drivers/leds/led-class-flash.c b/drivers/leds/led-class-flash.c index 300a2c9007ca..f53783b8d5e8 100644 --- a/drivers/leds/led-class-flash.c +++ b/drivers/leds/led-class-flash.c @@ -316,10 +316,6 @@ int led_classdev_flash_register(struct device *parent, if (ret < 0) return ret; - /* Setting a torch brightness needs to have immediate effect */ - led_cdev->flags &= ~SET_BRIGHTNESS_ASYNC; - led_cdev->flags |= SET_BRIGHTNESS_SYNC; - return 0; } EXPORT_SYMBOL_GPL(led_classdev_flash_register); diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c index 83a1dc725864..d946991091fb 100644 --- a/drivers/leds/led-class.c +++ b/drivers/leds/led-class.c @@ -215,8 +215,6 @@ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev) if (!led_cdev->max_brightness) led_cdev->max_brightness = LED_FULL; - led_cdev->flags |= SET_BRIGHTNESS_ASYNC; - led_update_brightness(led_cdev); led_init_core(led_cdev); diff --git a/drivers/leds/led-core.c b/drivers/leds/led-core.c index f57a96cb7b7d..19e1e60dfaa3 100644 --- a/drivers/leds/led-core.c +++ b/drivers/leds/led-core.c @@ -205,8 +205,6 @@ EXPORT_SYMBOL_GPL(led_stop_software_blink); void led_set_brightness(struct led_classdev *led_cdev, enum led_brightness brightness) { - int ret = 0; - /* * In case blinking is on delay brightness setting * until the next timer tick. @@ -227,17 +225,7 @@ void led_set_brightness(struct led_classdev *led_cdev, return; } - if (led_cdev->flags & SET_BRIGHTNESS_ASYNC) { - led_set_brightness_nosleep(led_cdev, brightness); - return; - } else if (led_cdev->flags & SET_BRIGHTNESS_SYNC) - ret = led_set_brightness_sync(led_cdev, brightness); - else - ret = -EINVAL; - - if (ret < 0) - dev_dbg(led_cdev->dev, "Setting LED brightness failed (%d)\n", - ret); + led_set_brightness_nosleep(led_cdev, brightness); } EXPORT_SYMBOL_GPL(led_set_brightness); @@ -268,6 +256,24 @@ void led_set_brightness_nosleep(struct led_classdev *led_cdev, } EXPORT_SYMBOL_GPL(led_set_brightness_nosleep); +int led_set_brightness_sync(struct led_classdev *led_cdev, + enum led_brightness value) +{ + if (led_cdev->blink_delay_on || led_cdev->blink_delay_off) + return -EBUSY; + + led_cdev->brightness = min(value, led_cdev->max_brightness); + + if (led_cdev->flags & LED_SUSPENDED) + return 0; + + if (led_cdev->brightness_set_blocking) + return led_cdev->brightness_set_blocking(led_cdev, + led_cdev->brightness); + return -ENOTSUPP; +} +EXPORT_SYMBOL_GPL(led_set_brightness_sync); + int led_update_brightness(struct led_classdev *led_cdev) { int ret = 0; diff --git a/drivers/leds/leds.h b/drivers/leds/leds.h index 683a605fd33c..db3f20da7221 100644 --- a/drivers/leds/leds.h +++ b/drivers/leds/leds.h @@ -16,19 +16,6 @@ #include #include -static inline int led_set_brightness_sync(struct led_classdev *led_cdev, - enum led_brightness value) -{ - int ret = 0; - - led_cdev->brightness = min(value, led_cdev->max_brightness); - - if (!(led_cdev->flags & LED_SUSPENDED)) - ret = led_cdev->brightness_set_blocking(led_cdev, - led_cdev->brightness); - return ret; -} - static inline int led_get_brightness(struct led_classdev *led_cdev) { return led_cdev->brightness; diff --git a/include/linux/leds.h b/include/linux/leds.h index b35e0f5b8d6c..088f1da02bed 100644 --- a/include/linux/leds.h +++ b/include/linux/leds.h @@ -47,9 +47,7 @@ struct led_classdev { #define LED_BLINK_BRIGHTNESS_CHANGE (1 << 20) #define LED_BLINK_DISABLE (1 << 21) #define LED_SYSFS_DISABLE (1 << 22) -#define SET_BRIGHTNESS_ASYNC (1 << 23) -#define SET_BRIGHTNESS_SYNC (1 << 24) -#define LED_DEV_CAP_FLASH (1 << 25) +#define LED_DEV_CAP_FLASH (1 << 23) /* Set LED brightness level */ /* Must not sleep, use a workqueue if needed */ @@ -162,6 +160,21 @@ extern void led_blink_set_oneshot(struct led_classdev *led_cdev, */ extern void led_set_brightness(struct led_classdev *led_cdev, enum led_brightness brightness); + +/** + * led_set_brightness_sync - set LED brightness synchronously + * @led_cdev: the LED to set + * @brightness: the brightness to set it to + * + * Set an LED's brightness immediately. This function will block + * the caller for the time required for accessing device registers, + * and it can sleep. + * + * Returns: 0 on success or negative error value on failure + */ +extern int led_set_brightness_sync(struct led_classdev *led_cdev, + enum led_brightness value); + /** * led_update_brightness - update LED brightness * @led_cdev: the LED to query -- cgit v1.2.3 From 0dd756f7677a519a1d52a94e74d179e0af39e2ec Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Thu, 20 Aug 2015 12:59:45 +0200 Subject: leds: wm8350: Remove work queue Now the core implements the work queue, remove it from the drivers, and switch to using brightness_set_blocking op. Signed-off-by: Andrew Lunn Signed-off-by: Jacek Anaszewski Acked-by: Antonio Ospite Reviewed-by: Mark Brown --- drivers/leds/leds-wm8350.c | 64 ++++++++++++++++------------------------- include/linux/mfd/wm8350/pmic.h | 1 - 2 files changed, 25 insertions(+), 40 deletions(-) (limited to 'include') diff --git a/drivers/leds/leds-wm8350.c b/drivers/leds/leds-wm8350.c index 0d121835673f..e1e4e9d0b8b1 100644 --- a/drivers/leds/leds-wm8350.c +++ b/drivers/leds/leds-wm8350.c @@ -89,40 +89,42 @@ static const int isink_cur[] = { #define to_wm8350_led(led_cdev) \ container_of(led_cdev, struct wm8350_led, cdev) -static void wm8350_led_enable(struct wm8350_led *led) +static int wm8350_led_enable(struct wm8350_led *led) { - int ret; + int ret = 0; if (led->enabled) - return; + return ret; ret = regulator_enable(led->isink); if (ret != 0) { dev_err(led->cdev.dev, "Failed to enable ISINK: %d\n", ret); - return; + return ret; } ret = regulator_enable(led->dcdc); if (ret != 0) { dev_err(led->cdev.dev, "Failed to enable DCDC: %d\n", ret); regulator_disable(led->isink); - return; + return ret; } led->enabled = 1; + + return ret; } -static void wm8350_led_disable(struct wm8350_led *led) +static int wm8350_led_disable(struct wm8350_led *led) { - int ret; + int ret = 0; if (!led->enabled) - return; + return ret; ret = regulator_disable(led->dcdc); if (ret != 0) { dev_err(led->cdev.dev, "Failed to disable DCDC: %d\n", ret); - return; + return ret; } ret = regulator_disable(led->isink); @@ -132,27 +134,29 @@ static void wm8350_led_disable(struct wm8350_led *led) if (ret != 0) dev_err(led->cdev.dev, "Failed to reenable DCDC: %d\n", ret); - return; + return ret; } led->enabled = 0; + + return ret; } -static void led_work(struct work_struct *work) +static int wm8350_led_set(struct led_classdev *led_cdev, + enum led_brightness value) { - struct wm8350_led *led = container_of(work, struct wm8350_led, work); + struct wm8350_led *led = to_wm8350_led(led_cdev); + unsigned long flags; int ret; int uA; - unsigned long flags; - mutex_lock(&led->mutex); + led->value = value; spin_lock_irqsave(&led->value_lock, flags); if (led->value == LED_OFF) { spin_unlock_irqrestore(&led->value_lock, flags); - wm8350_led_disable(led); - goto out; + return wm8350_led_disable(led); } /* This scales linearly into the index of valid current @@ -166,36 +170,21 @@ static void led_work(struct work_struct *work) ret = regulator_set_current_limit(led->isink, isink_cur[uA], isink_cur[uA]); - if (ret != 0) + if (ret != 0) { dev_err(led->cdev.dev, "Failed to set %duA: %d\n", isink_cur[uA], ret); + return ret; + } - wm8350_led_enable(led); - -out: - mutex_unlock(&led->mutex); -} - -static void wm8350_led_set(struct led_classdev *led_cdev, - enum led_brightness value) -{ - struct wm8350_led *led = to_wm8350_led(led_cdev); - unsigned long flags; - - spin_lock_irqsave(&led->value_lock, flags); - led->value = value; - schedule_work(&led->work); - spin_unlock_irqrestore(&led->value_lock, flags); + return wm8350_led_enable(led); } static void wm8350_led_shutdown(struct platform_device *pdev) { struct wm8350_led *led = platform_get_drvdata(pdev); - mutex_lock(&led->mutex); led->value = LED_OFF; wm8350_led_disable(led); - mutex_unlock(&led->mutex); } static int wm8350_led_probe(struct platform_device *pdev) @@ -232,7 +221,7 @@ static int wm8350_led_probe(struct platform_device *pdev) if (led == NULL) return -ENOMEM; - led->cdev.brightness_set = wm8350_led_set; + led->cdev.brightness_set_blocking = wm8350_led_set; led->cdev.default_trigger = pdata->default_trigger; led->cdev.name = pdata->name; led->cdev.flags |= LED_CORE_SUSPENDRESUME; @@ -251,8 +240,6 @@ static int wm8350_led_probe(struct platform_device *pdev) pdata->max_uA); spin_lock_init(&led->value_lock); - mutex_init(&led->mutex); - INIT_WORK(&led->work, led_work); led->value = LED_OFF; platform_set_drvdata(pdev, led); @@ -264,7 +251,6 @@ static int wm8350_led_remove(struct platform_device *pdev) struct wm8350_led *led = platform_get_drvdata(pdev); led_classdev_unregister(&led->cdev); - flush_work(&led->work); wm8350_led_disable(led); return 0; } diff --git a/include/linux/mfd/wm8350/pmic.h b/include/linux/mfd/wm8350/pmic.h index 579b50ca2e02..7a09e7f1f984 100644 --- a/include/linux/mfd/wm8350/pmic.h +++ b/include/linux/mfd/wm8350/pmic.h @@ -715,7 +715,6 @@ struct wm8350_led_platform_data { struct wm8350_led { struct platform_device *pdev; - struct mutex mutex; struct work_struct work; spinlock_t value_lock; enum led_brightness value; -- cgit v1.2.3 From 9534cc31dda2bb129480ce2db92bf7bc1ef470ed Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Sat, 2 Jan 2016 01:36:41 +0100 Subject: leds: core: add managed version of led_trigger_register Complementing devm_led_classdev_register add a managed version of led_trigger_register. I omit a managed version of led_classdev_unregister as the equivalent devm_led_classdev_unregister isn't used in the kernel as of today. Signed-off-by: Heiner Kallweit Signed-off-by: Jacek Anaszewski --- drivers/leds/led-triggers.c | 28 ++++++++++++++++++++++++++++ include/linux/leds.h | 2 ++ 2 files changed, 30 insertions(+) (limited to 'include') diff --git a/drivers/leds/led-triggers.c b/drivers/leds/led-triggers.c index e8b1120f486d..e1e933424ac9 100644 --- a/drivers/leds/led-triggers.c +++ b/drivers/leds/led-triggers.c @@ -249,6 +249,34 @@ void led_trigger_unregister(struct led_trigger *trig) } EXPORT_SYMBOL_GPL(led_trigger_unregister); +static void devm_led_trigger_release(struct device *dev, void *res) +{ + led_trigger_unregister(*(struct led_trigger **)res); +} + +int devm_led_trigger_register(struct device *dev, + struct led_trigger *trig) +{ + struct led_trigger **dr; + int rc; + + dr = devres_alloc(devm_led_trigger_release, sizeof(*dr), + GFP_KERNEL); + if (!dr) + return -ENOMEM; + + *dr = trig; + + rc = led_trigger_register(trig); + if (rc) + devres_free(dr); + else + devres_add(dev, dr); + + return rc; +} +EXPORT_SYMBOL_GPL(devm_led_trigger_register); + /* Simple LED Tigger Interface */ void led_trigger_event(struct led_trigger *trig, diff --git a/include/linux/leds.h b/include/linux/leds.h index 088f1da02bed..bc1476fda96e 100644 --- a/include/linux/leds.h +++ b/include/linux/leds.h @@ -246,6 +246,8 @@ ssize_t led_trigger_show(struct device *dev, struct device_attribute *attr, /* Registration functions for complex triggers */ extern int led_trigger_register(struct led_trigger *trigger); extern void led_trigger_unregister(struct led_trigger *trigger); +extern int devm_led_trigger_register(struct device *dev, + struct led_trigger *trigger); extern void led_trigger_register_simple(const char *name, struct led_trigger **trigger); -- cgit v1.2.3