diff options
Diffstat (limited to 'drivers/leds/led-triggers.c')
-rw-r--r-- | drivers/leds/led-triggers.c | 24 |
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, | |||
103 | EXPORT_SYMBOL_GPL(led_trigger_show); | 103 | EXPORT_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 */ |
106 | void led_trigger_set(struct led_classdev *led_cdev, struct led_trigger *trig) | 106 | int 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 | |||
159 | err_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 | } |
150 | EXPORT_SYMBOL_GPL(led_trigger_set); | 168 | EXPORT_SYMBOL_GPL(led_trigger_set); |
151 | 169 | ||