aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/leds
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/leds')
-rw-r--r--drivers/leds/Kconfig6
-rw-r--r--drivers/leds/ledtrig-timer.c41
2 files changed, 42 insertions, 5 deletions
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index cf3a6d4d9475..659448ead685 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -152,7 +152,11 @@ config LEDS_TRIGGER_TIMER
152 depends on LEDS_TRIGGERS 152 depends on LEDS_TRIGGERS
153 help 153 help
154 This allows LEDs to be controlled by a programmable timer 154 This allows LEDs to be controlled by a programmable timer
155 via sysfs. If unsure, say Y. 155 via sysfs. Some LED hardware can be programmed to start
156 blinking the LED without any further software interaction.
157 For more details read Documentation/leds-class.txt.
158
159 If unsure, say Y.
156 160
157config LEDS_TRIGGER_IDE_DISK 161config LEDS_TRIGGER_IDE_DISK
158 bool "LED IDE Disk Trigger" 162 bool "LED IDE Disk Trigger"
diff --git a/drivers/leds/ledtrig-timer.c b/drivers/leds/ledtrig-timer.c
index ed9ff02c77ea..82c55d6e4902 100644
--- a/drivers/leds/ledtrig-timer.c
+++ b/drivers/leds/ledtrig-timer.c
@@ -77,8 +77,21 @@ static ssize_t led_delay_on_store(struct device *dev,
77 count++; 77 count++;
78 78
79 if (count == size) { 79 if (count == size) {
80 timer_data->delay_on = state; 80 if (timer_data->delay_on != state) {
81 mod_timer(&timer_data->timer, jiffies + 1); 81 /* the new value differs from the previous */
82 timer_data->delay_on = state;
83
84 /* deactivate previous settings */
85 del_timer_sync(&timer_data->timer);
86
87 /* try to activate hardware acceleration, if any */
88 if (!led_cdev->blink_set ||
89 led_cdev->blink_set(led_cdev,
90 &timer_data->delay_on, &timer_data->delay_off)) {
91 /* no hardware acceleration, blink via timer */
92 mod_timer(&timer_data->timer, jiffies + 1);
93 }
94 }
82 ret = count; 95 ret = count;
83 } 96 }
84 97
@@ -110,8 +123,21 @@ static ssize_t led_delay_off_store(struct device *dev,
110 count++; 123 count++;
111 124
112 if (count == size) { 125 if (count == size) {
113 timer_data->delay_off = state; 126 if (timer_data->delay_off != state) {
114 mod_timer(&timer_data->timer, jiffies + 1); 127 /* the new value differs from the previous */
128 timer_data->delay_off = state;
129
130 /* deactivate previous settings */
131 del_timer_sync(&timer_data->timer);
132
133 /* try to activate hardware acceleration, if any */
134 if (!led_cdev->blink_set ||
135 led_cdev->blink_set(led_cdev,
136 &timer_data->delay_on, &timer_data->delay_off)) {
137 /* no hardware acceleration, blink via timer */
138 mod_timer(&timer_data->timer, jiffies + 1);
139 }
140 }
115 ret = count; 141 ret = count;
116 } 142 }
117 143
@@ -143,6 +169,13 @@ static void timer_trig_activate(struct led_classdev *led_cdev)
143 if (rc) 169 if (rc)
144 goto err_out_delayon; 170 goto err_out_delayon;
145 171
172 /* If there is hardware support for blinking, start one
173 * user friendly blink rate chosen by the driver.
174 */
175 if (led_cdev->blink_set)
176 led_cdev->blink_set(led_cdev,
177 &timer_data->delay_on, &timer_data->delay_off);
178
146 return; 179 return;
147 180
148err_out_delayon: 181err_out_delayon: