summaryrefslogtreecommitdiffstats
path: root/drivers/leds/led-triggers.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/leds/led-triggers.c')
-rw-r--r--drivers/leds/led-triggers.c116
1 files changed, 69 insertions, 47 deletions
diff --git a/drivers/leds/led-triggers.c b/drivers/leds/led-triggers.c
index 46b4c766335d..363975b3c925 100644
--- a/drivers/leds/led-triggers.c
+++ b/drivers/leds/led-triggers.c
@@ -99,7 +99,7 @@ ssize_t led_trigger_show(struct device *dev, struct device_attribute *attr,
99EXPORT_SYMBOL_GPL(led_trigger_show); 99EXPORT_SYMBOL_GPL(led_trigger_show);
100 100
101/* Caller must ensure led_cdev->trigger_lock held */ 101/* Caller must ensure led_cdev->trigger_lock held */
102void led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trigger) 102void led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trig)
103{ 103{
104 unsigned long flags; 104 unsigned long flags;
105 105
@@ -112,15 +112,15 @@ void led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trigger)
112 if (led_cdev->trigger->deactivate) 112 if (led_cdev->trigger->deactivate)
113 led_cdev->trigger->deactivate(led_cdev); 113 led_cdev->trigger->deactivate(led_cdev);
114 led_cdev->trigger = NULL; 114 led_cdev->trigger = NULL;
115 led_brightness_set(led_cdev, LED_OFF); 115 led_set_brightness(led_cdev, LED_OFF);
116 } 116 }
117 if (trigger) { 117 if (trig) {
118 write_lock_irqsave(&trigger->leddev_list_lock, flags); 118 write_lock_irqsave(&trig->leddev_list_lock, flags);
119 list_add_tail(&led_cdev->trig_list, &trigger->led_cdevs); 119 list_add_tail(&led_cdev->trig_list, &trig->led_cdevs);
120 write_unlock_irqrestore(&trigger->leddev_list_lock, flags); 120 write_unlock_irqrestore(&trig->leddev_list_lock, flags);
121 led_cdev->trigger = trigger; 121 led_cdev->trigger = trig;
122 if (trigger->activate) 122 if (trig->activate)
123 trigger->activate(led_cdev); 123 trig->activate(led_cdev);
124 } 124 }
125} 125}
126EXPORT_SYMBOL_GPL(led_trigger_set); 126EXPORT_SYMBOL_GPL(led_trigger_set);
@@ -153,24 +153,24 @@ EXPORT_SYMBOL_GPL(led_trigger_set_default);
153 153
154/* LED Trigger Interface */ 154/* LED Trigger Interface */
155 155
156int led_trigger_register(struct led_trigger *trigger) 156int led_trigger_register(struct led_trigger *trig)
157{ 157{
158 struct led_classdev *led_cdev; 158 struct led_classdev *led_cdev;
159 struct led_trigger *trig; 159 struct led_trigger *_trig;
160 160
161 rwlock_init(&trigger->leddev_list_lock); 161 rwlock_init(&trig->leddev_list_lock);
162 INIT_LIST_HEAD(&trigger->led_cdevs); 162 INIT_LIST_HEAD(&trig->led_cdevs);
163 163
164 down_write(&triggers_list_lock); 164 down_write(&triggers_list_lock);
165 /* Make sure the trigger's name isn't already in use */ 165 /* Make sure the trigger's name isn't already in use */
166 list_for_each_entry(trig, &trigger_list, next_trig) { 166 list_for_each_entry(_trig, &trigger_list, next_trig) {
167 if (!strcmp(trig->name, trigger->name)) { 167 if (!strcmp(_trig->name, trig->name)) {
168 up_write(&triggers_list_lock); 168 up_write(&triggers_list_lock);
169 return -EEXIST; 169 return -EEXIST;
170 } 170 }
171 } 171 }
172 /* Add to the list of led triggers */ 172 /* Add to the list of led triggers */
173 list_add_tail(&trigger->next_trig, &trigger_list); 173 list_add_tail(&trig->next_trig, &trigger_list);
174 up_write(&triggers_list_lock); 174 up_write(&triggers_list_lock);
175 175
176 /* Register with any LEDs that have this as a default trigger */ 176 /* Register with any LEDs that have this as a default trigger */
@@ -178,8 +178,8 @@ int led_trigger_register(struct led_trigger *trigger)
178 list_for_each_entry(led_cdev, &leds_list, node) { 178 list_for_each_entry(led_cdev, &leds_list, node) {
179 down_write(&led_cdev->trigger_lock); 179 down_write(&led_cdev->trigger_lock);
180 if (!led_cdev->trigger && led_cdev->default_trigger && 180 if (!led_cdev->trigger && led_cdev->default_trigger &&
181 !strcmp(led_cdev->default_trigger, trigger->name)) 181 !strcmp(led_cdev->default_trigger, trig->name))
182 led_trigger_set(led_cdev, trigger); 182 led_trigger_set(led_cdev, trig);
183 up_write(&led_cdev->trigger_lock); 183 up_write(&led_cdev->trigger_lock);
184 } 184 }
185 up_read(&leds_list_lock); 185 up_read(&leds_list_lock);
@@ -188,20 +188,20 @@ int led_trigger_register(struct led_trigger *trigger)
188} 188}
189EXPORT_SYMBOL_GPL(led_trigger_register); 189EXPORT_SYMBOL_GPL(led_trigger_register);
190 190
191void led_trigger_unregister(struct led_trigger *trigger) 191void led_trigger_unregister(struct led_trigger *trig)
192{ 192{
193 struct led_classdev *led_cdev; 193 struct led_classdev *led_cdev;
194 194
195 /* Remove from the list of led triggers */ 195 /* Remove from the list of led triggers */
196 down_write(&triggers_list_lock); 196 down_write(&triggers_list_lock);
197 list_del(&trigger->next_trig); 197 list_del(&trig->next_trig);
198 up_write(&triggers_list_lock); 198 up_write(&triggers_list_lock);
199 199
200 /* Remove anyone actively using this trigger */ 200 /* Remove anyone actively using this trigger */
201 down_read(&leds_list_lock); 201 down_read(&leds_list_lock);
202 list_for_each_entry(led_cdev, &leds_list, node) { 202 list_for_each_entry(led_cdev, &leds_list, node) {
203 down_write(&led_cdev->trigger_lock); 203 down_write(&led_cdev->trigger_lock);
204 if (led_cdev->trigger == trigger) 204 if (led_cdev->trigger == trig)
205 led_trigger_set(led_cdev, NULL); 205 led_trigger_set(led_cdev, NULL);
206 up_write(&led_cdev->trigger_lock); 206 up_write(&led_cdev->trigger_lock);
207 } 207 }
@@ -211,58 +211,80 @@ EXPORT_SYMBOL_GPL(led_trigger_unregister);
211 211
212/* Simple LED Tigger Interface */ 212/* Simple LED Tigger Interface */
213 213
214void led_trigger_event(struct led_trigger *trigger, 214void led_trigger_event(struct led_trigger *trig,
215 enum led_brightness brightness) 215 enum led_brightness brightness)
216{ 216{
217 struct list_head *entry; 217 struct list_head *entry;
218 218
219 if (!trigger) 219 if (!trig)
220 return; 220 return;
221 221
222 read_lock(&trigger->leddev_list_lock); 222 read_lock(&trig->leddev_list_lock);
223 list_for_each(entry, &trigger->led_cdevs) { 223 list_for_each(entry, &trig->led_cdevs) {
224 struct led_classdev *led_cdev; 224 struct led_classdev *led_cdev;
225 225
226 led_cdev = list_entry(entry, struct led_classdev, trig_list); 226 led_cdev = list_entry(entry, struct led_classdev, trig_list);
227 led_set_brightness(led_cdev, brightness); 227 __led_set_brightness(led_cdev, brightness);
228 } 228 }
229 read_unlock(&trigger->leddev_list_lock); 229 read_unlock(&trig->leddev_list_lock);
230} 230}
231EXPORT_SYMBOL_GPL(led_trigger_event); 231EXPORT_SYMBOL_GPL(led_trigger_event);
232 232
233void led_trigger_blink(struct led_trigger *trigger, 233static 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
239 if (!trigger) 241 if (!trig)
240 return; 242 return;
241 243
242 read_lock(&trigger->leddev_list_lock); 244 read_lock(&trig->leddev_list_lock);
243 list_for_each(entry, &trigger->led_cdevs) { 245 list_for_each(entry, &trig->led_cdevs) {
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(&trigger->leddev_list_lock); 255 read_unlock(&trig->leddev_list_lock);
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);
250} 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 *trigger; 277 struct led_trigger *trig;
256 int err; 278 int err;
257 279
258 trigger = kzalloc(sizeof(struct led_trigger), GFP_KERNEL); 280 trig = kzalloc(sizeof(struct led_trigger), GFP_KERNEL);
259 281
260 if (trigger) { 282 if (trig) {
261 trigger->name = name; 283 trig->name = name;
262 err = led_trigger_register(trigger); 284 err = led_trigger_register(trig);
263 if (err < 0) { 285 if (err < 0) {
264 kfree(trigger); 286 kfree(trig);
265 trigger = NULL; 287 trig = NULL;
266 printk(KERN_WARNING "LED trigger %s failed to register" 288 printk(KERN_WARNING "LED trigger %s failed to register"
267 " (%d)\n", name, err); 289 " (%d)\n", name, err);
268 } 290 }
@@ -270,15 +292,15 @@ void led_trigger_register_simple(const char *name, struct led_trigger **tp)
270 printk(KERN_WARNING "LED trigger %s failed to register" 292 printk(KERN_WARNING "LED trigger %s failed to register"
271 " (no memory)\n", name); 293 " (no memory)\n", name);
272 294
273 *tp = trigger; 295 *tp = trig;
274} 296}
275EXPORT_SYMBOL_GPL(led_trigger_register_simple); 297EXPORT_SYMBOL_GPL(led_trigger_register_simple);
276 298
277void led_trigger_unregister_simple(struct led_trigger *trigger) 299void led_trigger_unregister_simple(struct led_trigger *trig)
278{ 300{
279 if (trigger) 301 if (trig)
280 led_trigger_unregister(trigger); 302 led_trigger_unregister(trig);
281 kfree(trigger); 303 kfree(trig);
282} 304}
283EXPORT_SYMBOL_GPL(led_trigger_unregister_simple); 305EXPORT_SYMBOL_GPL(led_trigger_unregister_simple);
284 306