]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/usb/host/ehci-hub.c
Merge branch 'devel' of master.kernel.org:/home/rmk/linux-2.6-arm
[linux-2.6-omap-h63xx.git] / drivers / usb / host / ehci-hub.c
index 88cb4ada686ed6df1637b1a775b1bf3975e28271..b2ee13c58517cc9182fccc533c7c5ca4aff0c77a 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2001-2004 by David Brownell
- * 
+ *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the
  * Free Software Foundation; either version 2 of the License, or (at your
@@ -48,7 +48,7 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
        }
        ehci->command = readl (&ehci->regs->command);
        if (ehci->reclaim)
-               ehci->reclaim_ready = 1;
+               end_unlink_async (ehci, NULL);
        ehci_work(ehci, NULL);
 
        /* suspend any active/unsuspended ports, maybe allow wakeup */
@@ -59,7 +59,7 @@ static int ehci_bus_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);
@@ -94,12 +94,19 @@ static int ehci_bus_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
+               /* at least some APM implementations will try to deliver
                 * IRQs right away, so delay them until we're ready.
-                */
-               intr_enable = 1;
+                */
+               intr_enable = 1;
                writel (0, &ehci->regs->segment);
                writel (ehci->periodic_dma, &ehci->regs->frame_list);
                writel ((u32)ehci->async->qh_dma, &ehci->regs->async_next);
@@ -225,7 +232,7 @@ ehci_hub_status_data (struct usb_hcd *hcd, char *buf)
                buf [1] = 0;
                retval++;
        }
-       
+
        /* no hub change reports (bit 0) for now (power, ...) */
 
        /* port N changes (bit N)? */
@@ -297,7 +304,7 @@ ehci_hub_descriptor (
 
 /*-------------------------------------------------------------------------*/
 
-#define        PORT_WAKE_BITS  (PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E)
+#define        PORT_WAKE_BITS  (PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E)
 
 static int ehci_hub_control (
        struct usb_hcd  *hcd,
@@ -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]);