From d0464bcf12af54bafe02dd23ac5bd75d825f9fdd Mon Sep 17 00:00:00 2001 From: John Youn Date: Fri, 13 Nov 2015 17:02:10 +0000 Subject: usb: dwc2: Make PHY optional Fixes commit 09a75e857790 ("usb: dwc2: refactor common low-level hw code to platform.c") The above commit consolidated the low-level phy access into a common location. This change introduced a check from the gadget requiring that a PHY is specified. This requirement never existed on the host side and broke some platforms when it was moved into platform.c. The gadget doesn't require the PHY either so remove the check. Acked-by: Eric Anholt Reported-by: Stefan Wahren Cc: Marek Szyprowski Signed-off-by: John Youn Tested-by: Marek Szyprowski Fixes: 09a75e857790 ("usb: dwc2: refactor common low-level hw code to platform.c") Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/platform.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'drivers/usb/dwc2/platform.c') diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index e61d773cf65e..60b12a4a11c8 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -229,11 +229,6 @@ static int dwc2_lowlevel_hw_init(struct dwc2_hsotg *hsotg) hsotg->phyif = GUSBCFG_PHYIF8; } - if (!hsotg->phy && !hsotg->uphy && !hsotg->plat) { - dev_err(hsotg->dev, "no platform data or transceiver defined\n"); - return -EPROBE_DEFER; - } - /* Clock */ hsotg->clk = devm_clk_get(hsotg->dev, "otg"); if (IS_ERR(hsotg->clk)) { -- cgit v1.2.3 From 6c2dad69163fdb4ea82344dcba360fc00b4adda4 Mon Sep 17 00:00:00 2001 From: Stefan Wahren Date: Fri, 13 Nov 2015 17:02:11 +0000 Subject: usb: dwc2: Return errors from PHY When searching for PHYs, any error was treated as if the PHY did not exist or was not specified. Thus the probe function did not correctly return error conditions such as -EPROBE_DEFER. Fixed so that only a non-existing PHY is ignored and any other error is returned. Acked-by: Eric Anholt Reported-by: Alexander Aring Signed-off-by: John Youn Signed-off-by: Stefan Wahren Tested-by: Marek Szyprowski Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/platform.c | 37 ++++++++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 5 deletions(-) (limited to 'drivers/usb/dwc2/platform.c') diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index 60b12a4a11c8..d28f72e87389 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -212,14 +212,41 @@ static int dwc2_lowlevel_hw_init(struct dwc2_hsotg *hsotg) */ hsotg->phy = devm_phy_get(hsotg->dev, "usb2-phy"); if (IS_ERR(hsotg->phy)) { - hsotg->phy = NULL; + ret = PTR_ERR(hsotg->phy); + switch (ret) { + case -ENODEV: + case -ENOSYS: + hsotg->phy = NULL; + break; + case -EPROBE_DEFER: + return ret; + default: + dev_err(hsotg->dev, "error getting phy %d\n", ret); + return ret; + } + } + + if (!hsotg->phy) { hsotg->uphy = devm_usb_get_phy(hsotg->dev, USB_PHY_TYPE_USB2); - if (IS_ERR(hsotg->uphy)) - hsotg->uphy = NULL; - else - hsotg->plat = dev_get_platdata(hsotg->dev); + if (IS_ERR(hsotg->uphy)) { + ret = PTR_ERR(hsotg->uphy); + switch (ret) { + case -ENODEV: + case -ENXIO: + hsotg->uphy = NULL; + break; + case -EPROBE_DEFER: + return ret; + default: + dev_err(hsotg->dev, "error getting usb phy %d\n", + ret); + return ret; + } + } } + hsotg->plat = dev_get_platdata(hsotg->dev); + if (hsotg->phy) { /* * If using the generic PHY framework, check if the PHY bus -- cgit v1.2.3 From 8aa90cf2a28645c6733f8879c5fe1848c5d510b7 Mon Sep 17 00:00:00 2001 From: Stefan Wahren Date: Fri, 13 Nov 2015 17:02:12 +0000 Subject: usb: dwc2: make otg clk optional Fixes commit 09a75e857790 ("usb: dwc2: refactor common low-level hw code to platform.c") The above commit consolidated the low-level phy access into a common location. This change made the otg clk a requirement and broke some platforms when it was moved into platform.c. So make clk handling optional again. Acked-by: Eric Anholt Signed-off-by: Stefan Wahren Cc: Marek Szyprowski Acked-by: John Youn Tested-by: Marek Szyprowski Fixes: 09a75e857790 ("usb: dwc2: refactor common low-level hw code to platform.c") Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/platform.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'drivers/usb/dwc2/platform.c') diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index d28f72e87389..91e2e6b86c7c 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -125,9 +125,11 @@ static int __dwc2_lowlevel_hw_enable(struct dwc2_hsotg *hsotg) if (ret) return ret; - ret = clk_prepare_enable(hsotg->clk); - if (ret) - return ret; + if (hsotg->clk) { + ret = clk_prepare_enable(hsotg->clk); + if (ret) + return ret; + } if (hsotg->uphy) ret = usb_phy_init(hsotg->uphy); @@ -175,7 +177,8 @@ static int __dwc2_lowlevel_hw_disable(struct dwc2_hsotg *hsotg) if (ret) return ret; - clk_disable_unprepare(hsotg->clk); + if (hsotg->clk) + clk_disable_unprepare(hsotg->clk); ret = regulator_bulk_disable(ARRAY_SIZE(hsotg->supplies), hsotg->supplies); -- cgit v1.2.3 From f74875dc36135ebae82a8e005f4b7f52289d2c40 Mon Sep 17 00:00:00 2001 From: Stefan Wahren Date: Thu, 12 Nov 2015 21:08:34 +0000 Subject: usb: dwc2: fix kernel oops during driver probe This patch make sure that all necessary members of dwc2_hsotg are initialized before the irq handler is requested. So the kernel oops triggered by dwc2_handle_common_intr has been fixed. dwc2 20980000.usb: Configuration mismatch. Forcing host mode dwc2 20980000.usb: no platform data or transceiver defined Unable to handle kernel paging request at virtual address cc860040 pgd = c0004000 [cc860040] *pgd=0b41e811, *pte=00000000, *ppte=00000000 Internal error: Oops: 7 [#1] ARM CPU: 0 PID: 1 Comm: swapper Not tainted 4.3.0-rc3+ #19 Hardware name: BCM2835 task: cb494000 ti: cb4d0000 task.ti: cb4d0000 PC is at dwc2_is_controller_alive+0x18/0x34 LR is at dwc2_handle_common_intr+0x24/0xb60 Acked-by: John Youn Tested-by: Marek Szyprowski Signed-off-by: Stefan Wahren Signed-off-by: Felipe Balbi --- drivers/usb/dwc2/platform.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'drivers/usb/dwc2/platform.c') diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index 91e2e6b86c7c..39c1cbf0e75d 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -367,20 +367,6 @@ static int dwc2_driver_probe(struct platform_device *dev) if (retval) return retval; - irq = platform_get_irq(dev, 0); - if (irq < 0) { - dev_err(&dev->dev, "missing IRQ resource\n"); - return irq; - } - - dev_dbg(hsotg->dev, "registering common handler for irq%d\n", - irq); - retval = devm_request_irq(hsotg->dev, irq, - dwc2_handle_common_intr, IRQF_SHARED, - dev_name(hsotg->dev), hsotg); - if (retval) - return retval; - res = platform_get_resource(dev, IORESOURCE_MEM, 0); hsotg->regs = devm_ioremap_resource(&dev->dev, res); if (IS_ERR(hsotg->regs)) @@ -415,6 +401,20 @@ static int dwc2_driver_probe(struct platform_device *dev) dwc2_set_all_params(hsotg->core_params, -1); + irq = platform_get_irq(dev, 0); + if (irq < 0) { + dev_err(&dev->dev, "missing IRQ resource\n"); + return irq; + } + + dev_dbg(hsotg->dev, "registering common handler for irq%d\n", + irq); + retval = devm_request_irq(hsotg->dev, irq, + dwc2_handle_common_intr, IRQF_SHARED, + dev_name(hsotg->dev), hsotg); + if (retval) + return retval; + retval = dwc2_lowlevel_hw_enable(hsotg); if (retval) return retval; -- cgit v1.2.3