USB: dbgp: EHCI debug controller initialization delays
[linux-2.6.git] / drivers / usb / early / ehci-dbgp.c
index 7deae97fe50f2b93edf1167956f0ed52b56ca979..6198ebded3a4c70e3f95998ceedcfee77e5ad12a 100644 (file)
@@ -9,6 +9,12 @@
 #include <asm/pci-direct.h>
 #include <asm/fixmap.h>
 
+#ifdef DBGP_DEBUG
+# define dbgp_printk printk
+#else
+static inline void dbgp_printk(const char *fmt, ...) { }
+#endif
+
 static struct ehci_caps __iomem *ehci_caps;
 static struct ehci_regs __iomem *ehci_regs;
 static struct ehci_dbg_port __iomem *ehci_debug;
@@ -342,6 +348,7 @@ static int __init ehci_reset_port(int port)
        u32 delay_time, delay;
        int loop;
 
+       dbgp_printk("ehci_reset_port %i\n", port);
        /* Reset the usb debug port */
        portsc = readl(&ehci_regs->port_status[port - 1]);
        portsc &= ~PORT_PE;
@@ -352,14 +359,17 @@ static int __init ehci_reset_port(int port)
        for (delay_time = 0; delay_time < HUB_RESET_TIMEOUT;
             delay_time += delay) {
                dbgp_mdelay(delay);
-
                portsc = readl(&ehci_regs->port_status[port - 1]);
+               if (!(portsc & PORT_RESET))
+                       break;
+       }
                if (portsc & PORT_RESET) {
                        /* force reset to complete */
-                       loop = 2;
+                       loop = 100 * 1000;
                        writel(portsc & ~(PORT_RWC_BITS | PORT_RESET),
                                &ehci_regs->port_status[port - 1]);
                        do {
+                               udelay(1);
                                portsc = readl(&ehci_regs->port_status[port-1]);
                        } while ((portsc & PORT_RESET) && (--loop > 0));
                }
@@ -375,7 +385,6 @@ static int __init ehci_reset_port(int port)
                /* If we've finished resetting, then break out of the loop */
                if (!(portsc & PORT_RESET) && (portsc & PORT_PE))
                        return 0;
-       }
        return -EBUSY;
 }
 
@@ -384,24 +393,18 @@ static int __init ehci_wait_for_port(int port)
        u32 status;
        int ret, reps;
 
-       for (reps = 0; reps < 3; reps++) {
-               dbgp_mdelay(100);
+       for (reps = 0; reps < 300; reps++) {
                status = readl(&ehci_regs->status);
-               if (status & STS_PCD) {
-                       ret = ehci_reset_port(port);
-                       if (ret == 0)
-                               return 0;
-               }
+               if (status & STS_PCD)
+                       break;
+               dbgp_mdelay(1);
        }
+       ret = ehci_reset_port(port);
+       if (ret == 0)
+               return 0;
        return -ENOTCONN;
 }
 
-#ifdef DBGP_DEBUG
-# define dbgp_printk early_printk
-#else
-static inline void dbgp_printk(const char *fmt, ...) { }
-#endif
-
 typedef void (*set_debug_port_t)(int port);
 
 static void __init default_set_debug_port(int port)
@@ -520,7 +523,7 @@ try_next_port:
                return -1;
        }
 
-       loop = 100000;
+       loop = 250 * 1000;
        /* Reset the EHCI controller */
        cmd = readl(&ehci_regs->command);
        cmd |= CMD_RESET;
@@ -540,6 +543,7 @@ try_next_port:
        ctrl |= DBGP_OWNER;
        ctrl &= ~(DBGP_ENABLED | DBGP_INUSE);
        writel(ctrl, &ehci_debug->control);
+       udelay(1);
 
        /* Start the ehci running */
        cmd = readl(&ehci_regs->command);
@@ -554,10 +558,13 @@ try_next_port:
        loop = 10;
        do {
                status = readl(&ehci_regs->status);
-       } while ((status & STS_HALT) && (--loop > 0));
+               if (!(status & STS_HALT))
+                       break;
+               udelay(1);
+       } while (--loop > 0);
 
        if (!loop) {
-               dbgp_printk("ehci can be started\n");
+               dbgp_printk("ehci can not be started\n");
                return -1;
        }
        dbgp_printk("ehci started\n");