{
        struct ehci_hcd         *ehci = hcd_to_ehci (hcd);
        int                     port;
+       int                     mask;
 
        if (time_before (jiffies, ehci->next_statechange))
                msleep(5);
                ehci->reclaim_ready = 1;
        ehci_work(ehci);
 
-       /* suspend any active/unsuspended ports, maybe allow wakeup */
+       /* Unlike other USB host controller types, EHCI doesn't have
+        * any notion of "global" or bus-wide suspend.  The driver has
+        * to manually suspend all the active unsuspended ports, and
+        * then manually resume them in the bus_resume() routine.
+        */
+       ehci->bus_suspended = 0;
        while (port--) {
                u32 __iomem     *reg = &ehci->regs->port_status [port];
                u32             t1 = readl (reg) & ~PORT_RWC_BITS;
                u32             t2 = t1;
 
-               if ((t1 & PORT_PE) && !(t1 & PORT_OWNER))
+               /* keep track of which ports we suspend */
+               if ((t1 & PORT_PE) && !(t1 & PORT_OWNER) &&
+                               !(t1 & PORT_SUSPEND)) {
                        t2 |= PORT_SUSPEND;
+                       set_bit(port, &ehci->bus_suspended);
+               }
+
+               /* enable remote wakeup on all ports */
                if (device_may_wakeup(&hcd->self.root_hub->dev))
                        t2 |= PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E;
                else
        ehci_halt (ehci);
        hcd->state = HC_STATE_SUSPENDED;
 
+       /* allow remote wakeup */
+       mask = INTR_MASK;
+       if (!device_may_wakeup(&hcd->self.root_hub->dev))
+               mask &= ~STS_PCD;
+       writel(mask, &ehci->regs->intr_enable);
+       readl(&ehci->regs->intr_enable);
+
        ehci->next_statechange = jiffies + msecs_to_jiffies(10);
        spin_unlock_irq (&ehci->lock);
        return 0;
        struct ehci_hcd         *ehci = hcd_to_ehci (hcd);
        u32                     temp;
        int                     i;
-       int                     intr_enable;
 
        if (time_before (jiffies, ehci->next_statechange))
                msleep(5);
         * the last user of the controller, not reset/pm hardware keeping
         * state we gave to it.
         */
+       temp = readl(&ehci->regs->intr_enable);
+       ehci_dbg(ehci, "resume root hub%s\n", temp ? "" : " after power loss");
 
-       /* 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
-                * IRQs right away, so delay them until we're ready.
-                */
-               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);
-       } else
-               intr_enable = 0;
-       ehci_dbg(ehci, "resume root hub%s\n",
-                       intr_enable ? " after power loss" : "");
+       /* at least some APM implementations will try to deliver
+        * IRQs right away, so delay them until we're ready.
+        */
+       writel(0, &ehci->regs->intr_enable);
+
+       /* re-init operational registers */
+       writel(0, &ehci->regs->segment);
+       writel(ehci->periodic_dma, &ehci->regs->frame_list);
+       writel((u32) ehci->async->qh_dma, &ehci->regs->async_next);
 
        /* restore CMD_RUN, framelist size, and irq threshold */
        writel (ehci->command, &ehci->regs->command);
 
-       /* take ports out of suspend */
+       /* manually resume the ports we suspended during bus_suspend() */
        i = HCS_N_PORTS (ehci->hcs_params);
        while (i--) {
                temp = readl (&ehci->regs->port_status [i]);
                temp &= ~(PORT_RWC_BITS
                        | PORT_WKOC_E | PORT_WKDISC_E | PORT_WKCONN_E);
-               if (temp & PORT_SUSPEND) {
+               if (test_bit(i, &ehci->bus_suspended) &&
+                               (temp & PORT_SUSPEND)) {
                        ehci->reset_done [i] = jiffies + msecs_to_jiffies (20);
                        temp |= PORT_RESUME;
                }
        mdelay (20);
        while (i--) {
                temp = readl (&ehci->regs->port_status [i]);
-               if ((temp & PORT_SUSPEND) == 0)
-                       continue;
-               temp &= ~(PORT_RWC_BITS | PORT_RESUME);
-               writel (temp, &ehci->regs->port_status [i]);
-               ehci_vdbg (ehci, "resumed port %d\n", i + 1);
+               if (test_bit(i, &ehci->bus_suspended) &&
+                               (temp & PORT_SUSPEND)) {
+                       temp &= ~(PORT_RWC_BITS | PORT_RESUME);
+                       writel (temp, &ehci->regs->port_status [i]);
+                       ehci_vdbg (ehci, "resumed port %d\n", i + 1);
+               }
        }
        (void) readl (&ehci->regs->command);
 
        hcd->state = HC_STATE_RUNNING;
 
        /* Now we can safely re-enable irqs */
-       if (intr_enable)
-               writel (INTR_MASK, &ehci->regs->intr_enable);
+       writel(INTR_MASK, &ehci->regs->intr_enable);
 
        spin_unlock_irq (&ehci->lock);
        return 0;
 
 static int ehci_pci_resume(struct usb_hcd *hcd)
 {
        struct ehci_hcd         *ehci = hcd_to_ehci(hcd);
-       unsigned                port;
        struct pci_dev          *pdev = to_pci_dev(hcd->self.controller);
-       int                     retval = -EINVAL;
 
        // maybe restore FLADJ
 
        /* Mark hardware accessible again as we are out of D3 state by now */
        set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
 
-       /* If CF is clear, we lost PCI Vaux power and need to restart.  */
-       if (readl(&ehci->regs->configured_flag) != FLAG_CF)
-               goto restart;
-
-       /* If any port is suspended (or owned by the companion),
-        * we know we can/must resume the HC (and mustn't reset it).
-        * We just defer that to the root hub code.
+       /* If CF is still set, we maintained PCI Vaux power.
+        * Just undo the effect of ehci_pci_suspend().
         */
-       for (port = HCS_N_PORTS(ehci->hcs_params); port > 0; ) {
-               u32     status;
-               port--;
-               status = readl(&ehci->regs->port_status [port]);
-               if (!(status & PORT_POWER))
-                       continue;
-               if (status & (PORT_SUSPEND | PORT_RESUME | PORT_OWNER)) {
-                       usb_hcd_resume_root_hub(hcd);
-                       return 0;
-               }
+       if (readl(&ehci->regs->configured_flag) == FLAG_CF) {
+               int     mask = INTR_MASK;
+
+               if (!device_may_wakeup(&hcd->self.root_hub->dev))
+                       mask &= ~STS_PCD;
+               writel(mask, &ehci->regs->intr_enable);
+               readl(&ehci->regs->intr_enable);
+               return 0;
        }
 
-restart:
        ehci_dbg(ehci, "lost power, restarting\n");
        usb_root_hub_lost_power(hcd->self.root_hub);
 
        ehci_work(ehci);
        spin_unlock_irq(&ehci->lock);
 
-       /* restart; khubd will disconnect devices */
-       retval = ehci_run(hcd);
-
        /* here we "know" root ports should always stay powered */
        ehci_port_power(ehci, 1);
 
-       return retval;
+       writel(ehci->command, &ehci->regs->command);
+       writel(FLAG_CF, &ehci->regs->configured_flag);
+       readl(&ehci->regs->command);    /* unblock posted writes */
+
+       hcd->state = HC_STATE_SUSPENDED;
+       return 0;
 }
 #endif