diff options
Diffstat (limited to 'drivers/leds')
-rw-r--r-- | drivers/leds/led-class.c | 3 | ||||
-rw-r--r-- | drivers/leds/led-triggers.c | 12 | ||||
-rw-r--r-- | drivers/leds/leds.h | 7 | ||||
-rw-r--r-- | drivers/leds/ledtrig-timer.c | 23 |
4 files changed, 38 insertions, 7 deletions
diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c index 63aad90247c4..a8dd59ebedf8 100644 --- a/drivers/leds/led-class.c +++ b/drivers/leds/led-class.c | |||
@@ -51,6 +51,9 @@ static ssize_t led_brightness_store(struct device *dev, | |||
51 | 51 | ||
52 | if (count == size) { | 52 | if (count == size) { |
53 | ret = count; | 53 | ret = count; |
54 | |||
55 | if (state == LED_OFF) | ||
56 | led_trigger_remove(led_cdev); | ||
54 | led_set_brightness(led_cdev, state); | 57 | led_set_brightness(led_cdev, state); |
55 | } | 58 | } |
56 | 59 | ||
diff --git a/drivers/leds/led-triggers.c b/drivers/leds/led-triggers.c index 13c9026d68af..21dd96909444 100644 --- a/drivers/leds/led-triggers.c +++ b/drivers/leds/led-triggers.c | |||
@@ -45,9 +45,7 @@ ssize_t led_trigger_store(struct device *dev, struct device_attribute *attr, | |||
45 | trigger_name[len - 1] = '\0'; | 45 | trigger_name[len - 1] = '\0'; |
46 | 46 | ||
47 | if (!strcmp(trigger_name, "none")) { | 47 | if (!strcmp(trigger_name, "none")) { |
48 | down_write(&led_cdev->trigger_lock); | 48 | led_trigger_remove(led_cdev); |
49 | led_trigger_set(led_cdev, NULL); | ||
50 | up_write(&led_cdev->trigger_lock); | ||
51 | return count; | 49 | return count; |
52 | } | 50 | } |
53 | 51 | ||
@@ -139,6 +137,13 @@ void led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trigger) | |||
139 | led_cdev->trigger = trigger; | 137 | led_cdev->trigger = trigger; |
140 | } | 138 | } |
141 | 139 | ||
140 | void led_trigger_remove(struct led_classdev *led_cdev) | ||
141 | { | ||
142 | down_write(&led_cdev->trigger_lock); | ||
143 | led_trigger_set(led_cdev, NULL); | ||
144 | up_write(&led_cdev->trigger_lock); | ||
145 | } | ||
146 | |||
142 | void led_trigger_set_default(struct led_classdev *led_cdev) | 147 | void led_trigger_set_default(struct led_classdev *led_cdev) |
143 | { | 148 | { |
144 | struct led_trigger *trig; | 149 | struct led_trigger *trig; |
@@ -231,6 +236,7 @@ void led_trigger_unregister_simple(struct led_trigger *trigger) | |||
231 | 236 | ||
232 | /* Used by LED Class */ | 237 | /* Used by LED Class */ |
233 | EXPORT_SYMBOL_GPL(led_trigger_set); | 238 | EXPORT_SYMBOL_GPL(led_trigger_set); |
239 | EXPORT_SYMBOL_GPL(led_trigger_remove); | ||
234 | EXPORT_SYMBOL_GPL(led_trigger_set_default); | 240 | EXPORT_SYMBOL_GPL(led_trigger_set_default); |
235 | EXPORT_SYMBOL_GPL(led_trigger_show); | 241 | EXPORT_SYMBOL_GPL(led_trigger_show); |
236 | EXPORT_SYMBOL_GPL(led_trigger_store); | 242 | EXPORT_SYMBOL_GPL(led_trigger_store); |
diff --git a/drivers/leds/leds.h b/drivers/leds/leds.h index 12b6fe93b135..0214799639f7 100644 --- a/drivers/leds/leds.h +++ b/drivers/leds/leds.h | |||
@@ -27,6 +27,11 @@ static inline void led_set_brightness(struct led_classdev *led_cdev, | |||
27 | led_cdev->brightness_set(led_cdev, value); | 27 | led_cdev->brightness_set(led_cdev, value); |
28 | } | 28 | } |
29 | 29 | ||
30 | static inline int led_get_brightness(struct led_classdev *led_cdev) | ||
31 | { | ||
32 | return led_cdev->brightness; | ||
33 | } | ||
34 | |||
30 | extern struct rw_semaphore leds_list_lock; | 35 | extern struct rw_semaphore leds_list_lock; |
31 | extern struct list_head leds_list; | 36 | extern struct list_head leds_list; |
32 | 37 | ||
@@ -34,9 +39,11 @@ extern struct list_head leds_list; | |||
34 | void led_trigger_set_default(struct led_classdev *led_cdev); | 39 | void led_trigger_set_default(struct led_classdev *led_cdev); |
35 | void led_trigger_set(struct led_classdev *led_cdev, | 40 | void led_trigger_set(struct led_classdev *led_cdev, |
36 | struct led_trigger *trigger); | 41 | struct led_trigger *trigger); |
42 | void led_trigger_remove(struct led_classdev *led_cdev); | ||
37 | #else | 43 | #else |
38 | #define led_trigger_set_default(x) do {} while(0) | 44 | #define led_trigger_set_default(x) do {} while(0) |
39 | #define led_trigger_set(x, y) do {} while(0) | 45 | #define led_trigger_set(x, y) do {} while(0) |
46 | #define led_trigger_remove(x) do {} while(0) | ||
40 | #endif | 47 | #endif |
41 | 48 | ||
42 | ssize_t led_trigger_store(struct device *dev, struct device_attribute *attr, | 49 | ssize_t led_trigger_store(struct device *dev, struct device_attribute *attr, |
diff --git a/drivers/leds/ledtrig-timer.c b/drivers/leds/ledtrig-timer.c index 82c55d6e4902..706297765d93 100644 --- a/drivers/leds/ledtrig-timer.c +++ b/drivers/leds/ledtrig-timer.c | |||
@@ -25,6 +25,9 @@ | |||
25 | #include "leds.h" | 25 | #include "leds.h" |
26 | 26 | ||
27 | struct timer_trig_data { | 27 | struct timer_trig_data { |
28 | int brightness_on; /* LED brightness during "on" period. | ||
29 | * (LED_OFF < brightness_on <= LED_FULL) | ||
30 | */ | ||
28 | unsigned long delay_on; /* milliseconds on */ | 31 | unsigned long delay_on; /* milliseconds on */ |
29 | unsigned long delay_off; /* milliseconds off */ | 32 | unsigned long delay_off; /* milliseconds off */ |
30 | struct timer_list timer; | 33 | struct timer_list timer; |
@@ -34,17 +37,26 @@ static void led_timer_function(unsigned long data) | |||
34 | { | 37 | { |
35 | struct led_classdev *led_cdev = (struct led_classdev *) data; | 38 | struct led_classdev *led_cdev = (struct led_classdev *) data; |
36 | struct timer_trig_data *timer_data = led_cdev->trigger_data; | 39 | struct timer_trig_data *timer_data = led_cdev->trigger_data; |
37 | unsigned long brightness = LED_OFF; | 40 | unsigned long brightness; |
38 | unsigned long delay = timer_data->delay_off; | 41 | unsigned long delay; |
39 | 42 | ||
40 | if (!timer_data->delay_on || !timer_data->delay_off) { | 43 | if (!timer_data->delay_on || !timer_data->delay_off) { |
41 | led_set_brightness(led_cdev, LED_OFF); | 44 | led_set_brightness(led_cdev, LED_OFF); |
42 | return; | 45 | return; |
43 | } | 46 | } |
44 | 47 | ||
45 | if (!led_cdev->brightness) { | 48 | brightness = led_get_brightness(led_cdev); |
46 | brightness = LED_FULL; | 49 | if (!brightness) { |
50 | /* Time to switch the LED on. */ | ||
51 | brightness = timer_data->brightness_on; | ||
47 | delay = timer_data->delay_on; | 52 | delay = timer_data->delay_on; |
53 | } else { | ||
54 | /* Store the current brightness value to be able | ||
55 | * to restore it when the delay_off period is over. | ||
56 | */ | ||
57 | timer_data->brightness_on = brightness; | ||
58 | brightness = LED_OFF; | ||
59 | delay = timer_data->delay_off; | ||
48 | } | 60 | } |
49 | 61 | ||
50 | led_set_brightness(led_cdev, brightness); | 62 | led_set_brightness(led_cdev, brightness); |
@@ -156,6 +168,9 @@ static void timer_trig_activate(struct led_classdev *led_cdev) | |||
156 | if (!timer_data) | 168 | if (!timer_data) |
157 | return; | 169 | return; |
158 | 170 | ||
171 | timer_data->brightness_on = led_get_brightness(led_cdev); | ||
172 | if (timer_data->brightness_on == LED_OFF) | ||
173 | timer_data->brightness_on = LED_FULL; | ||
159 | led_cdev->trigger_data = timer_data; | 174 | led_cdev->trigger_data = timer_data; |
160 | 175 | ||
161 | init_timer(&timer_data->timer); | 176 | init_timer(&timer_data->timer); |