aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/leds
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/leds')
-rw-r--r--drivers/leds/led-class.c19
-rw-r--r--drivers/leds/led-core.c45
-rw-r--r--drivers/leds/led-triggers.c30
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);
27static void led_stop_software_blink(struct led_classdev *led_cdev) 27static 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
64void led_blink_set(struct led_classdev *led_cdev, 63void 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
79void 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}
80EXPORT_SYMBOL(led_blink_set); 90EXPORT_SYMBOL(led_blink_set);
81 91
92void 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}
111EXPORT_SYMBOL(led_blink_set_oneshot);
112
82void led_brightness_set(struct led_classdev *led_cdev, 113void 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}
231EXPORT_SYMBOL_GPL(led_trigger_event); 231EXPORT_SYMBOL_GPL(led_trigger_event);
232 232
233void led_trigger_blink(struct led_trigger *trig, 233void 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
258void 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}
251EXPORT_SYMBOL_GPL(led_trigger_blink); 264EXPORT_SYMBOL_GPL(led_trigger_blink);
252 265
266void 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}
273EXPORT_SYMBOL_GPL(led_trigger_blink_oneshot);
274
253void led_trigger_register_simple(const char *name, struct led_trigger **tp) 275void led_trigger_register_simple(const char *name, struct led_trigger **tp)
254{ 276{
255 struct led_trigger *trig; 277 struct led_trigger *trig;