Commit aa1a6d6d authored by Peter Ujfalusi's avatar Peter Ujfalusi Committed by Bryan Wu

leds: pwm: Fix for deferred probe in DT booted mode

We need to make sure that the error code from devm_of_pwm_get() is the one
the module returns in case of failure.
Restructure the code to make this possible for DT booted case.
With this patch the driver can ask for deferred probing when the board is
booted with DT.
Fixes for example omap4-sdp board's keyboard backlight led.
Signed-off-by: default avatarPeter Ujfalusi <peter.ujfalusi@ti.com>
Signed-off-by: default avatarBryan Wu <cooloney@gmail.com>
parent dc1ccc48
...@@ -82,22 +82,12 @@ static inline size_t sizeof_pwm_leds_priv(int num_leds) ...@@ -82,22 +82,12 @@ static inline size_t sizeof_pwm_leds_priv(int num_leds)
(sizeof(struct led_pwm_data) * num_leds); (sizeof(struct led_pwm_data) * num_leds);
} }
static struct led_pwm_priv *led_pwm_create_of(struct platform_device *pdev) static int led_pwm_create_of(struct platform_device *pdev,
struct led_pwm_priv *priv)
{ {
struct device_node *node = pdev->dev.of_node; struct device_node *node = pdev->dev.of_node;
struct device_node *child; struct device_node *child;
struct led_pwm_priv *priv; int ret;
int count, ret;
/* count LEDs in this device, so we know how much to allocate */
count = of_get_child_count(node);
if (!count)
return NULL;
priv = devm_kzalloc(&pdev->dev, sizeof_pwm_leds_priv(count),
GFP_KERNEL);
if (!priv)
return NULL;
for_each_child_of_node(node, child) { for_each_child_of_node(node, child) {
struct led_pwm_data *led_dat = &priv->leds[priv->num_leds]; struct led_pwm_data *led_dat = &priv->leds[priv->num_leds];
...@@ -109,6 +99,7 @@ static struct led_pwm_priv *led_pwm_create_of(struct platform_device *pdev) ...@@ -109,6 +99,7 @@ static struct led_pwm_priv *led_pwm_create_of(struct platform_device *pdev)
if (IS_ERR(led_dat->pwm)) { if (IS_ERR(led_dat->pwm)) {
dev_err(&pdev->dev, "unable to request PWM for %s\n", dev_err(&pdev->dev, "unable to request PWM for %s\n",
led_dat->cdev.name); led_dat->cdev.name);
ret = PTR_ERR(led_dat->pwm);
goto err; goto err;
} }
/* Get the period from PWM core when n*/ /* Get the period from PWM core when n*/
...@@ -137,28 +128,36 @@ static struct led_pwm_priv *led_pwm_create_of(struct platform_device *pdev) ...@@ -137,28 +128,36 @@ static struct led_pwm_priv *led_pwm_create_of(struct platform_device *pdev)
priv->num_leds++; priv->num_leds++;
} }
return priv; return 0;
err: err:
while (priv->num_leds--) while (priv->num_leds--)
led_classdev_unregister(&priv->leds[priv->num_leds].cdev); led_classdev_unregister(&priv->leds[priv->num_leds].cdev);
return NULL; return ret;
} }
static int led_pwm_probe(struct platform_device *pdev) static int led_pwm_probe(struct platform_device *pdev)
{ {
struct led_pwm_platform_data *pdata = dev_get_platdata(&pdev->dev); struct led_pwm_platform_data *pdata = dev_get_platdata(&pdev->dev);
struct led_pwm_priv *priv; struct led_pwm_priv *priv;
int i, ret = 0; int count, i;
int ret = 0;
if (pdata)
count = pdata->num_leds;
else
count = of_get_child_count(pdev->dev.of_node);
if (!count)
return -EINVAL;
if (pdata && pdata->num_leds) { priv = devm_kzalloc(&pdev->dev, sizeof_pwm_leds_priv(count),
priv = devm_kzalloc(&pdev->dev,
sizeof_pwm_leds_priv(pdata->num_leds),
GFP_KERNEL); GFP_KERNEL);
if (!priv) if (!priv)
return -ENOMEM; return -ENOMEM;
for (i = 0; i < pdata->num_leds; i++) { if (pdata) {
for (i = 0; i < count; i++) {
struct led_pwm *cur_led = &pdata->leds[i]; struct led_pwm *cur_led = &pdata->leds[i];
struct led_pwm_data *led_dat = &priv->leds[i]; struct led_pwm_data *led_dat = &priv->leds[i];
...@@ -188,11 +187,11 @@ static int led_pwm_probe(struct platform_device *pdev) ...@@ -188,11 +187,11 @@ static int led_pwm_probe(struct platform_device *pdev)
if (ret < 0) if (ret < 0)
goto err; goto err;
} }
priv->num_leds = pdata->num_leds; priv->num_leds = count;
} else { } else {
priv = led_pwm_create_of(pdev); ret = led_pwm_create_of(pdev, priv);
if (!priv) if (ret)
return -ENODEV; return ret;
} }
platform_set_drvdata(pdev, priv); platform_set_drvdata(pdev, priv);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment