diff options
Diffstat (limited to 'drivers/leds')
-rw-r--r-- | drivers/leds/led-class.c | 19 | ||||
-rw-r--r-- | drivers/leds/led-core.c | 45 | ||||
-rw-r--r-- | drivers/leds/led-triggers.c | 30 |
3 files changed, 83 insertions, 11 deletions
diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c index e663e6f413e9..81eb0916b44a 100644 --- a/drivers/leds/led-class.c +++ b/drivers/leds/led-class.c | |||
@@ -86,6 +86,11 @@ static void led_timer_function(unsigned long data) | |||
86 | return; | 86 | return; |
87 | } | 87 | } |
88 | 88 | ||
89 | if (led_cdev->flags & LED_BLINK_ONESHOT_STOP) { | ||
90 | led_cdev->flags &= ~LED_BLINK_ONESHOT_STOP; | ||
91 | return; | ||
92 | } | ||
93 | |||
89 | brightness = led_get_brightness(led_cdev); | 94 | brightness = led_get_brightness(led_cdev); |
90 | if (!brightness) { | 95 | if (!brightness) { |
91 | /* Time to switch the LED on. */ | 96 | /* Time to switch the LED on. */ |
@@ -102,6 +107,20 @@ static void led_timer_function(unsigned long data) | |||
102 | 107 | ||
103 | led_set_brightness(led_cdev, brightness); | 108 | led_set_brightness(led_cdev, brightness); |
104 | 109 | ||
110 | /* Return in next iteration if led is in one-shot mode and we are in | ||
111 | * the final blink state so that the led is toggled each delay_on + | ||
112 | * delay_off milliseconds in worst case. | ||
113 | */ | ||
114 | if (led_cdev->flags & LED_BLINK_ONESHOT) { | ||
115 | if (led_cdev->flags & LED_BLINK_INVERT) { | ||
116 | if (brightness) | ||
117 | led_cdev->flags |= LED_BLINK_ONESHOT_STOP; | ||
118 | } else { | ||
119 | if (!brightness) | ||
120 | led_cdev->flags |= LED_BLINK_ONESHOT_STOP; | ||
121 | } | ||
122 | } | ||
123 | |||
105 | mod_timer(&led_cdev->blink_timer, jiffies + msecs_to_jiffies(delay)); | 124 | mod_timer(&led_cdev->blink_timer, jiffies + msecs_to_jiffies(delay)); |
106 | } | 125 | } |
107 | 126 | ||
diff --git a/drivers/leds/led-core.c b/drivers/leds/led-core.c index d65353d8d3fc..a6f4d910ca08 100644 --- a/drivers/leds/led-core.c +++ b/drivers/leds/led-core.c | |||
@@ -27,7 +27,6 @@ EXPORT_SYMBOL_GPL(leds_list); | |||
27 | static void led_stop_software_blink(struct led_classdev *led_cdev) | 27 | static void led_stop_software_blink(struct led_classdev *led_cdev) |
28 | { | 28 | { |
29 | /* deactivate previous settings */ | 29 | /* deactivate previous settings */ |
30 | del_timer_sync(&led_cdev->blink_timer); | ||
31 | led_cdev->blink_delay_on = 0; | 30 | led_cdev->blink_delay_on = 0; |
32 | led_cdev->blink_delay_off = 0; | 31 | led_cdev->blink_delay_off = 0; |
33 | } | 32 | } |
@@ -61,13 +60,12 @@ static void led_set_software_blink(struct led_classdev *led_cdev, | |||
61 | } | 60 | } |
62 | 61 | ||
63 | 62 | ||
64 | void led_blink_set(struct led_classdev *led_cdev, | 63 | void led_blink_setup(struct led_classdev *led_cdev, |
65 | unsigned long *delay_on, | 64 | unsigned long *delay_on, |
66 | unsigned long *delay_off) | 65 | unsigned long *delay_off) |
67 | { | 66 | { |
68 | del_timer_sync(&led_cdev->blink_timer); | 67 | if (!(led_cdev->flags & LED_BLINK_ONESHOT) && |
69 | 68 | led_cdev->blink_set && | |
70 | if (led_cdev->blink_set && | ||
71 | !led_cdev->blink_set(led_cdev, delay_on, delay_off)) | 69 | !led_cdev->blink_set(led_cdev, delay_on, delay_off)) |
72 | return; | 70 | return; |
73 | 71 | ||
@@ -77,8 +75,41 @@ void led_blink_set(struct led_classdev *led_cdev, | |||
77 | 75 | ||
78 | led_set_software_blink(led_cdev, *delay_on, *delay_off); | 76 | led_set_software_blink(led_cdev, *delay_on, *delay_off); |
79 | } | 77 | } |
78 | |||
79 | void led_blink_set(struct led_classdev *led_cdev, | ||
80 | unsigned long *delay_on, | ||
81 | unsigned long *delay_off) | ||
82 | { | ||
83 | del_timer_sync(&led_cdev->blink_timer); | ||
84 | |||
85 | led_cdev->flags &= ~LED_BLINK_ONESHOT; | ||
86 | led_cdev->flags &= ~LED_BLINK_ONESHOT_STOP; | ||
87 | |||
88 | led_blink_setup(led_cdev, delay_on, delay_off); | ||
89 | } | ||
80 | EXPORT_SYMBOL(led_blink_set); | 90 | EXPORT_SYMBOL(led_blink_set); |
81 | 91 | ||
92 | void led_blink_set_oneshot(struct led_classdev *led_cdev, | ||
93 | unsigned long *delay_on, | ||
94 | unsigned long *delay_off, | ||
95 | int invert) | ||
96 | { | ||
97 | if ((led_cdev->flags & LED_BLINK_ONESHOT) && | ||
98 | timer_pending(&led_cdev->blink_timer)) | ||
99 | return; | ||
100 | |||
101 | led_cdev->flags |= LED_BLINK_ONESHOT; | ||
102 | led_cdev->flags &= ~LED_BLINK_ONESHOT_STOP; | ||
103 | |||
104 | if (invert) | ||
105 | led_cdev->flags |= LED_BLINK_INVERT; | ||
106 | else | ||
107 | led_cdev->flags &= ~LED_BLINK_INVERT; | ||
108 | |||
109 | led_blink_setup(led_cdev, delay_on, delay_off); | ||
110 | } | ||
111 | EXPORT_SYMBOL(led_blink_set_oneshot); | ||
112 | |||
82 | void led_brightness_set(struct led_classdev *led_cdev, | 113 | void led_brightness_set(struct led_classdev *led_cdev, |
83 | enum led_brightness brightness) | 114 | enum led_brightness brightness) |
84 | { | 115 | { |
diff --git a/drivers/leds/led-triggers.c b/drivers/leds/led-triggers.c index b449ed8d8712..fa0b9be019ea 100644 --- a/drivers/leds/led-triggers.c +++ b/drivers/leds/led-triggers.c | |||
@@ -230,9 +230,11 @@ void led_trigger_event(struct led_trigger *trig, | |||
230 | } | 230 | } |
231 | EXPORT_SYMBOL_GPL(led_trigger_event); | 231 | EXPORT_SYMBOL_GPL(led_trigger_event); |
232 | 232 | ||
233 | void led_trigger_blink(struct led_trigger *trig, | 233 | void led_trigger_blink_setup(struct led_trigger *trig, |
234 | unsigned long *delay_on, | 234 | unsigned long *delay_on, |
235 | unsigned long *delay_off) | 235 | unsigned long *delay_off, |
236 | int oneshot, | ||
237 | int invert) | ||
236 | { | 238 | { |
237 | struct list_head *entry; | 239 | struct list_head *entry; |
238 | 240 | ||
@@ -244,12 +246,32 @@ void led_trigger_blink(struct led_trigger *trig, | |||
244 | struct led_classdev *led_cdev; | 246 | struct led_classdev *led_cdev; |
245 | 247 | ||
246 | led_cdev = list_entry(entry, struct led_classdev, trig_list); | 248 | led_cdev = list_entry(entry, struct led_classdev, trig_list); |
247 | led_blink_set(led_cdev, delay_on, delay_off); | 249 | if (oneshot) |
250 | led_blink_set_oneshot(led_cdev, delay_on, delay_off, | ||
251 | invert); | ||
252 | else | ||
253 | led_blink_set(led_cdev, delay_on, delay_off); | ||
248 | } | 254 | } |
249 | read_unlock(&trig->leddev_list_lock); | 255 | read_unlock(&trig->leddev_list_lock); |
250 | } | 256 | } |
257 | |||
258 | void led_trigger_blink(struct led_trigger *trig, | ||
259 | unsigned long *delay_on, | ||
260 | unsigned long *delay_off) | ||
261 | { | ||
262 | led_trigger_blink_setup(trig, delay_on, delay_off, 0, 0); | ||
263 | } | ||
251 | EXPORT_SYMBOL_GPL(led_trigger_blink); | 264 | EXPORT_SYMBOL_GPL(led_trigger_blink); |
252 | 265 | ||
266 | void led_trigger_blink_oneshot(struct led_trigger *trig, | ||
267 | unsigned long *delay_on, | ||
268 | unsigned long *delay_off, | ||
269 | int invert) | ||
270 | { | ||
271 | led_trigger_blink_setup(trig, delay_on, delay_off, 1, invert); | ||
272 | } | ||
273 | EXPORT_SYMBOL_GPL(led_trigger_blink_oneshot); | ||
274 | |||
253 | void led_trigger_register_simple(const char *name, struct led_trigger **tp) | 275 | void led_trigger_register_simple(const char *name, struct led_trigger **tp) |
254 | { | 276 | { |
255 | struct led_trigger *trig; | 277 | struct led_trigger *trig; |