diff options
author | Liam Breck <liam@networkimprov.net> | 2017-01-18 12:26:50 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-05-14 08:00:14 -0400 |
commit | 63e1acc84d28d73107e72482e33dcca152bb5ea4 (patch) | |
tree | 2b295df86fc85d8af62ccf4527f63a4d07d08e46 /drivers/power | |
parent | 20e448f2251c0a78421889267b3709758c544ff2 (diff) |
power: supply: bq24190_charger: Install irq_handler_thread() at end of probe()
commit d62acc5ef0621463446091ebd7a345e06e9ab80c upstream.
The device specific data is not fully initialized on
request_threaded_irq(). This may cause a crash when the IRQ handler
tries to reference them.
Fix the issue by installing IRQ handler at the end of the probe.
Fixes: d7bf353fd0aa3 ("bq24190_charger: Add support for TI BQ24190 Battery Charger")
Signed-off-by: Liam Breck <kernel@networkimprov.net>
Acked-by: Mark Greer <mgreer@animalcreek.com>
Acked-by: Tony Lindgren <tony@atomide.com>
Signed-off-by: Sebastian Reichel <sre@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/power')
-rw-r--r-- | drivers/power/supply/bq24190_charger.c | 31 |
1 files changed, 16 insertions, 15 deletions
diff --git a/drivers/power/supply/bq24190_charger.c b/drivers/power/supply/bq24190_charger.c index 31090cef5a7f..d0afafd7b1cb 100644 --- a/drivers/power/supply/bq24190_charger.c +++ b/drivers/power/supply/bq24190_charger.c | |||
@@ -1392,22 +1392,13 @@ static int bq24190_probe(struct i2c_client *client, | |||
1392 | return -EINVAL; | 1392 | return -EINVAL; |
1393 | } | 1393 | } |
1394 | 1394 | ||
1395 | ret = devm_request_threaded_irq(dev, bdi->irq, NULL, | ||
1396 | bq24190_irq_handler_thread, | ||
1397 | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, | ||
1398 | "bq24190-charger", bdi); | ||
1399 | if (ret < 0) { | ||
1400 | dev_err(dev, "Can't set up irq handler\n"); | ||
1401 | goto out1; | ||
1402 | } | ||
1403 | |||
1404 | pm_runtime_enable(dev); | 1395 | pm_runtime_enable(dev); |
1405 | pm_runtime_resume(dev); | 1396 | pm_runtime_resume(dev); |
1406 | 1397 | ||
1407 | ret = bq24190_hw_init(bdi); | 1398 | ret = bq24190_hw_init(bdi); |
1408 | if (ret < 0) { | 1399 | if (ret < 0) { |
1409 | dev_err(dev, "Hardware init failed\n"); | 1400 | dev_err(dev, "Hardware init failed\n"); |
1410 | goto out2; | 1401 | goto out1; |
1411 | } | 1402 | } |
1412 | 1403 | ||
1413 | charger_cfg.drv_data = bdi; | 1404 | charger_cfg.drv_data = bdi; |
@@ -1418,7 +1409,7 @@ static int bq24190_probe(struct i2c_client *client, | |||
1418 | if (IS_ERR(bdi->charger)) { | 1409 | if (IS_ERR(bdi->charger)) { |
1419 | dev_err(dev, "Can't register charger\n"); | 1410 | dev_err(dev, "Can't register charger\n"); |
1420 | ret = PTR_ERR(bdi->charger); | 1411 | ret = PTR_ERR(bdi->charger); |
1421 | goto out2; | 1412 | goto out1; |
1422 | } | 1413 | } |
1423 | 1414 | ||
1424 | battery_cfg.drv_data = bdi; | 1415 | battery_cfg.drv_data = bdi; |
@@ -1427,24 +1418,34 @@ static int bq24190_probe(struct i2c_client *client, | |||
1427 | if (IS_ERR(bdi->battery)) { | 1418 | if (IS_ERR(bdi->battery)) { |
1428 | dev_err(dev, "Can't register battery\n"); | 1419 | dev_err(dev, "Can't register battery\n"); |
1429 | ret = PTR_ERR(bdi->battery); | 1420 | ret = PTR_ERR(bdi->battery); |
1430 | goto out3; | 1421 | goto out2; |
1431 | } | 1422 | } |
1432 | 1423 | ||
1433 | ret = bq24190_sysfs_create_group(bdi); | 1424 | ret = bq24190_sysfs_create_group(bdi); |
1434 | if (ret) { | 1425 | if (ret) { |
1435 | dev_err(dev, "Can't create sysfs entries\n"); | 1426 | dev_err(dev, "Can't create sysfs entries\n"); |
1427 | goto out3; | ||
1428 | } | ||
1429 | |||
1430 | ret = devm_request_threaded_irq(dev, bdi->irq, NULL, | ||
1431 | bq24190_irq_handler_thread, | ||
1432 | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, | ||
1433 | "bq24190-charger", bdi); | ||
1434 | if (ret < 0) { | ||
1435 | dev_err(dev, "Can't set up irq handler\n"); | ||
1436 | goto out4; | 1436 | goto out4; |
1437 | } | 1437 | } |
1438 | 1438 | ||
1439 | return 0; | 1439 | return 0; |
1440 | 1440 | ||
1441 | out4: | 1441 | out4: |
1442 | power_supply_unregister(bdi->battery); | 1442 | bq24190_sysfs_remove_group(bdi); |
1443 | out3: | 1443 | out3: |
1444 | power_supply_unregister(bdi->charger); | 1444 | power_supply_unregister(bdi->battery); |
1445 | out2: | 1445 | out2: |
1446 | pm_runtime_disable(dev); | 1446 | power_supply_unregister(bdi->charger); |
1447 | out1: | 1447 | out1: |
1448 | pm_runtime_disable(dev); | ||
1448 | if (bdi->gpio_int) | 1449 | if (bdi->gpio_int) |
1449 | gpio_free(bdi->gpio_int); | 1450 | gpio_free(bdi->gpio_int); |
1450 | 1451 | ||