diff mbox series

leds: trigger/tty: Use led_set_brightness_nosleep() to set brightness

Message ID 20230414164853.3668229-1-u.kleine-koenig@pengutronix.de
State New
Headers show
Series leds: trigger/tty: Use led_set_brightness_nosleep() to set brightness | expand

Commit Message

Uwe Kleine-König April 14, 2023, 4:48 p.m. UTC
After commit ba8a86e4dadb ("leds: trigger/tty: Use
led_set_brightness_sync() from workqueue") this is the second try to
pick the right function to set the LED brightness from a trigger.

led_set_brightness_sync() has the problem that it doesn't work for LEDs
without a .brightness_set_blocking() callback. This is (among others)
the case for LEDs connected to non-sleeping GPIOs.

Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
---
Hello,

after a few (non-public and public) reports that the tty trigger doesn't
work and Jacek pointed out in
https://lore.kernel.org/all/ad4a1069-72c6-a431-336f-ed78a57a1ba0@gmail.com/#t
that led_set_brightness_nosleep() is the right function, here comes a
patch to actually implement that.

Does this justify a Fixes line? In that case that would be:

	Fixes: ba8a86e4dadb ("leds: trigger/tty: Use led_set_brightness_sync() from workqueue")

(As ba8a86e4dadb declares to be a fix for fd4a641ac88f ("leds: trigger:
implement a tty trigger") I think a further reference to fd4a641ac88f
isn't necesary.)

Best regards
Uwe

 drivers/leds/trigger/ledtrig-tty.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)


base-commit: fe15c26ee26efa11741a7b632e9f23b01aca4cc6

Comments

Jacek Anaszewski April 16, 2023, 3:13 p.m. UTC | #1
Hi Uwe,

On 4/14/23 18:48, Uwe Kleine-König wrote:
> After commit ba8a86e4dadb ("leds: trigger/tty: Use
> led_set_brightness_sync() from workqueue") this is the second try to
> pick the right function to set the LED brightness from a trigger.
> 
> led_set_brightness_sync() has the problem that it doesn't work for LEDs
> without a .brightness_set_blocking() callback. This is (among others)
> the case for LEDs connected to non-sleeping GPIOs.
> 
> Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
> ---
> Hello,
> 
> after a few (non-public and public) reports that the tty trigger doesn't
> work and Jacek pointed out in
> https://lore.kernel.org/all/ad4a1069-72c6-a431-336f-ed78a57a1ba0@gmail.com/#t
> that led_set_brightness_nosleep() is the right function, here comes a
> patch to actually implement that.
> 
> Does this justify a Fixes line? In that case that would be:
> 
> 	Fixes: ba8a86e4dadb ("leds: trigger/tty: Use led_set_brightness_sync() from workqueue")
> 
> (As ba8a86e4dadb declares to be a fix for fd4a641ac88f ("leds: trigger:
> implement a tty trigger") I think a further reference to fd4a641ac88f
> isn't necesary.)
> 
> Best regards
> Uwe
> 
>   drivers/leds/trigger/ledtrig-tty.c | 6 +++---
>   1 file changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/leds/trigger/ledtrig-tty.c b/drivers/leds/trigger/ledtrig-tty.c
> index f62db7e520b5..c8bbdeac93b9 100644
> --- a/drivers/leds/trigger/ledtrig-tty.c
> +++ b/drivers/leds/trigger/ledtrig-tty.c
> @@ -1,11 +1,11 @@
>   // SPDX-License-Identifier: GPL-2.0
>   
>   #include <linux/delay.h>
> -#include <linux/leds.h>
>   #include <linux/module.h>
>   #include <linux/slab.h>
>   #include <linux/tty.h>
>   #include <uapi/linux/serial.h>
> +#include "../leds.h"
>   
>   struct ledtrig_tty_data {
>   	struct led_classdev *led_cdev;
> @@ -122,12 +122,12 @@ static void ledtrig_tty_work(struct work_struct *work)
>   
>   	if (icount.rx != trigger_data->rx ||
>   	    icount.tx != trigger_data->tx) {
> -		led_set_brightness_sync(trigger_data->led_cdev, LED_ON);
> +		led_set_brightness_nosleep(trigger_data->led_cdev, LED_ON);
>   
>   		trigger_data->rx = icount.rx;
>   		trigger_data->tx = icount.tx;
>   	} else {
> -		led_set_brightness_sync(trigger_data->led_cdev, LED_OFF);
> +		led_set_brightness_nosleep(trigger_data->led_cdev, LED_OFF);
>   	}
>   
>   out:
> 
> base-commit: fe15c26ee26efa11741a7b632e9f23b01aca4cc6

Acked-by: Jacek Anaszewski <jacek.anaszewski@gmail.com>
Florian Eckert April 17, 2023, 7:18 a.m. UTC | #2
Hello Uwe,

On 2023-04-14 18:48, Uwe Kleine-König wrote:
> After commit ba8a86e4dadb ("leds: trigger/tty: Use
> led_set_brightness_sync() from workqueue") this is the second try to
> pick the right function to set the LED brightness from a trigger.
> 
> led_set_brightness_sync() has the problem that it doesn't work for LEDs
> without a .brightness_set_blocking() callback. This is (among others)
> the case for LEDs connected to non-sleeping GPIOs.
> 
> Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
> ---
> Hello,
> 
> after a few (non-public and public) reports that the tty trigger 
> doesn't
> work and Jacek pointed out in
> https://lore.kernel.org/all/ad4a1069-72c6-a431-336f-ed78a57a1ba0@gmail.com/#t
> that led_set_brightness_nosleep() is the right function, here comes a
> patch to actually implement that.
> 
> Does this justify a Fixes line? In that case that would be:
> 
> 	Fixes: ba8a86e4dadb ("leds: trigger/tty: Use
> led_set_brightness_sync() from workqueue")
> 
> (As ba8a86e4dadb declares to be a fix for fd4a641ac88f ("leds: trigger:
> implement a tty trigger") I think a further reference to fd4a641ac88f
> isn't necesary.)
> 
> Best regards
> Uwe
> 
>  drivers/leds/trigger/ledtrig-tty.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/leds/trigger/ledtrig-tty.c
> b/drivers/leds/trigger/ledtrig-tty.c
> index f62db7e520b5..c8bbdeac93b9 100644
> --- a/drivers/leds/trigger/ledtrig-tty.c
> +++ b/drivers/leds/trigger/ledtrig-tty.c
> @@ -1,11 +1,11 @@
>  // SPDX-License-Identifier: GPL-2.0
> 
>  #include <linux/delay.h>
> -#include <linux/leds.h>
>  #include <linux/module.h>
>  #include <linux/slab.h>
>  #include <linux/tty.h>
>  #include <uapi/linux/serial.h>
> +#include "../leds.h"
> 
>  struct ledtrig_tty_data {
>  	struct led_classdev *led_cdev;
> @@ -122,12 +122,12 @@ static void ledtrig_tty_work(struct work_struct 
> *work)
> 
>  	if (icount.rx != trigger_data->rx ||
>  	    icount.tx != trigger_data->tx) {
> -		led_set_brightness_sync(trigger_data->led_cdev, LED_ON);
> +		led_set_brightness_nosleep(trigger_data->led_cdev, LED_ON);
> 
>  		trigger_data->rx = icount.rx;
>  		trigger_data->tx = icount.tx;
>  	} else {
> -		led_set_brightness_sync(trigger_data->led_cdev, LED_OFF);
> +		led_set_brightness_nosleep(trigger_data->led_cdev, LED_OFF);
>  	}
> 
>  out:
> 
> base-commit: fe15c26ee26efa11741a7b632e9f23b01aca4cc6

Tested-By: Florian Eckert <fe@dev.tdt.de>
Pavel Machek April 17, 2023, 12:28 p.m. UTC | #3
Hi!

> After commit ba8a86e4dadb ("leds: trigger/tty: Use
> led_set_brightness_sync() from workqueue") this is the second try to
> pick the right function to set the LED brightness from a trigger.
> 
> led_set_brightness_sync() has the problem that it doesn't work for LEDs
> without a .brightness_set_blocking() callback. This is (among others)
> the case for LEDs connected to non-sleeping GPIOs.
> 
> Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>

I don't think this is right.

_nosleep calls _nopm, which assmues it can't sleep, and schedules
another workqueue to set the LED.

Best regards,
									Pavel
Uwe Kleine-König April 17, 2023, 12:44 p.m. UTC | #4
Hello,

On Mon, Apr 17, 2023 at 02:28:52PM +0200, Pavel Machek wrote:
> > After commit ba8a86e4dadb ("leds: trigger/tty: Use
> > led_set_brightness_sync() from workqueue") this is the second try to
> > pick the right function to set the LED brightness from a trigger.
> > 
> > led_set_brightness_sync() has the problem that it doesn't work for LEDs
> > without a .brightness_set_blocking() callback. This is (among others)
> > the case for LEDs connected to non-sleeping GPIOs.
> > 
> > Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
> 
> I don't think this is right.
> 
> _nosleep calls _nopm, which assmues it can't sleep, and schedules
> another workqueue to set the LED.

Then which is the right variant?
led_set_brightness() and led_set_brightness_nosleep() set via a workqueue
(which is bad) and led_set_brightness_sync() doesn't work for some LEDs
(notably LEDs on non-sleeping GPIOs).

From reading the code comments led_set_brightness_sync() sounds like the
right function to call, so maybe we only need to fix gpio-led (and maybe
some others)?

Best regards
Uwe
Jacek Anaszewski April 17, 2023, 6:33 p.m. UTC | #5
Hi Uwe,

On 4/17/23 14:44, Uwe Kleine-König wrote:
> Hello,
> 
> On Mon, Apr 17, 2023 at 02:28:52PM +0200, Pavel Machek wrote:
>>> After commit ba8a86e4dadb ("leds: trigger/tty: Use
>>> led_set_brightness_sync() from workqueue") this is the second try to
>>> pick the right function to set the LED brightness from a trigger.
>>>
>>> led_set_brightness_sync() has the problem that it doesn't work for LEDs
>>> without a .brightness_set_blocking() callback. This is (among others)
>>> the case for LEDs connected to non-sleeping GPIOs.
>>>
>>> Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
>>
>> I don't think this is right.
>>
>> _nosleep calls _nopm, which assmues it can't sleep, and schedules
>> another workqueue to set the LED.
> 
> Then which is the right variant?
> led_set_brightness() and led_set_brightness_nosleep() set via a workqueue
> (which is bad) and led_set_brightness_sync() doesn't work for some LEDs
> (notably LEDs on non-sleeping GPIOs).

Can you remind me the context of this patch, why using workqueue is
bad here?
Uwe Kleine-König April 17, 2023, 7:17 p.m. UTC | #6
On Mon, Apr 17, 2023 at 08:33:31PM +0200, Jacek Anaszewski wrote:
> Hi Uwe,
> 
> On 4/17/23 14:44, Uwe Kleine-König wrote:
> > Hello,
> > 
> > On Mon, Apr 17, 2023 at 02:28:52PM +0200, Pavel Machek wrote:
> > > > After commit ba8a86e4dadb ("leds: trigger/tty: Use
> > > > led_set_brightness_sync() from workqueue") this is the second try to
> > > > pick the right function to set the LED brightness from a trigger.
> > > > 
> > > > led_set_brightness_sync() has the problem that it doesn't work for LEDs
> > > > without a .brightness_set_blocking() callback. This is (among others)
> > > > the case for LEDs connected to non-sleeping GPIOs.
> > > > 
> > > > Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
> > > 
> > > I don't think this is right.
> > > 
> > > _nosleep calls _nopm, which assmues it can't sleep, and schedules
> > > another workqueue to set the LED.
> > 
> > Then which is the right variant?
> > led_set_brightness() and led_set_brightness_nosleep() set via a workqueue
> > (which is bad) and led_set_brightness_sync() doesn't work for some LEDs
> > (notably LEDs on non-sleeping GPIOs).
> 
> Can you remind me the context of this patch, why using workqueue is
> bad here?

The workqueue is only needed if you have a slow LED and want to set the
brightness in atomic context. However if you are allowed to sleep that
is just needless overhead.

Best regards
Uwe
Jacek Anaszewski April 17, 2023, 7:51 p.m. UTC | #7
On 4/17/23 21:17, Uwe Kleine-König wrote:
> On Mon, Apr 17, 2023 at 08:33:31PM +0200, Jacek Anaszewski wrote:
>> Hi Uwe,
>>
>> On 4/17/23 14:44, Uwe Kleine-König wrote:
>>> Hello,
>>>
>>> On Mon, Apr 17, 2023 at 02:28:52PM +0200, Pavel Machek wrote:
>>>>> After commit ba8a86e4dadb ("leds: trigger/tty: Use
>>>>> led_set_brightness_sync() from workqueue") this is the second try to
>>>>> pick the right function to set the LED brightness from a trigger.
>>>>>
>>>>> led_set_brightness_sync() has the problem that it doesn't work for LEDs
>>>>> without a .brightness_set_blocking() callback. This is (among others)
>>>>> the case for LEDs connected to non-sleeping GPIOs.
>>>>>
>>>>> Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
>>>>
>>>> I don't think this is right.
>>>>
>>>> _nosleep calls _nopm, which assmues it can't sleep, and schedules
>>>> another workqueue to set the LED.
>>>
>>> Then which is the right variant?
>>> led_set_brightness() and led_set_brightness_nosleep() set via a workqueue
>>> (which is bad) and led_set_brightness_sync() doesn't work for some LEDs
>>> (notably LEDs on non-sleeping GPIOs).
>>
>> Can you remind me the context of this patch, why using workqueue is
>> bad here?
> 
> The workqueue is only needed if you have a slow LED and want to set the
> brightness in atomic context. However if you are allowed to sleep that
> is just needless overhead.

OK, now I get it. So new functions will be needed, something like
below (skipped args, need more thinking about corner cases, e.g.
interactions with led_classdev_suspend()):

int led_set_brightness_cansleep()
     led_cdev->brightness = min(value, led_cdev->max_brightness);

     if (led_cdev->flags & LED_SUSPENDED)
         return 0;

     return led_set_brightness_nopm_cansleep();


int led_set_brightness_nopm_cansleep()
     ret =__led_set_brightness();
     if (ret == -ENOTSUPP)
         ret = __led_set_brightness_blocking();

     return ret;

As a quick fix I would apply led_set_brightness_nosleep() nonetheless.
Does it have any observed downsides?
Uwe Kleine-König April 17, 2023, 10:27 p.m. UTC | #8
hello Jacek,

On Mon, Apr 17, 2023 at 09:51:06PM +0200, Jacek Anaszewski wrote:
> On 4/17/23 21:17, Uwe Kleine-König wrote:
> > On Mon, Apr 17, 2023 at 08:33:31PM +0200, Jacek Anaszewski wrote:
> > > On 4/17/23 14:44, Uwe Kleine-König wrote:
> > > > On Mon, Apr 17, 2023 at 02:28:52PM +0200, Pavel Machek wrote:
> > > > > > After commit ba8a86e4dadb ("leds: trigger/tty: Use
> > > > > > led_set_brightness_sync() from workqueue") this is the second try to
> > > > > > pick the right function to set the LED brightness from a trigger.
> > > > > > 
> > > > > > led_set_brightness_sync() has the problem that it doesn't work for LEDs
> > > > > > without a .brightness_set_blocking() callback. This is (among others)
> > > > > > the case for LEDs connected to non-sleeping GPIOs.
> > > > > > 
> > > > > > Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
> > > > > 
> > > > > I don't think this is right.
> > > > > 
> > > > > _nosleep calls _nopm, which assmues it can't sleep, and schedules
> > > > > another workqueue to set the LED.
> > > > 
> > > > Then which is the right variant?
> > > > led_set_brightness() and led_set_brightness_nosleep() set via a workqueue
> > > > (which is bad) and led_set_brightness_sync() doesn't work for some LEDs
> > > > (notably LEDs on non-sleeping GPIOs).
> > > 
> > > Can you remind me the context of this patch, why using workqueue is
> > > bad here?
> > 
> > The workqueue is only needed if you have a slow LED and want to set the
> > brightness in atomic context. However if you are allowed to sleep that
> > is just needless overhead.
> 
> OK, now I get it. So new functions will be needed, something like
> below (skipped args, need more thinking about corner cases, e.g.
> interactions with led_classdev_suspend()):
> 
> int led_set_brightness_cansleep()
>     led_cdev->brightness = min(value, led_cdev->max_brightness);
> 
>     if (led_cdev->flags & LED_SUSPENDED)
>         return 0;
> 
>     return led_set_brightness_nopm_cansleep();
> 
> 
> int led_set_brightness_nopm_cansleep()
>     ret =__led_set_brightness();
>     if (ret == -ENOTSUPP)
>         ret = __led_set_brightness_blocking();
> 
>     return ret;

Did you just reinvent led_set_brightness_sync() and the only thing we
need is:

diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c
index ce4e79939731..4f718609032b 100644
--- a/drivers/leds/leds-gpio.c
+++ b/drivers/leds/leds-gpio.c
@@ -83,8 +83,7 @@ static int create_gpio_led(const struct gpio_led *template,
 	led_dat->can_sleep = gpiod_cansleep(led_dat->gpiod);
 	if (!led_dat->can_sleep)
 		led_dat->cdev.brightness_set = gpio_led_set;
-	else
-		led_dat->cdev.brightness_set_blocking = gpio_led_set_blocking;
+	led_dat->cdev.brightness_set_blocking = gpio_led_set_blocking;
 	led_dat->blinking = 0;
 	if (blink_set) {
 		led_dat->platform_gpio_blink_set = blink_set;

?

> As a quick fix I would apply led_set_brightness_nosleep() nonetheless.
> Does it have any observed downsides?

Best regards
Uwe
Jacek Anaszewski April 18, 2023, 6:02 p.m. UTC | #9
Hi Uwe,

On 4/18/23 00:27, Uwe Kleine-König wrote:
> hello Jacek,
> 
> On Mon, Apr 17, 2023 at 09:51:06PM +0200, Jacek Anaszewski wrote:
>> On 4/17/23 21:17, Uwe Kleine-König wrote:
>>> On Mon, Apr 17, 2023 at 08:33:31PM +0200, Jacek Anaszewski wrote:
>>>> On 4/17/23 14:44, Uwe Kleine-König wrote:
>>>>> On Mon, Apr 17, 2023 at 02:28:52PM +0200, Pavel Machek wrote:
>>>>>>> After commit ba8a86e4dadb ("leds: trigger/tty: Use
>>>>>>> led_set_brightness_sync() from workqueue") this is the second try to
>>>>>>> pick the right function to set the LED brightness from a trigger.
>>>>>>>
>>>>>>> led_set_brightness_sync() has the problem that it doesn't work for LEDs
>>>>>>> without a .brightness_set_blocking() callback. This is (among others)
>>>>>>> the case for LEDs connected to non-sleeping GPIOs.
>>>>>>>
>>>>>>> Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
>>>>>>
>>>>>> I don't think this is right.
>>>>>>
>>>>>> _nosleep calls _nopm, which assmues it can't sleep, and schedules
>>>>>> another workqueue to set the LED.
>>>>>
>>>>> Then which is the right variant?
>>>>> led_set_brightness() and led_set_brightness_nosleep() set via a workqueue
>>>>> (which is bad) and led_set_brightness_sync() doesn't work for some LEDs
>>>>> (notably LEDs on non-sleeping GPIOs).
>>>>
>>>> Can you remind me the context of this patch, why using workqueue is
>>>> bad here?
>>>
>>> The workqueue is only needed if you have a slow LED and want to set the
>>> brightness in atomic context. However if you are allowed to sleep that
>>> is just needless overhead.
>>
>> OK, now I get it. So new functions will be needed, something like
>> below (skipped args, need more thinking about corner cases, e.g.
>> interactions with led_classdev_suspend()):
>>
>> int led_set_brightness_cansleep()
>>      led_cdev->brightness = min(value, led_cdev->max_brightness);
>>
>>      if (led_cdev->flags & LED_SUSPENDED)
>>          return 0;
>>
>>      return led_set_brightness_nopm_cansleep();
>>
>>
>> int led_set_brightness_nopm_cansleep()
>>      ret =__led_set_brightness();
>>      if (ret == -ENOTSUPP)
>>          ret = __led_set_brightness_blocking();
>>
>>      return ret;
> 
> Did you just reinvent led_set_brightness_sync() and the only thing we
> need is:

Actually you're right, but led_set_brightness_sync() needs to be
supplemented with the call to __led_set_brightness_blocking().

> 
> diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c
> index ce4e79939731..4f718609032b 100644
> --- a/drivers/leds/leds-gpio.c
> +++ b/drivers/leds/leds-gpio.c
> @@ -83,8 +83,7 @@ static int create_gpio_led(const struct gpio_led *template,
>   	led_dat->can_sleep = gpiod_cansleep(led_dat->gpiod);
>   	if (!led_dat->can_sleep)
>   		led_dat->cdev.brightness_set = gpio_led_set;
> -	else
> -		led_dat->cdev.brightness_set_blocking = gpio_led_set_blocking;
> +	led_dat->cdev.brightness_set_blocking = gpio_led_set_blocking;
>   	led_dat->blinking = 0;
>   	if (blink_set) {
>   		led_dat->platform_gpio_blink_set = blink_set;
> 
> ?
> 
>> As a quick fix I would apply led_set_brightness_nosleep() nonetheless.
>> Does it have any observed downsides?
> 
> Best regards
> Uwe
>
Jacek Anaszewski April 18, 2023, 6:04 p.m. UTC | #10
On 4/18/23 20:02, Jacek Anaszewski wrote:
> Hi Uwe,
> 
> On 4/18/23 00:27, Uwe Kleine-König wrote:
>> hello Jacek,
>>
>> On Mon, Apr 17, 2023 at 09:51:06PM +0200, Jacek Anaszewski wrote:
[...]
>>> int led_set_brightness_nopm_cansleep()
>>>      ret =__led_set_brightness();
>>>      if (ret == -ENOTSUPP)
>>>          ret = __led_set_brightness_blocking();
>>>
>>>      return ret;
>>
>> Did you just reinvent led_set_brightness_sync() and the only thing we
>> need is:
> 
> Actually you're right, but led_set_brightness_sync() needs to be
> supplemented with the call to __led_set_brightness_blocking().

I meant __led_set_brightness() of course.
diff mbox series

Patch

diff --git a/drivers/leds/trigger/ledtrig-tty.c b/drivers/leds/trigger/ledtrig-tty.c
index f62db7e520b5..c8bbdeac93b9 100644
--- a/drivers/leds/trigger/ledtrig-tty.c
+++ b/drivers/leds/trigger/ledtrig-tty.c
@@ -1,11 +1,11 @@ 
 // SPDX-License-Identifier: GPL-2.0
 
 #include <linux/delay.h>
-#include <linux/leds.h>
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/tty.h>
 #include <uapi/linux/serial.h>
+#include "../leds.h"
 
 struct ledtrig_tty_data {
 	struct led_classdev *led_cdev;
@@ -122,12 +122,12 @@  static void ledtrig_tty_work(struct work_struct *work)
 
 	if (icount.rx != trigger_data->rx ||
 	    icount.tx != trigger_data->tx) {
-		led_set_brightness_sync(trigger_data->led_cdev, LED_ON);
+		led_set_brightness_nosleep(trigger_data->led_cdev, LED_ON);
 
 		trigger_data->rx = icount.rx;
 		trigger_data->tx = icount.tx;
 	} else {
-		led_set_brightness_sync(trigger_data->led_cdev, LED_OFF);
+		led_set_brightness_nosleep(trigger_data->led_cdev, LED_OFF);
 	}
 
 out: