aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJon Hunter <jon-hunter@ti.com>2012-01-27 12:17:12 -0600
committerZiyann <jaraidaniel@gmail.com>2014-10-01 12:57:42 +0200
commitd787a2c1804c554a57aa7bb721f9c8db0ebf3588 (patch)
tree21e50136f56141aa7132dc52eb470f577b158197
parentdcd3ebeaa4390fba7bdee133ef9897d26a0a8ab8 (diff)
downloadkernel_samsung_tuna-d787a2c1804c554a57aa7bb721f9c8db0ebf3588.zip
kernel_samsung_tuna-d787a2c1804c554a57aa7bb721f9c8db0ebf3588.tar.gz
kernel_samsung_tuna-d787a2c1804c554a57aa7bb721f9c8db0ebf3588.tar.bz2
OMAP4: USB: Update EHCI TLL errata i640
The workaround for EHCI TLL i640 errata has a critical timing window between clearing the FPR bit in the PORTSC register and cutting the TLL clock. The register writes to clear the FPR bit and cut the TLL clock need to occur in back to back instructions otherwise we could still experience a disconnect as described in the original errata. The ehci_writel function will cause a L2 cache flush and so when compile takes multiple instructions. Instead of using ehci_writel use __raw_readl. Change-Id: Iaacf6987e37a1096b9d1c59fb3e71eb0f1c7aac3 Signed-off-by: Jon Hunter <jon-hunter@ti.com>
-rwxr-xr-xdrivers/usb/host/ehci-omap.c24
1 files changed, 14 insertions, 10 deletions
diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c
index a50ef09..1ce9e51 100755
--- a/drivers/usb/host/ehci-omap.c
+++ b/drivers/usb/host/ehci-omap.c
@@ -157,7 +157,9 @@ static int omap4_ehci_tll_hub_control(
u32 temp, temp1, status;
unsigned long flags;
int retval = 0;
- u32 runstop, temp_reg;
+ u32 runstop, temp_reg, tll_reg;
+
+ tll_reg = (u32)OMAP2_L4_IO_ADDRESS(L3INIT_HSUSBTLL_CLKCTRL);
spin_lock_irqsave(&ehci->lock, flags);
switch (typeReq) {
@@ -222,23 +224,25 @@ static int omap4_ehci_tll_hub_control(
ehci_writel(ehci, (runstop & ~CMD_RUN),
&ehci->regs->command);
(void) ehci_readl(ehci, &ehci->regs->command);
- handshake(ehci, &ehci->regs->status,
+ if (handshake(ehci, &ehci->regs->status,
STS_HALT,
STS_HALT,
- 2000);
+ 2000) != 0)
+ ehci_err(ehci,
+ "port %d would not halt!\n",
+ wIndex);
- temp_reg = omap_readl(L3INIT_HSUSBTLL_CLKCTRL);
+ temp_reg = __raw_readl(tll_reg);
temp_reg &= ~(1 << (wIndex + 8));
/* stop resume signaling */
- temp = ehci_readl(ehci, status_reg);
- ehci_writel(ehci,
- temp & ~(PORT_RWC_BITS | PORT_RESUME),
- status_reg);
+ temp = __raw_readl(status_reg) &
+ ~(PORT_RWC_BITS | PORT_RESUME);
+ __raw_writel(temp, status_reg);
/* Disable the Channel Optional Fclk */
- omap_writel(temp_reg, L3INIT_HSUSBTLL_CLKCTRL);
-
+ __raw_writel(temp_reg, tll_reg);
+ dmb();
retval = handshake(ehci, status_reg,
PORT_RESUME, 0, 2000 /* 2msec */);