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"); |
