diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2010-06-24 10:34:27 +0200 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2010-06-24 11:42:20 +0200 |
commit | 2f64aa66abc67be70b0e963bdfd70a2b72f4a942 (patch) | |
tree | 2512c4ba057b0d412e60fb2f70f5be9eaf3bbc23 /drivers/usb | |
parent | 0b863c83d0908a1524eed1e55f0efc3397badd2e (diff) | |
download | barebox-2f64aa66abc67be70b0e963bdfd70a2b72f4a942.tar.gz barebox-2f64aa66abc67be70b0e963bdfd70a2b72f4a942.tar.xz |
ehci: Force a ehci_halt before trying to reset
As observed on OMAP some controllers do not like being
resetted when running.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/usb_ehci_core.c | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/drivers/usb/usb_ehci_core.c b/drivers/usb/usb_ehci_core.c index e70e8718a7..fe988c3b87 100644 --- a/drivers/usb/usb_ehci_core.c +++ b/drivers/usb/usb_ehci_core.c @@ -770,12 +770,33 @@ unknown: return -1; } +/* force HC to halt state from unknown (EHCI spec section 2.3) */ +static int ehci_halt(struct ehci_priv *ehci) +{ + u32 temp = ehci_readl(&ehci->hcor->or_usbsts); + + /* disable any irqs left enabled by previous code */ + ehci_writel(&ehci->hcor->or_usbintr, 0); + + if (temp & STS_HALT) + return 0; + + temp = ehci_readl(&ehci->hcor->or_usbcmd); + temp &= ~CMD_RUN; + ehci_writel(&ehci->hcor->or_usbcmd, temp); + + return handshake(&ehci->hcor->or_usbsts, + STS_HALT, STS_HALT, 16 * 125); +} + static int ehci_init(struct usb_host *host) { struct ehci_priv *ehci = to_ehci(host); uint32_t reg; uint32_t cmd; + ehci_halt(ehci); + /* EHCI spec section 4.1 */ if (ehci_reset(ehci) != 0) return -1; |