diff mbox

[U-Boot,v5,01/15] usb: Fix handover of full-speed devices from ehci to companion

Message ID 1431259827-8109-2-git-send-email-hdegoede@redhat.com
State Accepted
Delegated to: Simon Glass
Headers show

Commit Message

Hans de Goede May 10, 2015, 12:10 p.m. UTC
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 | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

Comments

Marek Vasut May 10, 2015, 4:12 p.m. UTC | #1
On Sunday, May 10, 2015 at 02:10:13 PM, Hans de Goede wrote:
> 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>

Acked-by: Marek Vasut <marex@denx.de>

Best regards,
Marek Vasut
Simon Glass May 11, 2015, 10:36 p.m. UTC | #2
On 10 May 2015 at 10:12, Marek Vasut <marex@denx.de> wrote:
> On Sunday, May 10, 2015 at 02:10:13 PM, Hans de Goede wrote:
>> 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>
>
> Acked-by: Marek Vasut <marex@denx.de>

Applied to u-boot-dm, thanks!
diff mbox

Patch

diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 46d01d4..ce760d0 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -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: