diff options
Diffstat (limited to 'drivers/leds/led-triggers.c')
-rw-r--r-- | drivers/leds/led-triggers.c | 120 |
1 files changed, 63 insertions, 57 deletions
diff --git a/drivers/leds/led-triggers.c b/drivers/leds/led-triggers.c index 13c9026d68af..0f242b3f09b6 100644 --- a/drivers/leds/led-triggers.c +++ b/drivers/leds/led-triggers.c | |||
@@ -29,6 +29,8 @@ | |||
29 | static DECLARE_RWSEM(triggers_list_lock); | 29 | static DECLARE_RWSEM(triggers_list_lock); |
30 | static LIST_HEAD(trigger_list); | 30 | static LIST_HEAD(trigger_list); |
31 | 31 | ||
32 | /* Used by LED Class */ | ||
33 | |||
32 | ssize_t led_trigger_store(struct device *dev, struct device_attribute *attr, | 34 | ssize_t led_trigger_store(struct device *dev, struct device_attribute *attr, |
33 | const char *buf, size_t count) | 35 | const char *buf, size_t count) |
34 | { | 36 | { |
@@ -45,9 +47,7 @@ ssize_t led_trigger_store(struct device *dev, struct device_attribute *attr, | |||
45 | trigger_name[len - 1] = '\0'; | 47 | trigger_name[len - 1] = '\0'; |
46 | 48 | ||
47 | if (!strcmp(trigger_name, "none")) { | 49 | if (!strcmp(trigger_name, "none")) { |
48 | down_write(&led_cdev->trigger_lock); | 50 | led_trigger_remove(led_cdev); |
49 | led_trigger_set(led_cdev, NULL); | ||
50 | up_write(&led_cdev->trigger_lock); | ||
51 | return count; | 51 | return count; |
52 | } | 52 | } |
53 | 53 | ||
@@ -66,7 +66,7 @@ ssize_t led_trigger_store(struct device *dev, struct device_attribute *attr, | |||
66 | 66 | ||
67 | return -EINVAL; | 67 | return -EINVAL; |
68 | } | 68 | } |
69 | 69 | EXPORT_SYMBOL_GPL(led_trigger_store); | |
70 | 70 | ||
71 | ssize_t led_trigger_show(struct device *dev, struct device_attribute *attr, | 71 | ssize_t led_trigger_show(struct device *dev, struct device_attribute *attr, |
72 | char *buf) | 72 | char *buf) |
@@ -96,24 +96,7 @@ ssize_t led_trigger_show(struct device *dev, struct device_attribute *attr, | |||
96 | len += sprintf(len+buf, "\n"); | 96 | len += sprintf(len+buf, "\n"); |
97 | return len; | 97 | return len; |
98 | } | 98 | } |
99 | 99 | EXPORT_SYMBOL_GPL(led_trigger_show); | |
100 | void led_trigger_event(struct led_trigger *trigger, | ||
101 | enum led_brightness brightness) | ||
102 | { | ||
103 | struct list_head *entry; | ||
104 | |||
105 | if (!trigger) | ||
106 | return; | ||
107 | |||
108 | read_lock(&trigger->leddev_list_lock); | ||
109 | list_for_each(entry, &trigger->led_cdevs) { | ||
110 | struct led_classdev *led_cdev; | ||
111 | |||
112 | led_cdev = list_entry(entry, struct led_classdev, trig_list); | ||
113 | led_set_brightness(led_cdev, brightness); | ||
114 | } | ||
115 | read_unlock(&trigger->leddev_list_lock); | ||
116 | } | ||
117 | 100 | ||
118 | /* Caller must ensure led_cdev->trigger_lock held */ | 101 | /* Caller must ensure led_cdev->trigger_lock held */ |
119 | void led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trigger) | 102 | void led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trigger) |
@@ -124,7 +107,8 @@ void led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trigger) | |||
124 | if (led_cdev->trigger) { | 107 | if (led_cdev->trigger) { |
125 | write_lock_irqsave(&led_cdev->trigger->leddev_list_lock, flags); | 108 | write_lock_irqsave(&led_cdev->trigger->leddev_list_lock, flags); |
126 | list_del(&led_cdev->trig_list); | 109 | list_del(&led_cdev->trig_list); |
127 | write_unlock_irqrestore(&led_cdev->trigger->leddev_list_lock, flags); | 110 | write_unlock_irqrestore(&led_cdev->trigger->leddev_list_lock, |
111 | flags); | ||
128 | if (led_cdev->trigger->deactivate) | 112 | if (led_cdev->trigger->deactivate) |
129 | led_cdev->trigger->deactivate(led_cdev); | 113 | led_cdev->trigger->deactivate(led_cdev); |
130 | led_set_brightness(led_cdev, LED_OFF); | 114 | led_set_brightness(led_cdev, LED_OFF); |
@@ -138,6 +122,15 @@ void led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trigger) | |||
138 | } | 122 | } |
139 | led_cdev->trigger = trigger; | 123 | led_cdev->trigger = trigger; |
140 | } | 124 | } |
125 | EXPORT_SYMBOL_GPL(led_trigger_set); | ||
126 | |||
127 | void led_trigger_remove(struct led_classdev *led_cdev) | ||
128 | { | ||
129 | down_write(&led_cdev->trigger_lock); | ||
130 | led_trigger_set(led_cdev, NULL); | ||
131 | up_write(&led_cdev->trigger_lock); | ||
132 | } | ||
133 | EXPORT_SYMBOL_GPL(led_trigger_remove); | ||
141 | 134 | ||
142 | void led_trigger_set_default(struct led_classdev *led_cdev) | 135 | void led_trigger_set_default(struct led_classdev *led_cdev) |
143 | { | 136 | { |
@@ -155,6 +148,9 @@ void led_trigger_set_default(struct led_classdev *led_cdev) | |||
155 | up_write(&led_cdev->trigger_lock); | 148 | up_write(&led_cdev->trigger_lock); |
156 | up_read(&triggers_list_lock); | 149 | up_read(&triggers_list_lock); |
157 | } | 150 | } |
151 | EXPORT_SYMBOL_GPL(led_trigger_set_default); | ||
152 | |||
153 | /* LED Trigger Interface */ | ||
158 | 154 | ||
159 | int led_trigger_register(struct led_trigger *trigger) | 155 | int led_trigger_register(struct led_trigger *trigger) |
160 | { | 156 | { |
@@ -181,26 +177,7 @@ int led_trigger_register(struct led_trigger *trigger) | |||
181 | 177 | ||
182 | return 0; | 178 | return 0; |
183 | } | 179 | } |
184 | 180 | EXPORT_SYMBOL_GPL(led_trigger_register); | |
185 | void led_trigger_register_simple(const char *name, struct led_trigger **tp) | ||
186 | { | ||
187 | struct led_trigger *trigger; | ||
188 | int err; | ||
189 | |||
190 | trigger = kzalloc(sizeof(struct led_trigger), GFP_KERNEL); | ||
191 | |||
192 | if (trigger) { | ||
193 | trigger->name = name; | ||
194 | err = led_trigger_register(trigger); | ||
195 | if (err < 0) | ||
196 | printk(KERN_WARNING "LED trigger %s failed to register" | ||
197 | " (%d)\n", name, err); | ||
198 | } else | ||
199 | printk(KERN_WARNING "LED trigger %s failed to register" | ||
200 | " (no memory)\n", name); | ||
201 | |||
202 | *tp = trigger; | ||
203 | } | ||
204 | 181 | ||
205 | void led_trigger_unregister(struct led_trigger *trigger) | 182 | void led_trigger_unregister(struct led_trigger *trigger) |
206 | { | 183 | { |
@@ -221,6 +198,49 @@ void led_trigger_unregister(struct led_trigger *trigger) | |||
221 | } | 198 | } |
222 | up_read(&leds_list_lock); | 199 | up_read(&leds_list_lock); |
223 | } | 200 | } |
201 | EXPORT_SYMBOL_GPL(led_trigger_unregister); | ||
202 | |||
203 | /* Simple LED Tigger Interface */ | ||
204 | |||
205 | void led_trigger_event(struct led_trigger *trigger, | ||
206 | enum led_brightness brightness) | ||
207 | { | ||
208 | struct list_head *entry; | ||
209 | |||
210 | if (!trigger) | ||
211 | return; | ||
212 | |||
213 | read_lock(&trigger->leddev_list_lock); | ||
214 | list_for_each(entry, &trigger->led_cdevs) { | ||
215 | struct led_classdev *led_cdev; | ||
216 | |||
217 | led_cdev = list_entry(entry, struct led_classdev, trig_list); | ||
218 | led_set_brightness(led_cdev, brightness); | ||
219 | } | ||
220 | read_unlock(&trigger->leddev_list_lock); | ||
221 | } | ||
222 | EXPORT_SYMBOL_GPL(led_trigger_event); | ||
223 | |||
224 | void led_trigger_register_simple(const char *name, struct led_trigger **tp) | ||
225 | { | ||
226 | struct led_trigger *trigger; | ||
227 | int err; | ||
228 | |||
229 | trigger = kzalloc(sizeof(struct led_trigger), GFP_KERNEL); | ||
230 | |||
231 | if (trigger) { | ||
232 | trigger->name = name; | ||
233 | err = led_trigger_register(trigger); | ||
234 | if (err < 0) | ||
235 | printk(KERN_WARNING "LED trigger %s failed to register" | ||
236 | " (%d)\n", name, err); | ||
237 | } else | ||
238 | printk(KERN_WARNING "LED trigger %s failed to register" | ||
239 | " (no memory)\n", name); | ||
240 | |||
241 | *tp = trigger; | ||
242 | } | ||
243 | EXPORT_SYMBOL_GPL(led_trigger_register_simple); | ||
224 | 244 | ||
225 | void led_trigger_unregister_simple(struct led_trigger *trigger) | 245 | void led_trigger_unregister_simple(struct led_trigger *trigger) |
226 | { | 246 | { |
@@ -228,21 +248,7 @@ void led_trigger_unregister_simple(struct led_trigger *trigger) | |||
228 | led_trigger_unregister(trigger); | 248 | led_trigger_unregister(trigger); |
229 | kfree(trigger); | 249 | kfree(trigger); |
230 | } | 250 | } |
231 | |||
232 | /* Used by LED Class */ | ||
233 | EXPORT_SYMBOL_GPL(led_trigger_set); | ||
234 | EXPORT_SYMBOL_GPL(led_trigger_set_default); | ||
235 | EXPORT_SYMBOL_GPL(led_trigger_show); | ||
236 | EXPORT_SYMBOL_GPL(led_trigger_store); | ||
237 | |||
238 | /* LED Trigger Interface */ | ||
239 | EXPORT_SYMBOL_GPL(led_trigger_register); | ||
240 | EXPORT_SYMBOL_GPL(led_trigger_unregister); | ||
241 | |||
242 | /* Simple LED Tigger Interface */ | ||
243 | EXPORT_SYMBOL_GPL(led_trigger_register_simple); | ||
244 | EXPORT_SYMBOL_GPL(led_trigger_unregister_simple); | 251 | EXPORT_SYMBOL_GPL(led_trigger_unregister_simple); |
245 | EXPORT_SYMBOL_GPL(led_trigger_event); | ||
246 | 252 | ||
247 | MODULE_AUTHOR("Richard Purdie"); | 253 | MODULE_AUTHOR("Richard Purdie"); |
248 | MODULE_LICENSE("GPL"); | 254 | MODULE_LICENSE("GPL"); |