]> bbs.cooldavid.org Git - net-next-2.6.git/commitdiff
USB: xhci: Refactor code to clear port change bits.
authorSarah Sharp <sarah.a.sharp@linux.intel.com>
Wed, 9 Dec 2009 23:59:08 +0000 (15:59 -0800)
committerGreg Kroah-Hartman <gregkh@suse.de>
Tue, 2 Mar 2010 22:53:11 +0000 (14:53 -0800)
Refactor the code to clear the port change bits in the port status
register.  All port status change bits are write one to clear.

Remove a redundant port status read that was supposed to unblock any
posted writes.  We read the port after the write to get the updated status
for debugging, so the port read after that is unnecessary.

Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/usb/host/xhci-hub.c

index eac5b53aa9e77c57fd1ffb09ac1fcac21cee2c9d..5850e8bc30defe79904258ec185ffac2673797d7 100644 (file)
@@ -129,6 +129,36 @@ static u32 xhci_port_state_to_neutral(u32 state)
        return (state & XHCI_PORT_RO) | (state & XHCI_PORT_RWS);
 }
 
+static void xhci_clear_port_change_bit(struct xhci_hcd *xhci, u16 wValue,
+               u16 wIndex, u32 __iomem *addr, u32 port_status)
+{
+       char *port_change_bit;
+       u32 status;
+
+       switch (wValue) {
+       case USB_PORT_FEAT_C_RESET:
+               status = PORT_RC;
+               port_change_bit = "reset";
+               break;
+       case USB_PORT_FEAT_C_CONNECTION:
+               status = PORT_CSC;
+               port_change_bit = "connect";
+               break;
+       case USB_PORT_FEAT_C_OVER_CURRENT:
+               status = PORT_OCC;
+               port_change_bit = "over-current";
+               break;
+       default:
+               /* Should never happen */
+               return;
+       }
+       /* Change bits are all write 1 to clear */
+       xhci_writel(xhci, port_status | status, addr);
+       port_status = xhci_readl(xhci, addr);
+       xhci_dbg(xhci, "clear port %s change, actual port %d status  = 0x%x\n",
+                       port_change_bit, wIndex, port_status);
+}
+
 int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
                u16 wIndex, char *buf, u16 wLength)
 {
@@ -138,7 +168,6 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
        u32 temp, status;
        int retval = 0;
        u32 __iomem *addr;
-       char *port_change_bit;
 
        ports = HCS_MAX_PORTS(xhci->hcs_params1);
 
@@ -229,26 +258,14 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
                temp = xhci_port_state_to_neutral(temp);
                switch (wValue) {
                case USB_PORT_FEAT_C_RESET:
-                       status = PORT_RC;
-                       port_change_bit = "reset";
-                       break;
                case USB_PORT_FEAT_C_CONNECTION:
-                       status = PORT_CSC;
-                       port_change_bit = "connect";
-                       break;
                case USB_PORT_FEAT_C_OVER_CURRENT:
-                       status = PORT_OCC;
-                       port_change_bit = "over-current";
+                       xhci_clear_port_change_bit(xhci, wValue, wIndex,
+                                       addr, temp);
                        break;
                default:
                        goto error;
                }
-               /* Change bits are all write 1 to clear */
-               xhci_writel(xhci, temp | status, addr);
-               temp = xhci_readl(xhci, addr);
-               xhci_dbg(xhci, "clear port %s change, actual port %d status  = 0x%x\n",
-                               port_change_bit, wIndex, temp);
-               temp = xhci_readl(xhci, addr); /* unblock any posted writes */
                break;
        default:
 error: