diff options
author | Ivan T. Ivanov <ivan.ivanov@linaro.org> | 2015-05-08 12:46:17 +0300 |
---|---|---|
committer | Srinivas Kandagatla <srinivas.kandagatla@linaro.org> | 2015-05-11 15:42:29 +0100 |
commit | dcf51f2d382ae009f9ef6ffd75164513edbe7515 (patch) | |
tree | bda37aee812ffb96929defaff3d000984b7eed32 | |
parent | 5efb4029fa5f0c651172dcb48f0350218a4aae88 (diff) |
usb: phy: msm: Unregister driver interest for VBUS and ID eventstracking-integration-linux-qcomlt-ll-20150619.0tracking-integration-linux-qcomlt-ll-20150616.0tracking-integration-linux-qcomlt-ll-20150611.0tracking-integration-linux-qcomlt-ll-20150610.0tracking-integration-linux-qcomlt-ll-20150601.0
Right now even if driver failed to probe extcon framework will still
deliver VBUS and ID events, which will lead to random exception codes,
like:
# kworker/2:1[621]: undefined instruction: pc=ffffffc036a40148
Code: 00000000 00000000 30303031 2e303030 (636e6970)
Internal error: Oops - undefined instruction: 0 [#1] PREEMPT SMP
Modules linked in:
CPU: 2 PID: 621 Comm: kworker/2:1 Not tainted 4.1.0-rc2+ #1
Hardware name: Qualcomm Technologies, Inc. APQ 8016 SBC (DT)
Workqueue: events_power_efficient usb_extcon_detect_cable
task: ffffffc002756300 ti: ffffffc002724000 task.ti: ffffffc002724000
PC is at 0xffffffc036a40148
LR is at notifier_call_chain+0x4c/0x88
Fix this by removing driver interest for VBUS and ID events when
probe fail or driver remove.
Signed-off-by: Ivan T. Ivanov <ivan.ivanov@linaro.org>
-rw-r--r-- | drivers/usb/phy/phy-msm-usb.c | 29 |
1 files changed, 20 insertions, 9 deletions
diff --git a/drivers/usb/phy/phy-msm-usb.c b/drivers/usb/phy/phy-msm-usb.c index ab9c393dbe52..04f378052f8e 100644 --- a/drivers/usb/phy/phy-msm-usb.c +++ b/drivers/usb/phy/phy-msm-usb.c @@ -1629,15 +1629,6 @@ static int msm_otg_probe(struct platform_device *pdev) if (!motg) return -ENOMEM; - pdata = dev_get_platdata(&pdev->dev); - if (!pdata) { - if (!np) - return -ENXIO; - ret = msm_otg_read_dt(pdev, motg); - if (ret) - return ret; - } - motg->phy.otg = devm_kzalloc(&pdev->dev, sizeof(struct usb_otg), GFP_KERNEL); if (!motg->phy.otg) @@ -1708,6 +1699,15 @@ static int msm_otg_probe(struct platform_device *pdev) if (ret) return ret; + pdata = dev_get_platdata(&pdev->dev); + if (!pdata) { + if (!np) + return -ENXIO; + ret = msm_otg_read_dt(pdev, motg); + if (ret) + return ret; + } + motg->vddcx = regs[0].consumer; motg->v3p3 = regs[1].consumer; motg->v1p8 = regs[2].consumer; @@ -1789,6 +1789,12 @@ disable_vddcx: clk_disable_unprepare(motg->clk); if (!IS_ERR(motg->core_clk)) clk_disable_unprepare(motg->core_clk); + + if (motg->id_cable.edev) + extcon_unregister_interest(&motg->id_cable); + if (motg->vbus_cable.edev) + extcon_unregister_interest(&motg->vbus_cable); + return ret; } @@ -1801,6 +1807,11 @@ static int msm_otg_remove(struct platform_device *pdev) if (phy->otg->host || phy->otg->gadget) return -EBUSY; + if (motg->id_cable.edev) + extcon_unregister_interest(&motg->id_cable); + if (motg->vbus_cable.edev) + extcon_unregister_interest(&motg->vbus_cable); + msm_otg_debugfs_cleanup(); cancel_delayed_work_sync(&motg->chg_work); cancel_work_sync(&motg->sm_work); |