]> git.proxmox.com Git - mirror_ubuntu-focal-kernel.git/blobdiff - drivers/usb/host/ehci-hub.c
usbcore: refine warm reset logic
[mirror_ubuntu-focal-kernel.git] / drivers / usb / host / ehci-hub.c
index e051b30c1847804f6b94e188521a865e036108ea..77bbb2357e478a5e021118076bbe2a7f84811af4 100644 (file)
@@ -236,10 +236,8 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
        }
 
        /* stop schedules, clean any completed work */
-       if (HC_IS_RUNNING(hcd->state)) {
+       if (ehci->rh_state == EHCI_RH_RUNNING)
                ehci_quiesce (ehci);
-               hcd->state = HC_STATE_QUIESCING;
-       }
        ehci->command = ehci_readl(ehci, &ehci->regs->command);
        ehci_work(ehci);
 
@@ -313,7 +311,7 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
 
        /* turn off now-idle HC */
        ehci_halt (ehci);
-       hcd->state = HC_STATE_SUSPENDED;
+       ehci->rh_state = EHCI_RH_SUSPENDED;
 
        if (ehci->reclaim)
                end_unlink_async(ehci);
@@ -343,7 +341,7 @@ static int ehci_bus_resume (struct usb_hcd *hcd)
        u32                     temp;
        u32                     power_okay;
        int                     i;
-       u8                      resume_needed = 0;
+       unsigned long           resume_needed = 0;
 
        if (time_before (jiffies, ehci->next_statechange))
                msleep(5);
@@ -382,6 +380,7 @@ static int ehci_bus_resume (struct usb_hcd *hcd)
 
        /* restore CMD_RUN, framelist size, and irq threshold */
        ehci_writel(ehci, ehci->command, &ehci->regs->command);
+       ehci->rh_state = EHCI_RH_RUNNING;
 
        /* Some controller/firmware combinations need a delay during which
         * they set up the port statuses.  See Bugzilla #8190. */
@@ -416,7 +415,7 @@ static int ehci_bus_resume (struct usb_hcd *hcd)
                if (test_bit(i, &ehci->bus_suspended) &&
                                (temp & PORT_SUSPEND)) {
                        temp |= PORT_RESUME;
-                       resume_needed = 1;
+                       set_bit(i, &resume_needed);
                }
                ehci_writel(ehci, temp, &ehci->regs->port_status [i]);
        }
@@ -431,8 +430,7 @@ static int ehci_bus_resume (struct usb_hcd *hcd)
        i = HCS_N_PORTS (ehci->hcs_params);
        while (i--) {
                temp = ehci_readl(ehci, &ehci->regs->port_status [i]);
-               if (test_bit(i, &ehci->bus_suspended) &&
-                               (temp & PORT_SUSPEND)) {
+               if (test_bit(i, &resume_needed)) {
                        temp &= ~(PORT_RWC_BITS | PORT_RESUME);
                        ehci_writel(ehci, temp, &ehci->regs->port_status [i]);
                        ehci_vdbg (ehci, "resumed port %d\n", i + 1);
@@ -452,7 +450,6 @@ static int ehci_bus_resume (struct usb_hcd *hcd)
        }
 
        ehci->next_statechange = jiffies + msecs_to_jiffies(5);
-       hcd->state = HC_STATE_RUNNING;
 
        /* Now we can safely re-enable irqs */
        ehci_writel(ehci, INTR_MASK, &ehci->regs->intr_enable);
@@ -564,7 +561,7 @@ ehci_hub_status_data (struct usb_hcd *hcd, char *buf)
        u32             ppcd = 0;
 
        /* if !USB_SUSPEND, root hub timers won't get shut down ... */
-       if (!HC_IS_RUNNING(hcd->state))
+       if (ehci->rh_state != EHCI_RH_RUNNING)
                return 0;
 
        /* init status to no-changes */