diff options
Diffstat (limited to 'drivers/leds')
-rw-r--r-- | drivers/leds/Kconfig | 6 | ||||
-rw-r--r-- | drivers/leds/ledtrig-timer.c | 41 |
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 | ||
157 | config LEDS_TRIGGER_IDE_DISK | 161 | config 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 | ||
148 | err_out_delayon: | 181 | err_out_delayon: |