[RFC/PATCH 3/4] disociate chipidea PHY low power suspend control from hostpc

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Signed-off-by: Matthieu CASTET <matthieu.castet@xxxxxxxxxx>
---
 drivers/usb/host/ehci-hcd.c |    4 +-
 drivers/usb/host/ehci-hub.c |  104 ++++++++++++++++++++-----------------------
 drivers/usb/host/ehci.h     |    6 ++-
 3 files changed, 57 insertions(+), 57 deletions(-)

diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 2149583..00425af 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -722,8 +722,10 @@ static int ehci_init(struct usb_hcd *hcd)
 			hird = 0;
 		}
 		temp |= hird << 24;
-		if (ehci_is_TDI(ehci))
+		if (ehci_is_TDI(ehci)) {
 			ehci->has_hostpc = 1;
+			ehci->has_tdi_phy_lpm = 1;
+		}
 	}
 	ehci->command = temp;
 
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c
index 38fe076..b70fca6 100644
--- a/drivers/usb/host/ehci-hub.c
+++ b/drivers/usb/host/ehci-hub.c
@@ -31,6 +31,37 @@
 
 #define	PORT_WAKE_BITS	(PORT_WKOC_E|PORT_WKDISC_E|PORT_WKCONN_E)
 
+static void tdi_phy_lpm_clear(struct ehci_hcd *ehci, int port)
+{
+	if (ehci->has_hostpc) {
+		u32 __iomem	*hostpc_reg;
+		u32		temp;
+
+		hostpc_reg = (u32 __iomem *)((u8 *) ehci->regs
+				+ HOSTPC0 + 4 * port);
+		temp = ehci_readl(ehci, hostpc_reg);
+		ehci_writel(ehci, temp & ~HOSTPC_PHCD, hostpc_reg);
+	}
+}
+
+static void tdi_phy_lpm_set(struct ehci_hcd *ehci, int port)
+{
+	if (ehci->has_hostpc) {
+		u32 __iomem	*hostpc_reg;
+		u32		t3;
+
+		hostpc_reg = (u32 __iomem *)((u8 *) ehci->regs
+				+ HOSTPC0 + 4 * port);
+		t3 = ehci_readl(ehci, hostpc_reg);
+		ehci_writel(ehci, t3 | HOSTPC_PHCD, hostpc_reg);
+		t3 = ehci_readl(ehci, hostpc_reg);
+		ehci_dbg(ehci, "Port %d phy low-power mode %s\n",
+				port, (t3 & HOSTPC_PHCD) ?
+				"succeeded" : "failed");
+	}
+}
+
+
 #ifdef	CONFIG_PM
 
 static int ehci_hub_control(
@@ -146,15 +177,10 @@ static __maybe_unused void ehci_adjust_port_wakeup_flags(struct ehci_hcd *ehci,
 	spin_lock_irqsave(&ehci->lock, flags);
 
 	/* clear phy low-power mode before changing wakeup flags */
-	if (ehci->has_hostpc) {
+	if (ehci->has_tdi_phy_lpm) {
 		port = HCS_N_PORTS(ehci->hcs_params);
-		while (port--) {
-			u32 __iomem	*hostpc_reg;
-
-			hostpc_reg = (u32 __iomem *)((u8 *) ehci->regs
-					+ HOSTPC0 + 4 * port);
-			temp = ehci_readl(ehci, hostpc_reg);
-			ehci_writel(ehci, temp & ~HOSTPC_PHCD, hostpc_reg);
+		while (port--)
+			tdi_phy_lpm_clear(ehci, port);
 		}
 		spin_unlock_irqrestore(&ehci->lock, flags);
 		msleep(5);
@@ -182,16 +208,10 @@ static __maybe_unused void ehci_adjust_port_wakeup_flags(struct ehci_hcd *ehci,
 	}
 
 	/* enter phy low-power mode again */
-	if (ehci->has_hostpc) {
+	if (ehci->has_tdi_phy_lpm) {
 		port = HCS_N_PORTS(ehci->hcs_params);
-		while (port--) {
-			u32 __iomem	*hostpc_reg;
-
-			hostpc_reg = (u32 __iomem *)((u8 *) ehci->regs
-					+ HOSTPC0 + 4 * port);
-			temp = ehci_readl(ehci, hostpc_reg);
-			ehci_writel(ehci, temp | HOSTPC_PHCD, hostpc_reg);
-		}
+		while (port--)
+			tdi_phy_lpm_set(ehci, port);
 	}
 
 	/* Does the root hub have a port wakeup pending? */
@@ -279,25 +299,14 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
 		}
 	}
 
-	if (changed && ehci->has_hostpc) {
+	if (changed && ehci->has_tdi_phy_lpm) {
 		spin_unlock_irq(&ehci->lock);
 		msleep(5);	/* 5 ms for HCD to enter low-power mode */
 		spin_lock_irq(&ehci->lock);
 
 		port = HCS_N_PORTS(ehci->hcs_params);
-		while (port--) {
-			u32 __iomem	*hostpc_reg;
-			u32		t3;
-
-			hostpc_reg = (u32 __iomem *)((u8 *) ehci->regs
-					+ HOSTPC0 + 4 * port);
-			t3 = ehci_readl(ehci, hostpc_reg);
-			ehci_writel(ehci, t3 | HOSTPC_PHCD, hostpc_reg);
-			t3 = ehci_readl(ehci, hostpc_reg);
-			ehci_dbg(ehci, "Port %d phy low-power mode %s\n",
-					port, (t3 & HOSTPC_PHCD) ?
-					"succeeded" : "failed");
-		}
+		while (port--)
+			tdi_phy_lpm_set(ehci, port);
 	}
 
 	/* Apparently some devices need a >= 1-uframe delay here */
@@ -384,17 +393,11 @@ static int ehci_bus_resume (struct usb_hcd *hcd)
 	spin_lock_irq(&ehci->lock);
 
 	/* clear phy low-power mode before resume */
-	if (ehci->bus_suspended && ehci->has_hostpc) {
+	if (ehci->bus_suspended && ehci->has_tdi_phy_lpm) {
 		i = HCS_N_PORTS(ehci->hcs_params);
 		while (i--) {
 			if (test_bit(i, &ehci->bus_suspended)) {
-				u32 __iomem	*hostpc_reg;
-
-				hostpc_reg = (u32 __iomem *)((u8 *) ehci->regs
-						+ HOSTPC0 + 4 * i);
-				temp = ehci_readl(ehci, hostpc_reg);
-				ehci_writel(ehci, temp & ~HOSTPC_PHCD,
-						hostpc_reg);
+				tdi_phy_lpm_clear(ehci, i);
 			}
 		}
 		spin_unlock_irq(&ehci->lock);
@@ -666,7 +669,7 @@ static int ehci_hub_control (
 	int		ports = HCS_N_PORTS (ehci->hcs_params);
 	u32 __iomem	*status_reg = &ehci->regs->port_status[
 				(wIndex & 0xff) - 1];
-	u32 __iomem	*hostpc_reg = NULL;
+	u32 __iomem	*hostpc_reg;
 	u32		temp, temp1, status;
 	unsigned long	flags;
 	int		retval = 0;
@@ -679,9 +682,6 @@ static int ehci_hub_control (
 	 * power, "this is the one", etc.  EHCI spec supports this.
 	 */
 
-	if (ehci->has_hostpc)
-		hostpc_reg = (u32 __iomem *)((u8 *)ehci->regs
-				+ HOSTPC0 + 4 * ((wIndex & 0xff) - 1));
 	spin_lock_irqsave (&ehci->lock, flags);
 	switch (typeReq) {
 	case ClearHubFeature:
@@ -733,10 +733,8 @@ static int ehci_hub_control (
 				goto error;
 
 			/* clear phy low-power mode before resume */
-			if (hostpc_reg) {
-				temp1 = ehci_readl(ehci, hostpc_reg);
-				ehci_writel(ehci, temp1 & ~HOSTPC_PHCD,
-						hostpc_reg);
+			if (ehci->has_tdi_phy_lpm) {
+				tdi_phy_lpm_clear(ehci, wIndex);
 				spin_unlock_irqrestore(&ehci->lock, flags);
 				msleep(5);/* wait to leave low-power mode */
 				spin_lock_irqsave(&ehci->lock, flags);
@@ -907,6 +905,8 @@ static int ehci_hub_control (
 			status |= USB_PORT_STAT_CONNECTION;
 			// status may be from integrated TT
 			if (ehci->has_hostpc) {
+				hostpc_reg = (u32 __iomem *)((u8 *)ehci->regs
+				+ HOSTPC0 + 4 * wIndex);
 				temp1 = ehci_readl(ehci, hostpc_reg);
 				status |= ehci_port_speed(ehci, temp1);
 			} else
@@ -986,17 +986,11 @@ static int ehci_hub_control (
 			temp &= ~PORT_WKCONN_E;
 			temp |= PORT_WKDISC_E | PORT_WKOC_E;
 			ehci_writel(ehci, temp | PORT_SUSPEND, status_reg);
-			if (hostpc_reg) {
+			if (ehci->has_tdi_phy_lpm) {
 				spin_unlock_irqrestore(&ehci->lock, flags);
 				msleep(5);/* 5ms for HCD enter low pwr mode */
 				spin_lock_irqsave(&ehci->lock, flags);
-				temp1 = ehci_readl(ehci, hostpc_reg);
-				ehci_writel(ehci, temp1 | HOSTPC_PHCD,
-					hostpc_reg);
-				temp1 = ehci_readl(ehci, hostpc_reg);
-				ehci_dbg(ehci, "Port%d phy low pwr mode %s\n",
-					wIndex, (temp1 & HOSTPC_PHCD) ?
-					"succeeded" : "failed");
+				tdi_phy_lpm_set(ehci, wIndex);
 			}
 			set_bit(wIndex, &ehci->suspended_ports);
 			break;
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index 2694ed6..a9e288a 100644
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -158,9 +158,13 @@ struct ehci_hcd {			/* one per controller */
 	#define OHCI_HCCTRL_OFFSET      0x4
 	#define OHCI_HCCTRL_LEN         0x4
 	__hc32			*ohci_hcctrl_reg;
-	unsigned		has_hostpc:1;
+	/* ehci extension  */
 	unsigned		has_lpm:1;  /* support link power management */
 	unsigned		has_ppcd:1; /* support per-port change bits */
+	/* extension for TDI/chipidea core */
+	unsigned		has_tdi_phy_lpm:1; /* support PHY low power suspend */
+	unsigned		has_hostpc:1; /* have hostpc register */
+
 	u8			sbrn;		/* packed release number */
 
 	/* irq statistics */
-- 
1.7.10

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


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux