]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/usb/host/ehci-hub.c
Merge branch 'rusty-cpumask-parisc' into parisc
[linux-2.6-omap-h63xx.git] / drivers / usb / host / ehci-hub.c
index 218f9660d7ee06426e68130d0859d74428788e40..97a53a48a3d8e24383e5f14cc2590bc36b0408a9 100644 (file)
@@ -194,6 +194,7 @@ static int ehci_bus_resume (struct usb_hcd *hcd)
        u32                     temp;
        u32                     power_okay;
        int                     i;
+       u8                      resume_needed = 0;
 
        if (time_before (jiffies, ehci->next_statechange))
                msleep(5);
@@ -228,7 +229,9 @@ static int ehci_bus_resume (struct usb_hcd *hcd)
 
        /* Some controller/firmware combinations need a delay during which
         * they set up the port statuses.  See Bugzilla #8190. */
-       mdelay(8);
+       spin_unlock_irq(&ehci->lock);
+       msleep(8);
+       spin_lock_irq(&ehci->lock);
 
        /* manually resume the ports we suspended during bus_suspend() */
        i = HCS_N_PORTS (ehci->hcs_params);
@@ -236,12 +239,21 @@ static int ehci_bus_resume (struct usb_hcd *hcd)
                temp = ehci_readl(ehci, &ehci->regs->port_status [i]);
                temp &= ~(PORT_RWC_BITS | PORT_WAKE_BITS);
                if (test_bit(i, &ehci->bus_suspended) &&
-                               (temp & PORT_SUSPEND))
+                               (temp & PORT_SUSPEND)) {
                        temp |= PORT_RESUME;
+                       resume_needed = 1;
+               }
                ehci_writel(ehci, temp, &ehci->regs->port_status [i]);
        }
+
+       /* msleep for 20ms only if code is trying to resume port */
+       if (resume_needed) {
+               spin_unlock_irq(&ehci->lock);
+               msleep(20);
+               spin_lock_irq(&ehci->lock);
+       }
+
        i = HCS_N_PORTS (ehci->hcs_params);
-       mdelay (20);
        while (i--) {
                temp = ehci_readl(ehci, &ehci->regs->port_status [i]);
                if (test_bit(i, &ehci->bus_suspended) &&
@@ -422,8 +434,15 @@ static int check_reset_complete (
                port_status &= ~PORT_RWC_BITS;
                ehci_writel(ehci, port_status, status_reg);
 
-       } else
+               /* ensure 440EPX ohci controller state is operational */
+               if (ehci->has_amcc_usb23)
+                       set_ohci_hcfs(ehci, 1);
+       } else {
                ehci_dbg (ehci, "port %d high speed\n", index + 1);
+               /* ensure 440EPx ohci controller state is suspended */
+               if (ehci->has_amcc_usb23)
+                       set_ohci_hcfs(ehci, 0);
+       }
 
        return port_status;
 }