diff options
author | Dan Carpenter <dan.carpenter@oracle.com> | 2013-02-14 02:26:43 -0500 |
---|---|---|
committer | Anton Vorontsov <anton@enomsg.org> | 2013-02-16 16:27:09 -0500 |
commit | 64d26f225fefe06c870634e7bfe026a063e7f776 (patch) | |
tree | e4c8079771c59852d2bc4fa6752096012d385572 /drivers/power/generic-adc-battery.c | |
parent | 049645d753e39cb64c8563faf865b0689256cf28 (diff) |
generic-adc-battery: Fix forever loop in gab_remove()
There is a forever loop calling iio_channel_release() because the
"chan < " part of the "chan < ARRAY_SIZE()" is missing. This is in both
the error handling on probe and also in the remove function.
The other thing is that it's possible for some of the elements of the
adc_bat->channel[chan] array to be an ERR_PTR(). I've changed them to be
NULL instead. We're still not allowed to pass NULLs to
iio_channel_release() so I've added a check.
Finally, I removed an unused "chan = ARRAY_SIZE(gab_chan_name);" statement
as a small cleanup.
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Anton Vorontsov <anton@enomsg.org>
Diffstat (limited to 'drivers/power/generic-adc-battery.c')
-rw-r--r-- | drivers/power/generic-adc-battery.c | 16 |
1 files changed, 9 insertions, 7 deletions
diff --git a/drivers/power/generic-adc-battery.c b/drivers/power/generic-adc-battery.c index 32ce17e235c0..836816b82cbc 100644 --- a/drivers/power/generic-adc-battery.c +++ b/drivers/power/generic-adc-battery.c | |||
@@ -263,9 +263,6 @@ static int gab_probe(struct platform_device *pdev) | |||
263 | psy->external_power_changed = gab_ext_power_changed; | 263 | psy->external_power_changed = gab_ext_power_changed; |
264 | adc_bat->pdata = pdata; | 264 | adc_bat->pdata = pdata; |
265 | 265 | ||
266 | /* calculate the total number of channels */ | ||
267 | chan = ARRAY_SIZE(gab_chan_name); | ||
268 | |||
269 | /* | 266 | /* |
270 | * copying the static properties and allocating extra memory for holding | 267 | * copying the static properties and allocating extra memory for holding |
271 | * the extra configurable properties received from platform data. | 268 | * the extra configurable properties received from platform data. |
@@ -291,6 +288,7 @@ static int gab_probe(struct platform_device *pdev) | |||
291 | gab_chan_name[chan]); | 288 | gab_chan_name[chan]); |
292 | if (IS_ERR(adc_bat->channel[chan])) { | 289 | if (IS_ERR(adc_bat->channel[chan])) { |
293 | ret = PTR_ERR(adc_bat->channel[chan]); | 290 | ret = PTR_ERR(adc_bat->channel[chan]); |
291 | adc_bat->channel[chan] = NULL; | ||
294 | } else { | 292 | } else { |
295 | /* copying properties for supported channels only */ | 293 | /* copying properties for supported channels only */ |
296 | memcpy(properties + sizeof(*(psy->properties)) * index, | 294 | memcpy(properties + sizeof(*(psy->properties)) * index, |
@@ -344,8 +342,10 @@ err_gpio: | |||
344 | gpio_req_fail: | 342 | gpio_req_fail: |
345 | power_supply_unregister(psy); | 343 | power_supply_unregister(psy); |
346 | err_reg_fail: | 344 | err_reg_fail: |
347 | for (chan = 0; ARRAY_SIZE(gab_chan_name); chan++) | 345 | for (chan = 0; chan < ARRAY_SIZE(gab_chan_name); chan++) { |
348 | iio_channel_release(adc_bat->channel[chan]); | 346 | if (adc_bat->channel[chan]) |
347 | iio_channel_release(adc_bat->channel[chan]); | ||
348 | } | ||
349 | second_mem_fail: | 349 | second_mem_fail: |
350 | kfree(psy->properties); | 350 | kfree(psy->properties); |
351 | first_mem_fail: | 351 | first_mem_fail: |
@@ -365,8 +365,10 @@ static int gab_remove(struct platform_device *pdev) | |||
365 | gpio_free(pdata->gpio_charge_finished); | 365 | gpio_free(pdata->gpio_charge_finished); |
366 | } | 366 | } |
367 | 367 | ||
368 | for (chan = 0; ARRAY_SIZE(gab_chan_name); chan++) | 368 | for (chan = 0; chan < ARRAY_SIZE(gab_chan_name); chan++) { |
369 | iio_channel_release(adc_bat->channel[chan]); | 369 | if (adc_bat->channel[chan]) |
370 | iio_channel_release(adc_bat->channel[chan]); | ||
371 | } | ||
370 | 372 | ||
371 | kfree(adc_bat->psy.properties); | 373 | kfree(adc_bat->psy.properties); |
372 | cancel_delayed_work(&adc_bat->bat_work); | 374 | cancel_delayed_work(&adc_bat->bat_work); |