diff options
Diffstat (limited to 'drivers/leds/led-class.c')
-rw-r--r-- | drivers/leds/led-class.c | 27 |
1 files changed, 23 insertions, 4 deletions
diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c index e663e6f413e9..c599095bc005 100644 --- a/drivers/leds/led-class.c +++ b/drivers/leds/led-class.c @@ -53,7 +53,7 @@ static ssize_t led_brightness_store(struct device *dev, if (state == LED_OFF) led_trigger_remove(led_cdev); - led_set_brightness(led_cdev, state); + __led_set_brightness(led_cdev, state); return size; } @@ -82,7 +82,12 @@ static void led_timer_function(unsigned long data) unsigned long delay; if (!led_cdev->blink_delay_on || !led_cdev->blink_delay_off) { - led_set_brightness(led_cdev, LED_OFF); + __led_set_brightness(led_cdev, LED_OFF); + return; + } + + if (led_cdev->flags & LED_BLINK_ONESHOT_STOP) { + led_cdev->flags &= ~LED_BLINK_ONESHOT_STOP; return; } @@ -100,7 +105,21 @@ static void led_timer_function(unsigned long data) delay = led_cdev->blink_delay_off; } - led_set_brightness(led_cdev, brightness); + __led_set_brightness(led_cdev, brightness); + + /* Return in next iteration if led is in one-shot mode and we are in + * the final blink state so that the led is toggled each delay_on + + * delay_off milliseconds in worst case. + */ + if (led_cdev->flags & LED_BLINK_ONESHOT) { + if (led_cdev->flags & LED_BLINK_INVERT) { + if (brightness) + led_cdev->flags |= LED_BLINK_ONESHOT_STOP; + } else { + if (!brightness) + led_cdev->flags |= LED_BLINK_ONESHOT_STOP; + } + } mod_timer(&led_cdev->blink_timer, jiffies + msecs_to_jiffies(delay)); } @@ -203,7 +222,7 @@ void led_classdev_unregister(struct led_classdev *led_cdev) #endif /* Stop blinking */ - led_brightness_set(led_cdev, LED_OFF); + led_set_brightness(led_cdev, LED_OFF); device_unregister(led_cdev->dev); |