diff options
Diffstat (limited to 'drivers/leds/leds-pwm.c')
-rw-r--r-- | drivers/leds/leds-pwm.c | 53 |
1 files changed, 26 insertions, 27 deletions
diff --git a/drivers/leds/leds-pwm.c b/drivers/leds/leds-pwm.c index 2848171b8576..b31d8e99c419 100644 --- a/drivers/leds/leds-pwm.c +++ b/drivers/leds/leds-pwm.c | |||
@@ -82,22 +82,12 @@ static inline size_t sizeof_pwm_leds_priv(int num_leds) | |||
82 | (sizeof(struct led_pwm_data) * num_leds); | 82 | (sizeof(struct led_pwm_data) * num_leds); |
83 | } | 83 | } |
84 | 84 | ||
85 | static struct led_pwm_priv *led_pwm_create_of(struct platform_device *pdev) | 85 | static int led_pwm_create_of(struct platform_device *pdev, |
86 | struct led_pwm_priv *priv) | ||
86 | { | 87 | { |
87 | struct device_node *node = pdev->dev.of_node; | 88 | struct device_node *node = pdev->dev.of_node; |
88 | struct device_node *child; | 89 | struct device_node *child; |
89 | struct led_pwm_priv *priv; | 90 | int ret; |
90 | int count, ret; | ||
91 | |||
92 | /* count LEDs in this device, so we know how much to allocate */ | ||
93 | count = of_get_child_count(node); | ||
94 | if (!count) | ||
95 | return NULL; | ||
96 | |||
97 | priv = devm_kzalloc(&pdev->dev, sizeof_pwm_leds_priv(count), | ||
98 | GFP_KERNEL); | ||
99 | if (!priv) | ||
100 | return NULL; | ||
101 | 91 | ||
102 | for_each_child_of_node(node, child) { | 92 | for_each_child_of_node(node, child) { |
103 | struct led_pwm_data *led_dat = &priv->leds[priv->num_leds]; | 93 | 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 | if (IS_ERR(led_dat->pwm)) { | 99 | if (IS_ERR(led_dat->pwm)) { |
110 | dev_err(&pdev->dev, "unable to request PWM for %s\n", | 100 | dev_err(&pdev->dev, "unable to request PWM for %s\n", |
111 | led_dat->cdev.name); | 101 | led_dat->cdev.name); |
102 | ret = PTR_ERR(led_dat->pwm); | ||
112 | goto err; | 103 | goto err; |
113 | } | 104 | } |
114 | /* Get the period from PWM core when n*/ | 105 | /* 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 | priv->num_leds++; | 128 | priv->num_leds++; |
138 | } | 129 | } |
139 | 130 | ||
140 | return priv; | 131 | return 0; |
141 | err: | 132 | err: |
142 | while (priv->num_leds--) | 133 | while (priv->num_leds--) |
143 | led_classdev_unregister(&priv->leds[priv->num_leds].cdev); | 134 | led_classdev_unregister(&priv->leds[priv->num_leds].cdev); |
144 | 135 | ||
145 | return NULL; | 136 | return ret; |
146 | } | 137 | } |
147 | 138 | ||
148 | static int led_pwm_probe(struct platform_device *pdev) | 139 | static int led_pwm_probe(struct platform_device *pdev) |
149 | { | 140 | { |
150 | struct led_pwm_platform_data *pdata = dev_get_platdata(&pdev->dev); | 141 | struct led_pwm_platform_data *pdata = dev_get_platdata(&pdev->dev); |
151 | struct led_pwm_priv *priv; | 142 | struct led_pwm_priv *priv; |
152 | int i, ret = 0; | 143 | int count, i; |
144 | int ret = 0; | ||
145 | |||
146 | if (pdata) | ||
147 | count = pdata->num_leds; | ||
148 | else | ||
149 | count = of_get_child_count(pdev->dev.of_node); | ||
150 | |||
151 | if (!count) | ||
152 | return -EINVAL; | ||
153 | 153 | ||
154 | if (pdata && pdata->num_leds) { | 154 | priv = devm_kzalloc(&pdev->dev, sizeof_pwm_leds_priv(count), |
155 | priv = devm_kzalloc(&pdev->dev, | 155 | GFP_KERNEL); |
156 | sizeof_pwm_leds_priv(pdata->num_leds), | 156 | if (!priv) |
157 | GFP_KERNEL); | 157 | return -ENOMEM; |
158 | if (!priv) | ||
159 | return -ENOMEM; | ||
160 | 158 | ||
161 | for (i = 0; i < pdata->num_leds; i++) { | 159 | if (pdata) { |
160 | for (i = 0; i < count; i++) { | ||
162 | struct led_pwm *cur_led = &pdata->leds[i]; | 161 | struct led_pwm *cur_led = &pdata->leds[i]; |
163 | struct led_pwm_data *led_dat = &priv->leds[i]; | 162 | struct led_pwm_data *led_dat = &priv->leds[i]; |
164 | 163 | ||
@@ -188,11 +187,11 @@ static int led_pwm_probe(struct platform_device *pdev) | |||
188 | if (ret < 0) | 187 | if (ret < 0) |
189 | goto err; | 188 | goto err; |
190 | } | 189 | } |
191 | priv->num_leds = pdata->num_leds; | 190 | priv->num_leds = count; |
192 | } else { | 191 | } else { |
193 | priv = led_pwm_create_of(pdev); | 192 | ret = led_pwm_create_of(pdev, priv); |
194 | if (!priv) | 193 | if (ret) |
195 | return -ENODEV; | 194 | return ret; |
196 | } | 195 | } |
197 | 196 | ||
198 | platform_set_drvdata(pdev, priv); | 197 | platform_set_drvdata(pdev, priv); |