Răsfoiți Sursa

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>
Sebastian Hesselbarth 10 ani în urmă
părinte
comite
65c6b7e3ab
1 a modificat fișierele cu 3 adăugiri și 2 ștergeri
  1. 3 2
      drivers/leds/leds-gpio.c

+ 3 - 2
drivers/leds/leds-gpio.c

@@ -217,18 +217,19 @@ static struct gpio_leds_priv *gpio_leds_create(struct platform_device *pdev)
 		if (fwnode_property_present(child, "retain-state-suspended"))
 		if (fwnode_property_present(child, "retain-state-suspended"))
 			led.retain_state_suspended = 1;
 			led.retain_state_suspended = 1;
 
 
-		ret = create_gpio_led(&led, &priv->leds[priv->num_leds++],
+		ret = create_gpio_led(&led, &priv->leds[priv->num_leds],
 				      dev, NULL);
 				      dev, NULL);
 		if (ret < 0) {
 		if (ret < 0) {
 			fwnode_handle_put(child);
 			fwnode_handle_put(child);
 			goto err;
 			goto err;
 		}
 		}
+		priv->num_leds++;
 	}
 	}
 
 
 	return priv;
 	return priv;
 
 
 err:
 err:
-	for (count = priv->num_leds - 2; count >= 0; count--)
+	for (count = priv->num_leds - 1; count >= 0; count--)
 		delete_gpio_led(&priv->leds[count]);
 		delete_gpio_led(&priv->leds[count]);
 	return ERR_PTR(ret);
 	return ERR_PTR(ret);
 }
 }