From a38a08dfaaab978dced63aa9cad45f0f62e23a66 Mon Sep 17 00:00:00 2001 From: Srinivas Kandagatla Date: Wed, 13 Jan 2016 09:13:10 +0000 Subject: usb: phy: msm: fix error handling in probe. 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 [#1] PREEMPT SMP Modules linked in: CPU: 0 PID: 6 Comm: kworker/u8:0 Not tainted 4.4.0+ #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 : [] lr : [] 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: 591fc116f330 ("usb: phy: msm: Use extcon framework for VBUS and ID detection") CC: Stable Signed-off-by: Srinivas Kandagatla Signed-off-by: Felipe Balbi --- drivers/usb/phy/phy-msm-usb.c | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/drivers/usb/phy/phy-msm-usb.c b/drivers/usb/phy/phy-msm-usb.c index 0d19a6d61a71..970a30e155cb 100644 --- a/drivers/usb/phy/phy-msm-usb.c +++ b/drivers/usb/phy/phy-msm-usb.c @@ -1599,6 +1599,8 @@ static int msm_otg_read_dt(struct platform_device *pdev, struct msm_otg *motg) &motg->id.nb); if (ret < 0) { dev_err(&pdev->dev, "register ID notifier failed\n"); + extcon_unregister_notifier(motg->vbus.extcon, + EXTCON_USB, &motg->vbus.nb); return ret; } @@ -1660,15 +1662,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) @@ -1710,6 +1703,15 @@ static int msm_otg_probe(struct platform_device *pdev) if (!motg->regs) 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; + } + /* * NOTE: The PHYs can be multiplexed between the chipidea controller * and the dwc3 controller, using a single bit. It is important that @@ -1717,8 +1719,10 @@ static int msm_otg_probe(struct platform_device *pdev) */ if (motg->phy_number) { phy_select = devm_ioremap_nocache(&pdev->dev, USB2_PHY_SEL, 4); - if (!phy_select) - return -ENOMEM; + if (!phy_select) { + ret = -ENOMEM; + goto unregister_extcon; + } /* Enable second PHY with the OTG port */ writel(0x1, phy_select); } @@ -1728,7 +1732,8 @@ static int msm_otg_probe(struct platform_device *pdev) motg->irq = platform_get_irq(pdev, 0); if (motg->irq < 0) { dev_err(&pdev->dev, "platform_get_irq failed\n"); - return motg->irq; + ret = motg->irq; + goto unregister_extcon; } regs[0].supply = "vddcx"; @@ -1737,7 +1742,7 @@ static int msm_otg_probe(struct platform_device *pdev) ret = devm_regulator_bulk_get(motg->phy.dev, ARRAY_SIZE(regs), regs); if (ret) - return ret; + goto unregister_extcon; motg->vddcx = regs[0].consumer; motg->v3p3 = regs[1].consumer; @@ -1834,6 +1839,12 @@ disable_clks: clk_disable_unprepare(motg->clk); if (!IS_ERR(motg->core_clk)) clk_disable_unprepare(motg->core_clk); +unregister_extcon: + extcon_unregister_notifier(motg->id.extcon, + EXTCON_USB_HOST, &motg->id.nb); + extcon_unregister_notifier(motg->vbus.extcon, + EXTCON_USB, &motg->vbus.nb); + return ret; } -- cgit v1.2.3-59-g8ed1b From 63b121e3a3167df9fdb99633fd1c840c841b07b9 Mon Sep 17 00:00:00 2001 From: Li Jun Date: Thu, 21 Jan 2016 15:51:26 +0800 Subject: usb: phy: mxs: declare variable with initialized value Initialize vbus_value to be 0 since it's possible not to assign any value before judgement. Acked-by: Peter Chen Signed-off-by: Felipe Balbi --- drivers/usb/phy/phy-mxs-usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/phy/phy-mxs-usb.c b/drivers/usb/phy/phy-mxs-usb.c index c2936dc48ca7..00bfea01be65 100644 --- a/drivers/usb/phy/phy-mxs-usb.c +++ b/drivers/usb/phy/phy-mxs-usb.c @@ -220,7 +220,7 @@ static int mxs_phy_hw_init(struct mxs_phy *mxs_phy) /* Return true if the vbus is there */ static bool mxs_phy_get_vbus_status(struct mxs_phy *mxs_phy) { - unsigned int vbus_value; + unsigned int vbus_value = 0; if (!mxs_phy->regmap_anatop) return false; -- cgit v1.2.3-59-g8ed1b From 79c5623f1cb85f33403eb9f1e45124e9f56181f8 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Mon, 25 Jan 2016 13:01:29 +0100 Subject: usb: musb: ux500: Fix NULL pointer dereference at system PM The commit 7d32cdef5356 ("usb: musb: fail with error when no DMA controller set"), caused the core platform driver to correctly return an error code when fail probing. Unfurtante it also caused bug for a NULL pointer dereference, during system suspend for the ux500 driver. The reason is a lacking validation of the corresponding ->driver_data pointer, which won't be set when the musb core driver fails to probe (or haven't yet been probed). Fixes: 7d32cdef5356 ("usb: musb: fail with error when no DMA...") Acked-by: Linus Walleij Signed-off-by: Ulf Hansson Signed-off-by: Felipe Balbi --- drivers/usb/musb/ux500.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/usb/musb/ux500.c b/drivers/usb/musb/ux500.c index b2685e75a683..3eaa4ba6867d 100644 --- a/drivers/usb/musb/ux500.c +++ b/drivers/usb/musb/ux500.c @@ -348,7 +348,9 @@ static int ux500_suspend(struct device *dev) struct ux500_glue *glue = dev_get_drvdata(dev); struct musb *musb = glue_to_musb(glue); - usb_phy_set_suspend(musb->xceiv, 1); + if (musb) + usb_phy_set_suspend(musb->xceiv, 1); + clk_disable_unprepare(glue->clk); return 0; @@ -366,7 +368,8 @@ static int ux500_resume(struct device *dev) return ret; } - usb_phy_set_suspend(musb->xceiv, 0); + if (musb) + usb_phy_set_suspend(musb->xceiv, 0); return 0; } -- cgit v1.2.3-59-g8ed1b From 03b32e4c9bd1b52fcf1e4304e7a704aa0315e398 Mon Sep 17 00:00:00 2001 From: John Youn Date: Mon, 11 Jan 2016 16:32:14 -0800 Subject: Revert "usb: dwc2: Move reset into dwc2_get_hwparams()" This reverts commit 263b7fb557f7 ("usb: dwc2: Move reset into dwc2_get_hwparams()") due to regression found on bcm2835 platform. USB ethernet fails, due to being unable to pick up proper parameters when performing a plain reset before reading hw params. Below shows the results of the gnptxfsiz and hptxfsiz with and before and after reverting this (from Stefan Wahren): So here is the probe result before Patch 1 is applied: [ 1.283148] dwc2 20980000.usb: Configuration mismatch. dr_mode forced to host [ 1.313894] dwc2 20980000.usb: gnptxfsiz=00201000 [ 1.314104] dwc2 20980000.usb: hptxfsiz=00000000 [ 1.353908] dwc2 20980000.usb: 256 invalid for host_nperio_tx_fifo_size. Check HW configuration. [ 1.354262] dwc2 20980000.usb: 512 invalid for host_perio_tx_fifo_size. Check HW configuration. [ 1.394249] dwc2 20980000.usb: DWC OTG Controller [ 1.394561] dwc2 20980000.usb: new USB bus registered, assigned bus number 1 [ 1.394917] dwc2 20980000.usb: irq 33, io mem 0x00000000 And here is the probe result after Patch 1 is applied: [ 1.280107] dwc2 20980000.usb: Configuration mismatch. dr_mode forced to host [ 1.353949] dwc2 20980000.usb: gnptxfsiz=01001000 [ 1.354166] dwc2 20980000.usb: hptxfsiz=02002000 [ 1.434301] dwc2 20980000.usb: DWC OTG Controller [ 1.434616] dwc2 20980000.usb: new USB bus registered, assigned bus number 1 [ 1.434973] dwc2 20980000.usb: irq 33, io mem 0x00000000 Tested-by: Heiko Stuebner Tested-by: Douglas Anderson Signed-off-by: John Youn Reported-by: Stefan Wahren Reported-by: Remi Pommarel Tested-by: Stefan Wahren Tested-by: Remi Pommarel Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/core.c | 8 -------- drivers/usb/dwc2/platform.c | 8 +++++++- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c index 39a0fa8a4c0a..1489d315f287 100644 --- a/drivers/usb/dwc2/core.c +++ b/drivers/usb/dwc2/core.c @@ -3278,9 +3278,6 @@ static void dwc2_get_dev_hwparams(struct dwc2_hsotg *hsotg) /** * During device initialization, read various hardware configuration * registers and interpret the contents. - * - * This should be called during driver probe. It will perform a core - * soft reset in order to get the reset values of the parameters. */ int dwc2_get_hwparams(struct dwc2_hsotg *hsotg) { @@ -3288,7 +3285,6 @@ int dwc2_get_hwparams(struct dwc2_hsotg *hsotg) unsigned width; u32 hwcfg1, hwcfg2, hwcfg3, hwcfg4; u32 grxfsiz; - int retval; /* * Attempt to ensure this device is really a DWC_otg Controller. @@ -3308,10 +3304,6 @@ int dwc2_get_hwparams(struct dwc2_hsotg *hsotg) hw->snpsid >> 12 & 0xf, hw->snpsid >> 8 & 0xf, hw->snpsid >> 4 & 0xf, hw->snpsid & 0xf, hw->snpsid); - retval = dwc2_core_reset(hsotg); - if (retval) - return retval; - hwcfg1 = dwc2_readl(hsotg->regs + GHWCFG1); hwcfg2 = dwc2_readl(hsotg->regs + GHWCFG2); hwcfg3 = dwc2_readl(hsotg->regs + GHWCFG3); diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index 510f787434b3..690b9fd98b55 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -530,7 +530,13 @@ static int dwc2_driver_probe(struct platform_device *dev) if (retval) return retval; - /* Reset the controller and detect hardware config values */ + /* + * Reset before dwc2_get_hwparams() then it could get power-on real + * reset value form registers. + */ + dwc2_core_reset_and_force_dr_mode(hsotg); + + /* Detect config values from hardware */ retval = dwc2_get_hwparams(hsotg); if (retval) goto error; -- cgit v1.2.3-59-g8ed1b From 192cb07f7928e8cb09a9851e6c0f7478baa3bc6d Mon Sep 17 00:00:00 2001 From: John Youn Date: Mon, 11 Jan 2016 16:32:28 -0800 Subject: usb: dwc2: Fix probe problem on bcm2835 Fixes an issue found on Raspberry PI platform that prevents probe. Don't skip setting the force mode if it's already set. Fixes: 09c96980dc72 ("usb: dwc2: Add functions to set and clear force mode") Tested-by: Heiko Stuebner Tested-by: Douglas Anderson Signed-off-by: John Youn Reported-by: Stefan Wahren Reported-by: Remi Pommarel Tested-by: Stefan Wahren Tested-by: Remi Pommarel Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/core.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/usb/dwc2/core.c b/drivers/usb/dwc2/core.c index 1489d315f287..e991d55914db 100644 --- a/drivers/usb/dwc2/core.c +++ b/drivers/usb/dwc2/core.c @@ -572,12 +572,6 @@ static bool dwc2_force_mode(struct dwc2_hsotg *hsotg, bool host) set = host ? GUSBCFG_FORCEHOSTMODE : GUSBCFG_FORCEDEVMODE; clear = host ? GUSBCFG_FORCEDEVMODE : GUSBCFG_FORCEHOSTMODE; - /* - * If the force mode bit is already set, don't set it. - */ - if ((gusbcfg & set) && !(gusbcfg & clear)) - return false; - gusbcfg &= ~clear; gusbcfg |= set; dwc2_writel(gusbcfg, hsotg->regs + GUSBCFG); -- cgit v1.2.3-59-g8ed1b From a55f6286575863ebfa5577d4d3bb3b6f1dbd45ec Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Wed, 3 Feb 2016 20:23:01 +0200 Subject: MAINTAINERS: fix my email address As I'm not working for Texas Instruments anymore, balbi@ti.com isn't a valid address. I'll be using balbi@kernel.org at least for the time being. Acked-by: Greg Kroah-Hartman Signed-off-by: Felipe Balbi --- MAINTAINERS | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 30aca4aa5467..e8bde896230e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3445,7 +3445,7 @@ S: Maintained F: drivers/usb/dwc2/ DESIGNWARE USB3 DRD IP DRIVER -M: Felipe Balbi +M: Felipe Balbi L: linux-usb@vger.kernel.org L: linux-omap@vger.kernel.org T: git git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb.git @@ -7370,7 +7370,7 @@ F: drivers/tty/isicom.c F: include/linux/isicom.h MUSB MULTIPOINT HIGH SPEED DUAL-ROLE CONTROLLER -M: Felipe Balbi +M: Felipe Balbi L: linux-usb@vger.kernel.org T: git git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb.git S: Maintained @@ -7939,7 +7939,7 @@ F: drivers/media/platform/omap3isp/ F: drivers/staging/media/omap4iss/ OMAP USB SUPPORT -M: Felipe Balbi +M: Felipe Balbi L: linux-usb@vger.kernel.org L: linux-omap@vger.kernel.org T: git git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb.git @@ -11318,7 +11318,7 @@ F: Documentation/usb/ehci.txt F: drivers/usb/host/ehci* USB GADGET/PERIPHERAL SUBSYSTEM -M: Felipe Balbi +M: Felipe Balbi L: linux-usb@vger.kernel.org W: http://www.linux-usb.org/gadget T: git git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb.git @@ -11394,7 +11394,7 @@ S: Maintained F: drivers/net/usb/pegasus.* USB PHY LAYER -M: Felipe Balbi +M: Felipe Balbi L: linux-usb@vger.kernel.org T: git git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb.git S: Maintained -- cgit v1.2.3-59-g8ed1b From 6a4290cc28be12d72d50644bd4bda1aede37cd41 Mon Sep 17 00:00:00 2001 From: Jianqiang Tang Date: Wed, 20 Jan 2016 14:09:39 +0800 Subject: usb: dwc3: gadget: set the OTG flag in dwc3 gadget driver. This patch is needed in order to pass one test case defined in the OTG Automated Compliance Test specification. Specification location: http://www.usb.org/developers/onthego/otgeh_compliance_plan_1_2.pdf This test case uses PET Tool, and PET Tool is one USB hardware equipment provided by MQP Electronics. Test case id is 6.8.3 B-UUT Bypass Capacitance. We must set this otg flag in order to be able to return OTG descriptor during enumeration, otherwise this test case with failed with below error: "Get OTG descriptor request stalled". Signed-off-by: Jianqiang Tang Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/gadget.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index af023a81a0b0..7d1dd82a95ac 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -2789,6 +2789,7 @@ int dwc3_gadget_init(struct dwc3 *dwc) dwc->gadget.speed = USB_SPEED_UNKNOWN; dwc->gadget.sg_supported = true; dwc->gadget.name = "dwc3-gadget"; + dwc->gadget.is_otg = dwc->dr_mode == USB_DR_MODE_OTG; /* * FIXME We might be setting max_speed to