diff options
author | Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> | 2015-04-14 17:23:30 -0400 |
---|---|---|
committer | Bryan Wu <cooloney@gmail.com> | 2015-05-04 14:05:54 -0400 |
commit | 65c6b7e3ab70effc150dacc9c2fbd6581925dd53 (patch) | |
tree | e2babc061bd43fe446f8734024c57134a2511ac0 /drivers/leds/leds-gpio.c | |
parent | e370d010a5fe385ae65635ce0dbb1eff0e25059c (diff) |
leds: gpio: Fix device teardown on probe deferral
In gpio_leds_create(), when devm_get_gpiod_from_child() fails with
-EPROBE_DEFER on the second gpio led to be created, the first already
registered led is not torn down properly. This causes create_gpio_led()
to fail for the first led on re-probe().
Fix this misbehaviour by incrementing num_leds only if all
potentially failing calls completed successfully.
Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
Acked-by: Jacek Anaszewski <j.anaszewski@samsung.com>
Signed-off-by: Bryan Wu <cooloney@gmail.com>
Diffstat (limited to 'drivers/leds/leds-gpio.c')
-rw-r--r-- | drivers/leds/leds-gpio.c | 5 |
1 files changed, 3 insertions, 2 deletions
diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c index 15eb3f86f670..25df4a240972 100644 --- a/drivers/leds/leds-gpio.c +++ b/drivers/leds/leds-gpio.c | |||
@@ -217,18 +217,19 @@ static struct gpio_leds_priv *gpio_leds_create(struct platform_device *pdev) | |||
217 | if (fwnode_property_present(child, "retain-state-suspended")) | 217 | if (fwnode_property_present(child, "retain-state-suspended")) |
218 | led.retain_state_suspended = 1; | 218 | led.retain_state_suspended = 1; |
219 | 219 | ||
220 | ret = create_gpio_led(&led, &priv->leds[priv->num_leds++], | 220 | ret = create_gpio_led(&led, &priv->leds[priv->num_leds], |
221 | dev, NULL); | 221 | dev, NULL); |
222 | if (ret < 0) { | 222 | if (ret < 0) { |
223 | fwnode_handle_put(child); | 223 | fwnode_handle_put(child); |
224 | goto err; | 224 | goto err; |
225 | } | 225 | } |
226 | priv->num_leds++; | ||
226 | } | 227 | } |
227 | 228 | ||
228 | return priv; | 229 | return priv; |
229 | 230 | ||
230 | err: | 231 | err: |
231 | for (count = priv->num_leds - 2; count >= 0; count--) | 232 | for (count = priv->num_leds - 1; count >= 0; count--) |
232 | delete_gpio_led(&priv->leds[count]); | 233 | delete_gpio_led(&priv->leds[count]); |
233 | return ERR_PTR(ret); | 234 | return ERR_PTR(ret); |
234 | } | 235 | } |