cpqarray: switch to seq_file
[safe/jmp/linux-2.6] / drivers / leds / led-triggers.c
index 0bdb786..d8ddd9e 100644 (file)
@@ -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,21 +149,32 @@ 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)
 {
        struct led_classdev *led_cdev;
+       struct led_trigger *trig;
 
        rwlock_init(&trigger->leddev_list_lock);
        INIT_LIST_HEAD(&trigger->led_cdevs);
 
-       /* Add to the list of led triggers */
        down_write(&triggers_list_lock);
+       /* Make sure the trigger's name isn't already in use */
+       list_for_each_entry(trig, &trigger_list, next_trig) {
+               if (!strcmp(trig->name, trigger->name)) {
+                       up_write(&triggers_list_lock);
+                       return -EEXIST;
+               }
+       }
+       /* Add to the list of led triggers */
        list_add_tail(&trigger->next_trig, &trigger_list);
        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 +182,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 +249,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 +257,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");