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.c24
1 files changed, 21 insertions, 3 deletions
diff --git a/drivers/leds/led-triggers.c b/drivers/leds/led-triggers.c
index 431123b048a2..a8786f4b3453 100644
--- a/drivers/leds/led-triggers.c
+++ b/drivers/leds/led-triggers.c
@@ -103,15 +103,16 @@ ssize_t led_trigger_show(struct device *dev, struct device_attribute *attr,
103EXPORT_SYMBOL_GPL(led_trigger_show); 103EXPORT_SYMBOL_GPL(led_trigger_show);
104 104
105/* Caller must ensure led_cdev->trigger_lock held */ 105/* Caller must ensure led_cdev->trigger_lock held */
106void led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trig) 106int led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trig)
107{ 107{
108 unsigned long flags; 108 unsigned long flags;
109 char *event = NULL; 109 char *event = NULL;
110 char *envp[2]; 110 char *envp[2];
111 const char *name; 111 const char *name;
112 int ret;
112 113
113 if (!led_cdev->trigger && !trig) 114 if (!led_cdev->trigger && !trig)
114 return; 115 return 0;
115 116
116 name = trig ? trig->name : "none"; 117 name = trig ? trig->name : "none";
117 event = kasprintf(GFP_KERNEL, "TRIGGER=%s", name); 118 event = kasprintf(GFP_KERNEL, "TRIGGER=%s", name);
@@ -134,8 +135,14 @@ void led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trig)
134 list_add_tail(&led_cdev->trig_list, &trig->led_cdevs); 135 list_add_tail(&led_cdev->trig_list, &trig->led_cdevs);
135 write_unlock_irqrestore(&trig->leddev_list_lock, flags); 136 write_unlock_irqrestore(&trig->leddev_list_lock, flags);
136 led_cdev->trigger = trig; 137 led_cdev->trigger = trig;
138
137 if (trig->activate) 139 if (trig->activate)
138 trig->activate(led_cdev); 140 ret = trig->activate(led_cdev);
141 else
142 ret = 0;
143
144 if (ret)
145 goto err_activate;
139 } 146 }
140 147
141 if (event) { 148 if (event) {
@@ -146,6 +153,17 @@ void led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trig)
146 "%s: Error sending uevent\n", __func__); 153 "%s: Error sending uevent\n", __func__);
147 kfree(event); 154 kfree(event);
148 } 155 }
156
157 return 0;
158
159err_activate:
160 led_cdev->trigger = NULL;
161 write_lock_irqsave(&led_cdev->trigger->leddev_list_lock, flags);
162 list_del(&led_cdev->trig_list);
163 write_unlock_irqrestore(&led_cdev->trigger->leddev_list_lock, flags);
164 led_set_brightness(led_cdev, LED_OFF);
165
166 return ret;
149} 167}
150EXPORT_SYMBOL_GPL(led_trigger_set); 168EXPORT_SYMBOL_GPL(led_trigger_set);
151 169