summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvan T. Ivanov <ivan.ivanov@linaro.org>2015-05-08 12:46:17 +0300
committerSrinivas Kandagatla <srinivas.kandagatla@linaro.org>2015-05-11 15:42:29 +0100
commitdcf51f2d382ae009f9ef6ffd75164513edbe7515 (patch)
treebda37aee812ffb96929defaff3d000984b7eed32
parent5efb4029fa5f0c651172dcb48f0350218a4aae88 (diff)
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.c29
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);