Refactoring port power on/off related code into
a helper function xhci_set_power_on() which can
be reused when enabling test mode.

Signed-off-by: Guoqing Zhang <guoqing.zh...@intel.com>
---
 drivers/usb/host/xhci-hub.c | 64 ++++++++++++++++++++++++++++++---------------
 1 file changed, 43 insertions(+), 21 deletions(-)

diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index d61fcc4..e6d6396 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -528,6 +528,47 @@ static int xhci_get_ports(struct usb_hcd *hcd, __le32 
__iomem ***port_array)
        return max_ports;
 }
 
+static __le32 __iomem *xhci_get_port_io_addr(struct usb_hcd *hcd, int index)
+{
+       __le32 __iomem **port_array;
+
+       xhci_get_ports(hcd, &port_array);
+       return port_array[index];
+}
+
+/*
+ * xhci_set_port_power() must be called with xhci->lock held.
+ * It will release and re-aquire the lock while calling ACPI
+ * method.
+ */
+static void xhci_set_port_power(struct xhci_hcd *xhci, struct usb_hcd *hcd, 
u16 index, bool on)
+{
+       __le32 __iomem *addr;
+       u32 temp;
+       unsigned long flags = 0;
+
+       addr = xhci_get_port_io_addr(hcd, index);
+       temp = readl(addr);
+       if (on) {
+               /* Power on */
+               writel(temp | PORT_POWER, addr);
+               temp = readl(addr);
+               xhci_dbg(xhci, "set port power, actual port %d status  = 
0x%x\n",
+                                               index, temp);
+       } else {
+               /* Power off */
+               writel(temp & ~PORT_POWER, addr);
+       }
+
+       spin_unlock_irqrestore(&xhci->lock, flags);
+       temp = usb_acpi_power_manageable(hcd->self.root_hub,
+                                       index);
+       if (temp)
+               usb_acpi_set_power_state(hcd->self.root_hub,
+                       index, on);
+       spin_lock_irqsave(&xhci->lock, flags);
+}
+
 void xhci_set_link_state(struct xhci_hcd *xhci, __le32 __iomem **port_array,
                                int port_id, u32 link_state)
 {
@@ -1081,18 +1122,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, 
u16 wValue,
                         * However, hub_wq will ignore the roothub events until
                         * the roothub is registered.
                         */
-                       writel(temp | PORT_POWER, port_array[wIndex]);
-
-                       temp = readl(port_array[wIndex]);
-                       xhci_dbg(xhci, "set port power, actual port %d status  
= 0x%x\n", wIndex, temp);
-
-                       spin_unlock_irqrestore(&xhci->lock, flags);
-                       temp = usb_acpi_power_manageable(hcd->self.root_hub,
-                                       wIndex);
-                       if (temp)
-                               usb_acpi_set_power_state(hcd->self.root_hub,
-                                               wIndex, true);
-                       spin_lock_irqsave(&xhci->lock, flags);
+                       xhci_set_port_power(xhci, hcd, wIndex, true);
                        break;
                case USB_PORT_FEAT_RESET:
                        temp = (temp | PORT_RESET);
@@ -1196,15 +1226,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, 
u16 wValue,
                                        port_array[wIndex], temp);
                        break;
                case USB_PORT_FEAT_POWER:
-                       writel(temp & ~PORT_POWER, port_array[wIndex]);
-
-                       spin_unlock_irqrestore(&xhci->lock, flags);
-                       temp = usb_acpi_power_manageable(hcd->self.root_hub,
-                                       wIndex);
-                       if (temp)
-                               usb_acpi_set_power_state(hcd->self.root_hub,
-                                               wIndex, false);
-                       spin_lock_irqsave(&xhci->lock, flags);
+                       xhci_set_port_power(xhci, hcd, wIndex, false);
                        break;
                default:
                        goto error;
-- 
2.5.0

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to