Messages in this thread Patch in this message | | | From | "H. Nikolaus Schaller" <> | Subject | [PATCH v2 2/3] drivers:power:twl4030-charger: don't return after allocating irq | Date | Mon, 2 Nov 2015 12:27:35 +0100 |
| |
It appears that simply returning with error status (especially -EPROBE_DEFER) is very dangerous *after* allocating devm managed interrupts.
See discussion of potential issues: https://lkml.org/lkml/2013/2/22/65
The result is that the boot process hangs if both, phy-twl4030-usb and this twl4030_charger driver are compiled as modules. This has been observed on gta04 and openpandora boards.
So we move the search and check that the twl4030-phy transceiver link is available before we request to set up the interrupts.
Signed-off-by: H. Nikolaus Schaller <hns@goldelico.com> --- drivers/power/twl4030_charger.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-)
diff --git a/drivers/power/twl4030_charger.c b/drivers/power/twl4030_charger.c index 00697e9..05d693d 100644 --- a/drivers/power/twl4030_charger.c +++ b/drivers/power/twl4030_charger.c @@ -1031,23 +1031,6 @@ static int twl4030_bci_probe(struct platform_device *pdev) return ret; } - ret = devm_request_threaded_irq(&pdev->dev, bci->irq_chg, NULL, - twl4030_charger_interrupt, IRQF_ONESHOT, pdev->name, - bci); - if (ret < 0) { - dev_err(&pdev->dev, "could not request irq %d, status %d\n", - bci->irq_chg, ret); - return ret; - } - - ret = devm_request_threaded_irq(&pdev->dev, bci->irq_bci, NULL, - twl4030_bci_interrupt, IRQF_ONESHOT, pdev->name, bci); - if (ret < 0) { - dev_err(&pdev->dev, "could not request irq %d, status %d\n", - bci->irq_bci, ret); - return ret; - } - INIT_WORK(&bci->work, twl4030_bci_usb_work); INIT_DELAYED_WORK(&bci->current_worker, twl4030_current_worker); @@ -1066,6 +1049,23 @@ static int twl4030_bci_probe(struct platform_device *pdev) } } + ret = devm_request_threaded_irq(&pdev->dev, bci->irq_chg, NULL, + twl4030_charger_interrupt, IRQF_ONESHOT, pdev->name, + bci); + if (ret < 0) { + dev_err(&pdev->dev, "could not request irq %d, status %d\n", + bci->irq_chg, ret); + return ret; + } + + ret = devm_request_threaded_irq(&pdev->dev, bci->irq_bci, NULL, + twl4030_bci_interrupt, IRQF_ONESHOT, pdev->name, bci); + if (ret < 0) { + dev_err(&pdev->dev, "could not request irq %d, status %d\n", + bci->irq_bci, ret); + return ret; + } + /* Enable interrupts now. */ reg = ~(u32)(TWL4030_ICHGLOW | TWL4030_ICHGEOC | TWL4030_TBATOR2 | TWL4030_TBATOR1 | TWL4030_BATSTS); -- 2.5.1
| |