usb: Fix handover of full-speed devices from ehci to companion
authorHans de Goede <hdegoede@redhat.com>
Sun, 10 May 2015 12:10:13 +0000 (14:10 +0200)
committerSimon Glass <sjg@chromium.org>
Fri, 15 May 2015 00:49:30 +0000 (18:49 -0600)
When after a reset the port status connection bit is still set and the enable
bit is not then we're dealing with a full-speed device and should hand it over
to the companion controller.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
drivers/usb/host/ehci-hcd.c

index 46d01d40e84a773bfb03de537e2ce639563f88bc..ce760d0cd3056b21ec300e5324678a2aa811d8cd 100644 (file)
@@ -897,11 +897,21 @@ static int ehci_submit_root(struct usb_device *dev, unsigned long pipe,
                                 */
                                ret = handshake(status_reg, EHCI_PS_PR, 0,
                                                2 * 1000);
-                               if (!ret)
-                                       ctrl->portreset |= 1 << port;
-                               else
+                               if (!ret) {
+                                       reg = ehci_readl(status_reg);
+                                       if ((reg & (EHCI_PS_PE | EHCI_PS_CS))
+                                           == EHCI_PS_CS && !ehci_is_TDI()) {
+                                               debug("port %d full speed --> companion\n", port - 1);
+                                               reg &= ~EHCI_PS_CLEAR;
+                                               reg |= EHCI_PS_PO;
+                                               ehci_writel(status_reg, reg);
+                                       } else {
+                                               ctrl->portreset |= 1 << port;
+                                       }
+                               } else {
                                        printf("port(%d) reset error\n",
                                               port - 1);
+                               }
                        }
                        break;
                case USB_PORT_FEAT_TEST: