aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorTuomas Tynkkynen <ttynkkynen@nvidia.com>2013-08-12 09:06:49 -0400
committerFelipe Balbi <balbi@ti.com>2013-08-12 14:29:46 -0400
commit2cdcec4fedd6a5ee77bd551e6be7505f2230cd43 (patch)
treeaad4d77dbfcfd247ee4f6926904895fdec13e35c /drivers/usb
parent23381db7cedc26f87a37746ccf7c658d977e467e (diff)
usb: host: add has_tdi_phy_lpm capability bit
The has_hostpc capability bit indicates that the host controller has the HOSTPC register extensions, but at the same time enables clock disabling power saving features with the PHY Low Power Clock Disable (PHCD) bit. However, some host controllers have the HOSTPC extensions but don't support the low-power feature, so the PHCD bit must not be set on those controllers. Add a separate capability bit for the low-power feature instead, and change all existing users of has_hostpc to use this new capability bit. The idea for this commit is taken from an old 2012 commit that never got merged ("disociate chipidea PHY low power suspend control from hostpc") Inspired-by: Matthieu CASTET <matthieu.castet@parrot.com> Signed-off-by: Tuomas Tynkkynen <ttynkkynen@nvidia.com> Acked-by: Alan Stern <stern@rowland.harvard.edu> Tested-by: Stephen Warren <swarren@nvidia.com> Reviewed-by: Stephen Warren <swarren@nvidia.com> Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/chipidea/host.c1
-rw-r--r--drivers/usb/host/ehci-hub.c14
-rw-r--r--drivers/usb/host/ehci.h1
3 files changed, 9 insertions, 7 deletions
diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c
index 40d0fda4f66c..9b3aaf132bc3 100644
--- a/drivers/usb/chipidea/host.c
+++ b/drivers/usb/chipidea/host.c
@@ -63,6 +63,7 @@ static int host_start(struct ci_hdrc *ci)
63 ehci = hcd_to_ehci(hcd); 63 ehci = hcd_to_ehci(hcd);
64 ehci->caps = ci->hw_bank.cap; 64 ehci->caps = ci->hw_bank.cap;
65 ehci->has_hostpc = ci->hw_bank.lpm; 65 ehci->has_hostpc = ci->hw_bank.lpm;
66 ehci->has_tdi_phy_lpm = ci->hw_bank.lpm;
66 67
67 ret = usb_add_hcd(hcd, 0, 0); 68 ret = usb_add_hcd(hcd, 0, 0);
68 if (ret) 69 if (ret)
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c
index 6dce37555c4f..6280bd269e12 100644
--- a/drivers/usb/host/ehci-hub.c
+++ b/drivers/usb/host/ehci-hub.c
@@ -183,7 +183,7 @@ static void ehci_adjust_port_wakeup_flags(struct ehci_hcd *ehci,
183 spin_lock_irq(&ehci->lock); 183 spin_lock_irq(&ehci->lock);
184 184
185 /* clear phy low-power mode before changing wakeup flags */ 185 /* clear phy low-power mode before changing wakeup flags */
186 if (ehci->has_hostpc) { 186 if (ehci->has_tdi_phy_lpm) {
187 port = HCS_N_PORTS(ehci->hcs_params); 187 port = HCS_N_PORTS(ehci->hcs_params);
188 while (port--) { 188 while (port--) {
189 u32 __iomem *hostpc_reg = &ehci->regs->hostpc[port]; 189 u32 __iomem *hostpc_reg = &ehci->regs->hostpc[port];
@@ -217,7 +217,7 @@ static void ehci_adjust_port_wakeup_flags(struct ehci_hcd *ehci,
217 } 217 }
218 218
219 /* enter phy low-power mode again */ 219 /* enter phy low-power mode again */
220 if (ehci->has_hostpc) { 220 if (ehci->has_tdi_phy_lpm) {
221 port = HCS_N_PORTS(ehci->hcs_params); 221 port = HCS_N_PORTS(ehci->hcs_params);
222 while (port--) { 222 while (port--) {
223 u32 __iomem *hostpc_reg = &ehci->regs->hostpc[port]; 223 u32 __iomem *hostpc_reg = &ehci->regs->hostpc[port];
@@ -309,7 +309,7 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
309 } 309 }
310 } 310 }
311 311
312 if (changed && ehci->has_hostpc) { 312 if (changed && ehci->has_tdi_phy_lpm) {
313 spin_unlock_irq(&ehci->lock); 313 spin_unlock_irq(&ehci->lock);
314 msleep(5); /* 5 ms for HCD to enter low-power mode */ 314 msleep(5); /* 5 ms for HCD to enter low-power mode */
315 spin_lock_irq(&ehci->lock); 315 spin_lock_irq(&ehci->lock);
@@ -435,7 +435,7 @@ static int ehci_bus_resume (struct usb_hcd *hcd)
435 goto shutdown; 435 goto shutdown;
436 436
437 /* clear phy low-power mode before resume */ 437 /* clear phy low-power mode before resume */
438 if (ehci->bus_suspended && ehci->has_hostpc) { 438 if (ehci->bus_suspended && ehci->has_tdi_phy_lpm) {
439 i = HCS_N_PORTS(ehci->hcs_params); 439 i = HCS_N_PORTS(ehci->hcs_params);
440 while (i--) { 440 while (i--) {
441 if (test_bit(i, &ehci->bus_suspended)) { 441 if (test_bit(i, &ehci->bus_suspended)) {
@@ -788,7 +788,7 @@ static int ehci_hub_control (
788 goto error; 788 goto error;
789 789
790 /* clear phy low-power mode before resume */ 790 /* clear phy low-power mode before resume */
791 if (ehci->has_hostpc) { 791 if (ehci->has_tdi_phy_lpm) {
792 temp1 = ehci_readl(ehci, hostpc_reg); 792 temp1 = ehci_readl(ehci, hostpc_reg);
793 ehci_writel(ehci, temp1 & ~HOSTPC_PHCD, 793 ehci_writel(ehci, temp1 & ~HOSTPC_PHCD,
794 hostpc_reg); 794 hostpc_reg);
@@ -1032,12 +1032,12 @@ static int ehci_hub_control (
1032 1032
1033 /* After above check the port must be connected. 1033 /* After above check the port must be connected.
1034 * Set appropriate bit thus could put phy into low power 1034 * Set appropriate bit thus could put phy into low power
1035 * mode if we have hostpc feature 1035 * mode if we have tdi_phy_lpm feature
1036 */ 1036 */
1037 temp &= ~PORT_WKCONN_E; 1037 temp &= ~PORT_WKCONN_E;
1038 temp |= PORT_WKDISC_E | PORT_WKOC_E; 1038 temp |= PORT_WKDISC_E | PORT_WKOC_E;
1039 ehci_writel(ehci, temp | PORT_SUSPEND, status_reg); 1039 ehci_writel(ehci, temp | PORT_SUSPEND, status_reg);
1040 if (ehci->has_hostpc) { 1040 if (ehci->has_tdi_phy_lpm) {
1041 spin_unlock_irqrestore(&ehci->lock, flags); 1041 spin_unlock_irqrestore(&ehci->lock, flags);
1042 msleep(5);/* 5ms for HCD enter low pwr mode */ 1042 msleep(5);/* 5ms for HCD enter low pwr mode */
1043 spin_lock_irqsave(&ehci->lock, flags); 1043 spin_lock_irqsave(&ehci->lock, flags);
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index 64f9a08e959c..d034d94a7fea 100644
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -210,6 +210,7 @@ struct ehci_hcd { /* one per controller */
210 #define OHCI_HCCTRL_LEN 0x4 210 #define OHCI_HCCTRL_LEN 0x4
211 __hc32 *ohci_hcctrl_reg; 211 __hc32 *ohci_hcctrl_reg;
212 unsigned has_hostpc:1; 212 unsigned has_hostpc:1;
213 unsigned has_tdi_phy_lpm:1;
213 unsigned has_ppcd:1; /* support per-port change bits */ 214 unsigned has_ppcd:1; /* support per-port change bits */
214 u8 sbrn; /* packed release number */ 215 u8 sbrn; /* packed release number */
215 216