--- zzzz-none-000/linux-2.6.28.10/drivers/usb/host/ehci-hub.c 2009-05-02 18:54:43.000000000 +0000 +++ puma5-6360-529/linux-2.6.28.10/drivers/usb/host/ehci-hub.c 2011-08-02 08:41:15.000000000 +0000 @@ -713,6 +713,26 @@ status |= 1 << USB_PORT_FEAT_C_RESET; ehci->reset_done [wIndex] = 0; +#ifdef CONFIG_FUSIV_VX180 + /* == AVM/WK 20110801 FIX: improved PEC Error prevention == + ** do very short PHY reset during USB reset ** + ** - (works for Brother Printers, too) + */ + { + int val = *((volatile int *)0xb90000dc); + + // Reinit Phy Port + val |= ((wIndex == 0) ? 0x00000010: 0x00000020); + *((volatile int *)0xb90000dc) = val; + + udelay(200); + + val &= ~((wIndex == 0) ? 0x00000010: 0x00000020); + + *((volatile int *)0xb90000dc) = val; + udelay(500); + } +#endif /* force reset to complete */ ehci_writel(ehci, temp & ~(PORT_RWC_BITS | PORT_RESET), status_reg); @@ -727,6 +747,51 @@ goto error; } +#ifdef CONFIG_FUSIV_VX180 + /* == AVM/WK 20110601 improved Workaround for Ikanos VX180 == + * Phy reinit recovers from PEC error + * Will retry USB reset + */ + msleep(5); + { + unsigned temp2 = ehci_readl (ehci, status_reg); + if (temp2 & PORT_PEC) { + int val = *((volatile int *)0xb90000dc); + + temp = ehci_readl (ehci, status_reg); + ehci_err (ehci, "AVM EHCI PEC Recovery for port %d, val %x\n", (wIndex + 1), temp); + + /* Reinit Phy Port */ + val &= ~((wIndex == 0) ? 0x00000002: 0x00000004); + *((volatile int *)0xb90000dc) = val; + msleep(5); + + val |= ((wIndex == 0) ? 0x00000010: 0x00000020); + *((volatile int *)0xb90000dc) = val; + msleep(50); + + val &= ~((wIndex == 0) ? 0x00000010: 0x00000020); + *((volatile int *)0xb90000dc) = val; + msleep(50); + + val |= ((wIndex == 0) ? 0x00000002: 0x00000004); + *((volatile int *)0xb90000dc) = val; + msleep(5); + + ehci_writel(ehci, PORT_PEC|(temp2 & ~(PORT_RWC_BITS)), status_reg); + + /* let's repeat USB reset */ + goto error; + } + /* == AVM/WK 20110601 FIX: Handle spurious disconnects ==*/ + if ((temp2 & (PORT_CSC|PORT_CONNECT)) == (PORT_CSC|PORT_CONNECT)) { + ehci_err (ehci, "AVM EHCI spurious disconnect after reset port %d, val %x\n", (wIndex + 1), temp2); + /* let's repeat USB reset */ + ehci_writel(ehci, PORT_CSC|(temp2 & ~(PORT_RWC_BITS)), status_reg); + goto error; + } + } +#endif /* see what we found out */ temp = check_reset_complete (ehci, wIndex, status_reg, ehci_readl(ehci, status_reg));