USB: EHCI: improve use of per-port status-change bits
authorAlan Stern <stern@rowland.harvard.edu>
Mon, 18 Mar 2013 16:05:08 +0000 (12:05 -0400)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 18 Mar 2013 23:05:58 +0000 (16:05 -0700)
This patch (as1634) simplifies some of the code associated with the
per-port change bits added in EHCI-1.1, and in particular it fixes a
bug in the logic of ehci_hub_status_data().  Even if the change bit
doesn't indicate anything happened on a particular port, we still have
to notify the core about changes to the suspend or reset status.

Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/host/ehci-hcd.c
drivers/usb/host/ehci-hub.c

index 303b022..fcf8b94 100644 (file)
@@ -758,7 +758,7 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
        /* remote wakeup [4.3.1] */
        if (status & STS_PCD) {
                unsigned        i = HCS_N_PORTS (ehci->hcs_params);
-               u32             ppcd = 0;
+               u32             ppcd = ~0;
 
                /* kick root hub later */
                pcd_status = status;
@@ -775,7 +775,7 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
                        int pstatus;
 
                        /* leverage per-port change bits feature */
-                       if (ehci->has_ppcd && !(ppcd & (1 << i)))
+                       if (!(ppcd & (1 << i)))
                                continue;
                        pstatus = ehci_readl(ehci,
                                         &ehci->regs->port_status[i]);
index 4d3b294..576b735 100644 (file)
@@ -590,7 +590,7 @@ ehci_hub_status_data (struct usb_hcd *hcd, char *buf)
        u32             mask;
        int             ports, i, retval = 1;
        unsigned long   flags;
-       u32             ppcd = 0;
+       u32             ppcd = ~0;
 
        /* init status to no-changes */
        buf [0] = 0;
@@ -628,9 +628,10 @@ ehci_hub_status_data (struct usb_hcd *hcd, char *buf)
 
        for (i = 0; i < ports; i++) {
                /* leverage per-port change bits feature */
-               if (ehci->has_ppcd && !(ppcd & (1 << i)))
-                       continue;
-               temp = ehci_readl(ehci, &ehci->regs->port_status [i]);
+               if (ppcd & (1 << i))
+                       temp = ehci_readl(ehci, &ehci->regs->port_status[i]);
+               else
+                       temp = 0;
 
                /*
                 * Return status information even for ports with OWNER set.