]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/usb/host/ehci-hub.c
[PATCH] UHCI: fix race in ISO dequeuing
[linux-2.6-omap-h63xx.git] / drivers / usb / host / ehci-hub.c
index 18d3f22703160af0c8ac55fd8f425a5d20e8c369..d03e3cad5ca8a90a2cf7319a2f92891b481a1784 100644 (file)
@@ -30,7 +30,7 @@
 
 #ifdef CONFIG_PM
 
-static int ehci_hub_suspend (struct usb_hcd *hcd)
+static int ehci_bus_suspend (struct usb_hcd *hcd)
 {
        struct ehci_hcd         *ehci = hcd_to_ehci (hcd);
        int                     port;
@@ -59,7 +59,7 @@ static int ehci_hub_suspend (struct usb_hcd *hcd)
 
                if ((t1 & PORT_PE) && !(t1 & PORT_OWNER))
                        t2 |= PORT_SUSPEND;
-               if (hcd->remote_wakeup)
+               if (device_may_wakeup(&hcd->self.root_hub->dev))
                        t2 |= PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E;
                else
                        t2 &= ~(PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E);
@@ -83,7 +83,7 @@ static int ehci_hub_suspend (struct usb_hcd *hcd)
 
 
 /* caller has locked the root hub, and should reset/reinit on error */
-static int ehci_hub_resume (struct usb_hcd *hcd)
+static int ehci_bus_resume (struct usb_hcd *hcd)
 {
        struct ehci_hcd         *ehci = hcd_to_ehci (hcd);
        u32                     temp;
@@ -94,6 +94,13 @@ static int ehci_hub_resume (struct usb_hcd *hcd)
                msleep(5);
        spin_lock_irq (&ehci->lock);
 
+       /* Ideally and we've got a real resume here, and no port's power
+        * was lost.  (For PCI, that means Vaux was maintained.)  But we
+        * could instead be restoring a swsusp snapshot -- so that BIOS was
+        * the last user of the controller, not reset/pm hardware keeping
+        * state we gave to it.
+        */
+
        /* re-init operational registers in case we lost power */
        if (readl (&ehci->regs->intr_enable) == 0) {
                /* at least some APM implementations will try to deliver
@@ -159,8 +166,8 @@ static int ehci_hub_resume (struct usb_hcd *hcd)
 
 #else
 
-#define ehci_hub_suspend       NULL
-#define ehci_hub_resume                NULL
+#define ehci_bus_suspend       NULL
+#define ehci_bus_resume                NULL
 
 #endif /* CONFIG_PM */
 
@@ -352,6 +359,8 @@ static int ehci_hub_control (
                case USB_PORT_FEAT_SUSPEND:
                        if (temp & PORT_RESET)
                                goto error;
+                       if (ehci->no_selective_suspend)
+                               break;
                        if (temp & PORT_SUSPEND) {
                                if ((temp & PORT_PE) == 0)
                                        goto error;
@@ -507,10 +516,12 @@ static int ehci_hub_control (
                temp &= ~PORT_RWC_BITS;
                switch (wValue) {
                case USB_PORT_FEAT_SUSPEND:
+                       if (ehci->no_selective_suspend)
+                               break;
                        if ((temp & PORT_PE) == 0
                                        || (temp & PORT_RESET) != 0)
                                goto error;
-                       if (hcd->remote_wakeup)
+                       if (device_may_wakeup(&hcd->self.root_hub->dev))
                                temp |= PORT_WAKE_BITS;
                        writel (temp | PORT_SUSPEND,
                                &ehci->regs->port_status [wIndex]);