diff mbox

usb: dwc2: Fix endless deferral probe

Message ID 1515526134-2148-1-git-send-email-stefan.wahren@i2se.com (mailing list archive)
State New, archived
Headers show

Commit Message

Stefan Wahren Jan. 9, 2018, 7:28 p.m. UTC
The dwc2 USB driver tries to find a generic PHY first and then look
for an old style USB PHY. In case of a valid generic PHY node without
a PHY driver, the PHY layer will return -EPROBE_DEFER forever. So dwc2
will never tries for an USB PHY.

Fix this issue by finding a generic PHY and an old style USB PHY
at once.

Fixes: 6c2dad69163f ("usb: dwc2: Return errors from PHY")
Link: https://marc.info/?l=linux-usb&m=151518314314753&w=2
Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com>
---
 drivers/usb/dwc2/platform.c | 42 ++++++++++++++++++++++++------------------
 1 file changed, 24 insertions(+), 18 deletions(-)

Comments

Arnd Bergmann Jan. 9, 2018, 9:33 p.m. UTC | #1
On Tue, Jan 9, 2018 at 8:28 PM, Stefan Wahren <stefan.wahren@i2se.com> wrote:
> The dwc2 USB driver tries to find a generic PHY first and then look
> for an old style USB PHY. In case of a valid generic PHY node without
> a PHY driver, the PHY layer will return -EPROBE_DEFER forever. So dwc2
> will never tries for an USB PHY.
>
> Fix this issue by finding a generic PHY and an old style USB PHY
> at once.

This would fix only one of the USB controllers (dwc2), but not the others
that are affected. As I wrote in my suggested patch, dwc3 appears to be
affected the same way, and all other host drivers that call usb_add_hcd()
without first setting hcd->phy would suffer from this as well.

If we go down the route of addressing it here in the hcd drivers, we should
at least change all three of those, and hope this doesn't regress in
another way.

       Arnd
Stefan Wahren Jan. 10, 2018, 12:15 p.m. UTC | #2
Hi Arnd,

Am 09.01.2018 um 22:33 schrieb Arnd Bergmann:
> On Tue, Jan 9, 2018 at 8:28 PM, Stefan Wahren <stefan.wahren@i2se.com> wrote:
>> The dwc2 USB driver tries to find a generic PHY first and then look
>> for an old style USB PHY. In case of a valid generic PHY node without
>> a PHY driver, the PHY layer will return -EPROBE_DEFER forever. So dwc2
>> will never tries for an USB PHY.
>>
>> Fix this issue by finding a generic PHY and an old style USB PHY
>> at once.
> This would fix only one of the USB controllers (dwc2), but not the others
> that are affected. As I wrote in my suggested patch, dwc3 appears to be
> affected the same way, and all other host drivers that call usb_add_hcd()
> without first setting hcd->phy would suffer from this as well.
>
> If we go down the route of addressing it here in the hcd drivers, we should
> at least change all three of those, and hope this doesn't regress in
> another way.
>
>         Arnd

i fully unterstand. But we leaving the path of "fixing a critical issue 
on BCM2835" and go to "fixing multiple USB host controller". I do this 
all in my spare time and don't have any of the other USB controller 
available. So before i proceed with any other patch i like so see some 
feedback from John, Greg or Felipe.

After finalizing this patch i think the chance is little that this would 
be applied to 4.15. So i seems to me that we still revert my DT clean up 
patch.

Stefan
diff mbox

Patch

diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c
index 3e26550..5279567 100644
--- a/drivers/usb/dwc2/platform.c
+++ b/drivers/usb/dwc2/platform.c
@@ -225,10 +225,11 @@  static int dwc2_lowlevel_hw_init(struct dwc2_hsotg *hsotg)
 	hsotg->phyif = GUSBCFG_PHYIF16;
 
 	/*
-	 * Attempt to find a generic PHY, then look for an old style
-	 * USB PHY and then fall back to pdata
+	 * Attempt to find a generic PHY or an old style USB PHY at once
+	 * otherwise fall back to pdata
 	 */
 	hsotg->phy = devm_phy_get(hsotg->dev, "usb2-phy");
+	hsotg->uphy = devm_usb_get_phy(hsotg->dev, USB_PHY_TYPE_USB2);
 	if (IS_ERR(hsotg->phy)) {
 		ret = PTR_ERR(hsotg->phy);
 		switch (ret) {
@@ -237,29 +238,34 @@  static int dwc2_lowlevel_hw_init(struct dwc2_hsotg *hsotg)
 			hsotg->phy = NULL;
 			break;
 		case -EPROBE_DEFER:
-			return ret;
+			if (IS_ERR(hsotg->uphy))
+				return ret;
+
+			hsotg->phy = NULL;
+			break;
 		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)) {
-			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);
+	if (IS_ERR(hsotg->uphy)) {
+		ret = PTR_ERR(hsotg->uphy);
+		switch (ret) {
+		case -ENODEV:
+		case -ENXIO:
+			hsotg->uphy = NULL;
+			break;
+		case -EPROBE_DEFER:
+			if (!hsotg->phy)
 				return ret;
-			}
+
+			hsotg->uphy = NULL;
+			break;
+		default:
+			dev_err(hsotg->dev, "error getting usb phy %d\n",
+				ret);
+			return ret;
 		}
 	}