diff options
author | Roland Stigge <stigge@antcom.de> | 2012-10-28 11:34:59 -0400 |
---|---|---|
committer | Bryan Wu <cooloney@gmail.com> | 2012-11-26 17:28:49 -0500 |
commit | 04553e925baaa815025c6fd3cdc301a794fa2c74 (patch) | |
tree | 39d49a08fca20eccdb2dc308a15e81f41096fc7d /drivers/leds | |
parent | e8941928faf248530c0eff95462e9fee0b1cc8da (diff) |
leds: leds-gpio: Defer probing in case of deferred gpio probing
This patch makes leds-gpio's probe() return -EPROBE_DEFER if any of the gpios
to register are deferred themselves. This makes a change of
gpio_leds_create_of()'s return value necessary: Instead of returning NULL on
error, we now use ERR_PTR() error coding.
Signed-off-by: Roland Stigge <stigge@antcom.de>
Signed-off-by: Bryan Wu <cooloney@gmail.com>
Diffstat (limited to 'drivers/leds')
-rw-r--r-- | drivers/leds/leds-gpio.c | 17 |
1 files changed, 11 insertions, 6 deletions
diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c index 0b4185315261..6a2109638fbe 100644 --- a/drivers/leds/leds-gpio.c +++ b/drivers/leds/leds-gpio.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/workqueue.h> | 21 | #include <linux/workqueue.h> |
22 | #include <linux/module.h> | 22 | #include <linux/module.h> |
23 | #include <linux/pinctrl/consumer.h> | 23 | #include <linux/pinctrl/consumer.h> |
24 | #include <linux/err.h> | ||
24 | 25 | ||
25 | struct gpio_led_data { | 26 | struct gpio_led_data { |
26 | struct led_classdev cdev; | 27 | struct led_classdev cdev; |
@@ -174,12 +175,16 @@ static struct gpio_leds_priv * __devinit gpio_leds_create_of(struct platform_dev | |||
174 | /* count LEDs in this device, so we know how much to allocate */ | 175 | /* count LEDs in this device, so we know how much to allocate */ |
175 | count = of_get_child_count(np); | 176 | count = of_get_child_count(np); |
176 | if (!count) | 177 | if (!count) |
177 | return NULL; | 178 | return ERR_PTR(-ENODEV); |
179 | |||
180 | for_each_child_of_node(np, child) | ||
181 | if (of_get_gpio(child, 0) == -EPROBE_DEFER) | ||
182 | return ERR_PTR(-EPROBE_DEFER); | ||
178 | 183 | ||
179 | priv = devm_kzalloc(&pdev->dev, sizeof_gpio_leds_priv(count), | 184 | priv = devm_kzalloc(&pdev->dev, sizeof_gpio_leds_priv(count), |
180 | GFP_KERNEL); | 185 | GFP_KERNEL); |
181 | if (!priv) | 186 | if (!priv) |
182 | return NULL; | 187 | return ERR_PTR(-ENOMEM); |
183 | 188 | ||
184 | for_each_child_of_node(np, child) { | 189 | for_each_child_of_node(np, child) { |
185 | struct gpio_led led = {}; | 190 | struct gpio_led led = {}; |
@@ -214,7 +219,7 @@ static struct gpio_leds_priv * __devinit gpio_leds_create_of(struct platform_dev | |||
214 | err: | 219 | err: |
215 | for (count = priv->num_leds - 2; count >= 0; count--) | 220 | for (count = priv->num_leds - 2; count >= 0; count--) |
216 | delete_gpio_led(&priv->leds[count]); | 221 | delete_gpio_led(&priv->leds[count]); |
217 | return NULL; | 222 | return ERR_PTR(-ENODEV); |
218 | } | 223 | } |
219 | 224 | ||
220 | static const struct of_device_id of_gpio_leds_match[] = { | 225 | static const struct of_device_id of_gpio_leds_match[] = { |
@@ -224,7 +229,7 @@ static const struct of_device_id of_gpio_leds_match[] = { | |||
224 | #else /* CONFIG_OF_GPIO */ | 229 | #else /* CONFIG_OF_GPIO */ |
225 | static struct gpio_leds_priv * __devinit gpio_leds_create_of(struct platform_device *pdev) | 230 | static struct gpio_leds_priv * __devinit gpio_leds_create_of(struct platform_device *pdev) |
226 | { | 231 | { |
227 | return NULL; | 232 | return ERR_PTR(-ENODEV); |
228 | } | 233 | } |
229 | #endif /* CONFIG_OF_GPIO */ | 234 | #endif /* CONFIG_OF_GPIO */ |
230 | 235 | ||
@@ -262,8 +267,8 @@ static int __devinit gpio_led_probe(struct platform_device *pdev) | |||
262 | } | 267 | } |
263 | } else { | 268 | } else { |
264 | priv = gpio_leds_create_of(pdev); | 269 | priv = gpio_leds_create_of(pdev); |
265 | if (!priv) | 270 | if (IS_ERR(priv)) |
266 | return -ENODEV; | 271 | return PTR_ERR(priv); |
267 | } | 272 | } |
268 | 273 | ||
269 | platform_set_drvdata(pdev, priv); | 274 | platform_set_drvdata(pdev, priv); |