]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - drivers/usb/host/ehci-hcd.c
Merge branch 'master' into csb1725
[mv-sheeva.git] / drivers / usb / host / ehci-hcd.c
index 34a928d3b7d2f69ddf671330cc9bbb60dbf5405c..e9062806d4a24898286240f139a2f28dadd8522c 100644 (file)
@@ -194,6 +194,17 @@ static int handshake (struct ehci_hcd *ehci, void __iomem *ptr,
        return -ETIMEDOUT;
 }
 
+/* check TDI/ARC silicon is in host mode */
+static int tdi_in_host_mode (struct ehci_hcd *ehci)
+{
+       u32 __iomem     *reg_ptr;
+       u32             tmp;
+
+       reg_ptr = (u32 __iomem *)(((u8 __iomem *)ehci->regs) + USBMODE);
+       tmp = ehci_readl(ehci, reg_ptr);
+       return (tmp & 3) == USBMODE_CM_HC;
+}
+
 /* force HC to halt state from unknown (EHCI spec section 2.3) */
 static int ehci_halt (struct ehci_hcd *ehci)
 {
@@ -202,6 +213,10 @@ static int ehci_halt (struct ehci_hcd *ehci)
        /* disable any irqs left enabled by previous code */
        ehci_writel(ehci, 0, &ehci->regs->intr_enable);
 
+       if (ehci_is_TDI(ehci) && tdi_in_host_mode(ehci) == 0) {
+               return 0;
+       }
+
        if ((temp & STS_HALT) != 0)
                return 0;
 
@@ -1048,10 +1063,11 @@ rescan:
                                tmp && tmp != qh;
                                tmp = tmp->qh_next.qh)
                        continue;
-               /* periodic qh self-unlinks on empty */
-               if (!tmp)
-                       goto nogood;
-               unlink_async (ehci, qh);
+               /* periodic qh self-unlinks on empty, and a COMPLETING qh
+                * may already be unlinked.
+                */
+               if (tmp)
+                       unlink_async(ehci, qh);
                /* FALL THROUGH */
        case QH_STATE_UNLINK:           /* wait for hw to finish? */
        case QH_STATE_UNLINK_WAIT:
@@ -1068,7 +1084,6 @@ idle_timeout:
                }
                /* else FALL THROUGH */
        default:
-nogood:
                /* caller was supposed to have unlinked any requests;
                 * that's not our job.  just leak this memory.
                 */
@@ -1080,7 +1095,6 @@ nogood:
        ep->hcpriv = NULL;
 done:
        spin_unlock_irqrestore (&ehci->lock, flags);
-       return;
 }
 
 static void
@@ -1197,6 +1211,11 @@ MODULE_LICENSE ("GPL");
 #define        PLATFORM_DRIVER         ehci_atmel_driver
 #endif
 
+#ifdef CONFIG_USB_OCTEON_EHCI
+#include "ehci-octeon.c"
+#define PLATFORM_DRIVER                ehci_octeon_driver
+#endif
+
 #if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) && \
     !defined(PS3_SYSTEM_BUS_DRIVER) && !defined(OF_PLATFORM_DRIVER) && \
     !defined(XILINX_OF_PLATFORM_DRIVER)