X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=drivers%2Fleds%2Fled-triggers.c;h=f910eaffe3a6f057cd835412204c304f1bd0af38;hb=ff5d48a6d18d09bb750d1f89f6464f5fdb6fc85b;hp=0bdb786210b1885bee8e6f194ccdcab09e5bdd18;hpb=b242a60206881559bb3102110048762422e6b74e;p=linux-2.6 diff --git a/drivers/leds/led-triggers.c b/drivers/leds/led-triggers.c index 0bdb786210..f910eaffe3 100644 --- a/drivers/leds/led-triggers.c +++ b/drivers/leds/led-triggers.c @@ -29,6 +29,8 @@ static DECLARE_RWSEM(triggers_list_lock); static LIST_HEAD(trigger_list); + /* Used by LED Class */ + ssize_t led_trigger_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { @@ -45,9 +47,7 @@ ssize_t led_trigger_store(struct device *dev, struct device_attribute *attr, trigger_name[len - 1] = '\0'; if (!strcmp(trigger_name, "none")) { - down_write(&led_cdev->trigger_lock); - led_trigger_set(led_cdev, NULL); - up_write(&led_cdev->trigger_lock); + led_trigger_remove(led_cdev); return count; } @@ -66,7 +66,7 @@ ssize_t led_trigger_store(struct device *dev, struct device_attribute *attr, return -EINVAL; } - +EXPORT_SYMBOL_GPL(led_trigger_store); ssize_t led_trigger_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -96,24 +96,7 @@ ssize_t led_trigger_show(struct device *dev, struct device_attribute *attr, len += sprintf(len+buf, "\n"); return len; } - -void led_trigger_event(struct led_trigger *trigger, - enum led_brightness brightness) -{ - struct list_head *entry; - - if (!trigger) - return; - - read_lock(&trigger->leddev_list_lock); - list_for_each(entry, &trigger->led_cdevs) { - struct led_classdev *led_cdev; - - led_cdev = list_entry(entry, struct led_classdev, trig_list); - led_set_brightness(led_cdev, brightness); - } - read_unlock(&trigger->leddev_list_lock); -} +EXPORT_SYMBOL_GPL(led_trigger_show); /* Caller must ensure led_cdev->trigger_lock held */ void led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trigger) @@ -124,20 +107,31 @@ void led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trigger) if (led_cdev->trigger) { write_lock_irqsave(&led_cdev->trigger->leddev_list_lock, flags); list_del(&led_cdev->trig_list); - write_unlock_irqrestore(&led_cdev->trigger->leddev_list_lock, flags); + write_unlock_irqrestore(&led_cdev->trigger->leddev_list_lock, + flags); if (led_cdev->trigger->deactivate) led_cdev->trigger->deactivate(led_cdev); + led_cdev->trigger = NULL; led_set_brightness(led_cdev, LED_OFF); } if (trigger) { write_lock_irqsave(&trigger->leddev_list_lock, flags); list_add_tail(&led_cdev->trig_list, &trigger->led_cdevs); write_unlock_irqrestore(&trigger->leddev_list_lock, flags); + led_cdev->trigger = trigger; if (trigger->activate) trigger->activate(led_cdev); } - led_cdev->trigger = trigger; } +EXPORT_SYMBOL_GPL(led_trigger_set); + +void led_trigger_remove(struct led_classdev *led_cdev) +{ + down_write(&led_cdev->trigger_lock); + led_trigger_set(led_cdev, NULL); + up_write(&led_cdev->trigger_lock); +} +EXPORT_SYMBOL_GPL(led_trigger_remove); void led_trigger_set_default(struct led_classdev *led_cdev) { @@ -155,6 +149,9 @@ void led_trigger_set_default(struct led_classdev *led_cdev) up_write(&led_cdev->trigger_lock); up_read(&triggers_list_lock); } +EXPORT_SYMBOL_GPL(led_trigger_set_default); + +/* LED Trigger Interface */ int led_trigger_register(struct led_trigger *trigger) { @@ -169,7 +166,7 @@ int led_trigger_register(struct led_trigger *trigger) up_write(&triggers_list_lock); /* Register with any LEDs that have this as a default trigger */ - read_lock(&leds_list_lock); + down_read(&leds_list_lock); list_for_each_entry(led_cdev, &leds_list, node) { down_write(&led_cdev->trigger_lock); if (!led_cdev->trigger && led_cdev->default_trigger && @@ -177,10 +174,53 @@ int led_trigger_register(struct led_trigger *trigger) led_trigger_set(led_cdev, trigger); up_write(&led_cdev->trigger_lock); } - read_unlock(&leds_list_lock); + up_read(&leds_list_lock); return 0; } +EXPORT_SYMBOL_GPL(led_trigger_register); + +void led_trigger_unregister(struct led_trigger *trigger) +{ + struct led_classdev *led_cdev; + + /* Remove from the list of led triggers */ + down_write(&triggers_list_lock); + list_del(&trigger->next_trig); + up_write(&triggers_list_lock); + + /* Remove anyone actively using this trigger */ + down_read(&leds_list_lock); + list_for_each_entry(led_cdev, &leds_list, node) { + down_write(&led_cdev->trigger_lock); + if (led_cdev->trigger == trigger) + led_trigger_set(led_cdev, NULL); + up_write(&led_cdev->trigger_lock); + } + up_read(&leds_list_lock); +} +EXPORT_SYMBOL_GPL(led_trigger_unregister); + +/* Simple LED Tigger Interface */ + +void led_trigger_event(struct led_trigger *trigger, + enum led_brightness brightness) +{ + struct list_head *entry; + + if (!trigger) + return; + + read_lock(&trigger->leddev_list_lock); + list_for_each(entry, &trigger->led_cdevs) { + struct led_classdev *led_cdev; + + led_cdev = list_entry(entry, struct led_classdev, trig_list); + led_set_brightness(led_cdev, brightness); + } + read_unlock(&trigger->leddev_list_lock); +} +EXPORT_SYMBOL_GPL(led_trigger_event); void led_trigger_register_simple(const char *name, struct led_trigger **tp) { @@ -201,26 +241,7 @@ void led_trigger_register_simple(const char *name, struct led_trigger **tp) *tp = trigger; } - -void led_trigger_unregister(struct led_trigger *trigger) -{ - struct led_classdev *led_cdev; - - /* Remove from the list of led triggers */ - down_write(&triggers_list_lock); - list_del(&trigger->next_trig); - up_write(&triggers_list_lock); - - /* Remove anyone actively using this trigger */ - read_lock(&leds_list_lock); - list_for_each_entry(led_cdev, &leds_list, node) { - down_write(&led_cdev->trigger_lock); - if (led_cdev->trigger == trigger) - led_trigger_set(led_cdev, NULL); - up_write(&led_cdev->trigger_lock); - } - read_unlock(&leds_list_lock); -} +EXPORT_SYMBOL_GPL(led_trigger_register_simple); void led_trigger_unregister_simple(struct led_trigger *trigger) { @@ -228,21 +249,7 @@ void led_trigger_unregister_simple(struct led_trigger *trigger) led_trigger_unregister(trigger); kfree(trigger); } - -/* Used by LED Class */ -EXPORT_SYMBOL_GPL(led_trigger_set); -EXPORT_SYMBOL_GPL(led_trigger_set_default); -EXPORT_SYMBOL_GPL(led_trigger_show); -EXPORT_SYMBOL_GPL(led_trigger_store); - -/* LED Trigger Interface */ -EXPORT_SYMBOL_GPL(led_trigger_register); -EXPORT_SYMBOL_GPL(led_trigger_unregister); - -/* Simple LED Tigger Interface */ -EXPORT_SYMBOL_GPL(led_trigger_register_simple); EXPORT_SYMBOL_GPL(led_trigger_unregister_simple); -EXPORT_SYMBOL_GPL(led_trigger_event); MODULE_AUTHOR("Richard Purdie"); MODULE_LICENSE("GPL");