Skip to content

Commit 7ab0e9d

Browse files
Srinivas-Kandagatlagregkh
authored andcommitted
usb: phy: msm: fix error handling in probe.
commit a38a08d upstream. This driver registers for extcon events as part of its probe, but never unregisters them in case of error in the probe path. There were multiple issues noticed due to this missing error handling. One of them is random crashes if the regulators are not ready yet by the time probe is invoked. Ivan's previous attempt [1] to fix this issue, did not really address all the failure cases like regualtor/get_irq failures. [1] https://lkml.org/lkml/2015/9/7/62 Without this patch the kernel would carsh with log: ... Unable to handle kernel paging request at virtual address 17d78410 pgd = ffffffc001a5c000 [17d78410] *pgd=00000000b6806003, *pud=00000000b6806003, *pmd=0000000000000000 Internal error: Oops: 96000005 [raspberrypi#1] PREEMPT SMP Modules linked in: CPU: 0 PID: 6 Comm: kworker/u8:0 Not tainted 4.4.0+ raspberrypi#48 Hardware name: Qualcomm Technologies, Inc. APQ 8016 SBC (DT) Workqueue: deferwq deferred_probe_work_func task: ffffffc03686e900 ti: ffffffc0368b0000 task.ti: ffffffc0368b0000 PC is at raw_notifier_chain_register+0x1c/0x44 LR is at extcon_register_notifier+0x88/0xc8 pc : [<ffffffc0000da43c>] lr : [<ffffffc000606298>] pstate: 80000085 sp : ffffffc0368b3a70 x29: ffffffc0368b3a70 x28: ffffffc03680c310 x27: ffffffc035518000 x26: ffffffc035518000 x25: ffffffc03bfa20e0 x24: ffffffc035580a18 x23: 0000000000000000 x22: ffffffc035518458 x21: ffffffc0355e9a60 x20: ffffffc035518000 x19: 0000000000000000 x18: 0000000000000028 x17: 0000000000000003 x16: ffffffc0018153c8 x15: 0000000000000001 x14: ffffffc03686f0f8 x13: ffffffc03686f0f8 x12: 0000000000000003 x11: 0000000000000001 x10: 0000000000000001 x9 : ffffffc03686f0f8 x8 : 0000e3872014c1a1 x7 : 0000000000000028 x6 : 0000000000000000 x5 : 0000000000000001 x4 : 0000000000000000 x3 : 00000000354fb170 x2 : 0000000017d78400 x1 : ffffffc0355e9a60 x0 : ffffffc0354fb268 Fixes: 591fc11 ("usb: phy: msm: Use extcon framework for VBUS and ID detection") Signed-off-by: Srinivas Kandagatla <[email protected]> Signed-off-by: Felipe Balbi <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent dde53ae commit 7ab0e9d

File tree

1 file changed

+24
-13
lines changed

1 file changed

+24
-13
lines changed

drivers/usb/phy/phy-msm-usb.c

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1599,6 +1599,8 @@ static int msm_otg_read_dt(struct platform_device *pdev, struct msm_otg *motg)
15991599
&motg->id.nb);
16001600
if (ret < 0) {
16011601
dev_err(&pdev->dev, "register ID notifier failed\n");
1602+
extcon_unregister_notifier(motg->vbus.extcon,
1603+
EXTCON_USB, &motg->vbus.nb);
16021604
return ret;
16031605
}
16041606

@@ -1660,15 +1662,6 @@ static int msm_otg_probe(struct platform_device *pdev)
16601662
if (!motg)
16611663
return -ENOMEM;
16621664

1663-
pdata = dev_get_platdata(&pdev->dev);
1664-
if (!pdata) {
1665-
if (!np)
1666-
return -ENXIO;
1667-
ret = msm_otg_read_dt(pdev, motg);
1668-
if (ret)
1669-
return ret;
1670-
}
1671-
16721665
motg->phy.otg = devm_kzalloc(&pdev->dev, sizeof(struct usb_otg),
16731666
GFP_KERNEL);
16741667
if (!motg->phy.otg)
@@ -1710,15 +1703,26 @@ static int msm_otg_probe(struct platform_device *pdev)
17101703
if (!motg->regs)
17111704
return -ENOMEM;
17121705

1706+
pdata = dev_get_platdata(&pdev->dev);
1707+
if (!pdata) {
1708+
if (!np)
1709+
return -ENXIO;
1710+
ret = msm_otg_read_dt(pdev, motg);
1711+
if (ret)
1712+
return ret;
1713+
}
1714+
17131715
/*
17141716
* NOTE: The PHYs can be multiplexed between the chipidea controller
17151717
* and the dwc3 controller, using a single bit. It is important that
17161718
* the dwc3 driver does not set this bit in an incompatible way.
17171719
*/
17181720
if (motg->phy_number) {
17191721
phy_select = devm_ioremap_nocache(&pdev->dev, USB2_PHY_SEL, 4);
1720-
if (!phy_select)
1721-
return -ENOMEM;
1722+
if (!phy_select) {
1723+
ret = -ENOMEM;
1724+
goto unregister_extcon;
1725+
}
17221726
/* Enable second PHY with the OTG port */
17231727
writel(0x1, phy_select);
17241728
}
@@ -1728,7 +1732,8 @@ static int msm_otg_probe(struct platform_device *pdev)
17281732
motg->irq = platform_get_irq(pdev, 0);
17291733
if (motg->irq < 0) {
17301734
dev_err(&pdev->dev, "platform_get_irq failed\n");
1731-
return motg->irq;
1735+
ret = motg->irq;
1736+
goto unregister_extcon;
17321737
}
17331738

17341739
regs[0].supply = "vddcx";
@@ -1737,7 +1742,7 @@ static int msm_otg_probe(struct platform_device *pdev)
17371742

17381743
ret = devm_regulator_bulk_get(motg->phy.dev, ARRAY_SIZE(regs), regs);
17391744
if (ret)
1740-
return ret;
1745+
goto unregister_extcon;
17411746

17421747
motg->vddcx = regs[0].consumer;
17431748
motg->v3p3 = regs[1].consumer;
@@ -1834,6 +1839,12 @@ static int msm_otg_probe(struct platform_device *pdev)
18341839
clk_disable_unprepare(motg->clk);
18351840
if (!IS_ERR(motg->core_clk))
18361841
clk_disable_unprepare(motg->core_clk);
1842+
unregister_extcon:
1843+
extcon_unregister_notifier(motg->id.extcon,
1844+
EXTCON_USB_HOST, &motg->id.nb);
1845+
extcon_unregister_notifier(motg->vbus.extcon,
1846+
EXTCON_USB, &motg->vbus.nb);
1847+
18371848
return ret;
18381849
}
18391850

0 commit comments

Comments
 (0)