summaryrefslogtreecommitdiffstats
path: root/drivers/leds/led-core.c
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2012-05-15 17:21:26 +1000
committerHerbert Xu <herbert@gondor.apana.org.au>2012-05-15 17:21:26 +1000
commitb29e2679d0da91c60d3ac190d9c3bd65ac2f68c5 (patch)
tree518ec8f4bfd316e91bcc30f434edb78529557eba /drivers/leds/led-core.c
parent8a63b1994c500d4825ee73dc71502deffe5b135b (diff)
parent4bb2d1009f671815870e8f78e826e4f9071392a7 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux
Merge mainline to add prerequisite for ARM ux500 crypto support.
Diffstat (limited to 'drivers/leds/led-core.c')
-rw-r--r--drivers/leds/led-core.c70
1 files changed, 70 insertions, 0 deletions
diff --git a/drivers/leds/led-core.c b/drivers/leds/led-core.c
index 016d19f5486..d6860043f6f 100644
--- a/drivers/leds/led-core.c
+++ b/drivers/leds/led-core.c
@@ -23,3 +23,73 @@ EXPORT_SYMBOL_GPL(leds_list_lock);
LIST_HEAD(leds_list);
EXPORT_SYMBOL_GPL(leds_list);
+
+static void led_stop_software_blink(struct led_classdev *led_cdev)
+{
+ /* deactivate previous settings */
+ del_timer_sync(&led_cdev->blink_timer);
+ led_cdev->blink_delay_on = 0;
+ led_cdev->blink_delay_off = 0;
+}
+
+static void led_set_software_blink(struct led_classdev *led_cdev,
+ unsigned long delay_on,
+ unsigned long delay_off)
+{
+ int current_brightness;
+
+ current_brightness = led_get_brightness(led_cdev);
+ if (current_brightness)
+ led_cdev->blink_brightness = current_brightness;
+ if (!led_cdev->blink_brightness)
+ led_cdev->blink_brightness = led_cdev->max_brightness;
+
+ if (led_get_trigger_data(led_cdev) &&
+ delay_on == led_cdev->blink_delay_on &&
+ delay_off == led_cdev->blink_delay_off)
+ return;
+
+ led_stop_software_blink(led_cdev);
+
+ led_cdev->blink_delay_on = delay_on;
+ led_cdev->blink_delay_off = delay_off;
+
+ /* never on - don't blink */
+ if (!delay_on)
+ return;
+
+ /* never off - just set to brightness */
+ if (!delay_off) {
+ led_set_brightness(led_cdev, led_cdev->blink_brightness);
+ return;
+ }
+
+ mod_timer(&led_cdev->blink_timer, jiffies + 1);
+}
+
+
+void led_blink_set(struct led_classdev *led_cdev,
+ unsigned long *delay_on,
+ unsigned long *delay_off)
+{
+ del_timer_sync(&led_cdev->blink_timer);
+
+ if (led_cdev->blink_set &&
+ !led_cdev->blink_set(led_cdev, delay_on, delay_off))
+ return;
+
+ /* blink with 1 Hz as default if nothing specified */
+ if (!*delay_on && !*delay_off)
+ *delay_on = *delay_off = 500;
+
+ led_set_software_blink(led_cdev, *delay_on, *delay_off);
+}
+EXPORT_SYMBOL(led_blink_set);
+
+void led_brightness_set(struct led_classdev *led_cdev,
+ enum led_brightness brightness)
+{
+ led_stop_software_blink(led_cdev);
+ led_cdev->brightness_set(led_cdev, brightness);
+}
+EXPORT_SYMBOL(led_brightness_set);