aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/ehci-hub.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host/ehci-hub.c')
-rw-r--r--drivers/usb/host/ehci-hub.c84
1 files changed, 79 insertions, 5 deletions
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c
index f46ad27c9a90..1b6f1c0e5cee 100644
--- a/drivers/usb/host/ehci-hub.c
+++ b/drivers/usb/host/ehci-hub.c
@@ -111,6 +111,7 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
111 struct ehci_hcd *ehci = hcd_to_ehci (hcd); 111 struct ehci_hcd *ehci = hcd_to_ehci (hcd);
112 int port; 112 int port;
113 int mask; 113 int mask;
114 u32 __iomem *hostpc_reg = NULL;
114 115
115 ehci_dbg(ehci, "suspend root hub\n"); 116 ehci_dbg(ehci, "suspend root hub\n");
116 117
@@ -142,6 +143,9 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
142 u32 t1 = ehci_readl(ehci, reg) & ~PORT_RWC_BITS; 143 u32 t1 = ehci_readl(ehci, reg) & ~PORT_RWC_BITS;
143 u32 t2 = t1; 144 u32 t2 = t1;
144 145
146 if (ehci->has_hostpc)
147 hostpc_reg = (u32 __iomem *)((u8 *)ehci->regs
148 + HOSTPC0 + 4 * (port & 0xff));
145 /* keep track of which ports we suspend */ 149 /* keep track of which ports we suspend */
146 if (t1 & PORT_OWNER) 150 if (t1 & PORT_OWNER)
147 set_bit(port, &ehci->owned_ports); 151 set_bit(port, &ehci->owned_ports);
@@ -151,15 +155,37 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
151 } 155 }
152 156
153 /* enable remote wakeup on all ports */ 157 /* enable remote wakeup on all ports */
154 if (hcd->self.root_hub->do_remote_wakeup) 158 if (hcd->self.root_hub->do_remote_wakeup) {
155 t2 |= PORT_WAKE_BITS; 159 /* only enable appropriate wake bits, otherwise the
156 else 160 * hardware can not go phy low power mode. If a race
161 * condition happens here(connection change during bits
162 * set), the port change detection will finally fix it.
163 */
164 if (t1 & PORT_CONNECT) {
165 t2 |= PORT_WKOC_E | PORT_WKDISC_E;
166 t2 &= ~PORT_WKCONN_E;
167 } else {
168 t2 |= PORT_WKOC_E | PORT_WKCONN_E;
169 t2 &= ~PORT_WKDISC_E;
170 }
171 } else
157 t2 &= ~PORT_WAKE_BITS; 172 t2 &= ~PORT_WAKE_BITS;
158 173
159 if (t1 != t2) { 174 if (t1 != t2) {
160 ehci_vdbg (ehci, "port %d, %08x -> %08x\n", 175 ehci_vdbg (ehci, "port %d, %08x -> %08x\n",
161 port + 1, t1, t2); 176 port + 1, t1, t2);
162 ehci_writel(ehci, t2, reg); 177 ehci_writel(ehci, t2, reg);
178 if (hostpc_reg) {
179 u32 t3;
180
181 msleep(5);/* 5ms for HCD enter low pwr mode */
182 t3 = ehci_readl(ehci, hostpc_reg);
183 ehci_writel(ehci, t3 | HOSTPC_PHCD, hostpc_reg);
184 t3 = ehci_readl(ehci, hostpc_reg);
185 ehci_dbg(ehci, "Port%d phy low pwr mode %s\n",
186 port, (t3 & HOSTPC_PHCD) ?
187 "succeeded" : "failed");
188 }
163 } 189 }
164 } 190 }
165 191
@@ -183,6 +209,11 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
183 209
184 ehci->next_statechange = jiffies + msecs_to_jiffies(10); 210 ehci->next_statechange = jiffies + msecs_to_jiffies(10);
185 spin_unlock_irq (&ehci->lock); 211 spin_unlock_irq (&ehci->lock);
212
213 /* ehci_work() may have re-enabled the watchdog timer, which we do not
214 * want, and so we must delete any pending watchdog timer events.
215 */
216 del_timer_sync(&ehci->watchdog);
186 return 0; 217 return 0;
187} 218}
188 219
@@ -204,6 +235,13 @@ static int ehci_bus_resume (struct usb_hcd *hcd)
204 return -ESHUTDOWN; 235 return -ESHUTDOWN;
205 } 236 }
206 237
238 if (unlikely(ehci->debug)) {
239 if (ehci->debug && !dbgp_reset_prep())
240 ehci->debug = NULL;
241 else
242 dbgp_external_startup();
243 }
244
207 /* Ideally and we've got a real resume here, and no port's power 245 /* Ideally and we've got a real resume here, and no port's power
208 * was lost. (For PCI, that means Vaux was maintained.) But we 246 * was lost. (For PCI, that means Vaux was maintained.) But we
209 * could instead be restoring a swsusp snapshot -- so that BIOS was 247 * could instead be restoring a swsusp snapshot -- so that BIOS was
@@ -563,7 +601,8 @@ static int ehci_hub_control (
563 int ports = HCS_N_PORTS (ehci->hcs_params); 601 int ports = HCS_N_PORTS (ehci->hcs_params);
564 u32 __iomem *status_reg = &ehci->regs->port_status[ 602 u32 __iomem *status_reg = &ehci->regs->port_status[
565 (wIndex & 0xff) - 1]; 603 (wIndex & 0xff) - 1];
566 u32 temp, status; 604 u32 __iomem *hostpc_reg = NULL;
605 u32 temp, temp1, status;
567 unsigned long flags; 606 unsigned long flags;
568 int retval = 0; 607 int retval = 0;
569 unsigned selector; 608 unsigned selector;
@@ -575,6 +614,9 @@ static int ehci_hub_control (
575 * power, "this is the one", etc. EHCI spec supports this. 614 * power, "this is the one", etc. EHCI spec supports this.
576 */ 615 */
577 616
617 if (ehci->has_hostpc)
618 hostpc_reg = (u32 __iomem *)((u8 *)ehci->regs
619 + HOSTPC0 + 4 * ((wIndex & 0xff) - 1));
578 spin_lock_irqsave (&ehci->lock, flags); 620 spin_lock_irqsave (&ehci->lock, flags);
579 switch (typeReq) { 621 switch (typeReq) {
580 case ClearHubFeature: 622 case ClearHubFeature:
@@ -773,7 +815,11 @@ static int ehci_hub_control (
773 if (temp & PORT_CONNECT) { 815 if (temp & PORT_CONNECT) {
774 status |= 1 << USB_PORT_FEAT_CONNECTION; 816 status |= 1 << USB_PORT_FEAT_CONNECTION;
775 // status may be from integrated TT 817 // status may be from integrated TT
776 status |= ehci_port_speed(ehci, temp); 818 if (ehci->has_hostpc) {
819 temp1 = ehci_readl(ehci, hostpc_reg);
820 status |= ehci_port_speed(ehci, temp1);
821 } else
822 status |= ehci_port_speed(ehci, temp);
777 } 823 }
778 if (temp & PORT_PE) 824 if (temp & PORT_PE)
779 status |= 1 << USB_PORT_FEAT_ENABLE; 825 status |= 1 << USB_PORT_FEAT_ENABLE;
@@ -816,6 +862,15 @@ static int ehci_hub_control (
816 case SetPortFeature: 862 case SetPortFeature:
817 selector = wIndex >> 8; 863 selector = wIndex >> 8;
818 wIndex &= 0xff; 864 wIndex &= 0xff;
865 if (unlikely(ehci->debug)) {
866 /* If the debug port is active any port
867 * feature requests should get denied */
868 if (wIndex == HCS_DEBUG_PORT(ehci->hcs_params) &&
869 (readl(&ehci->debug->control) & DBGP_ENABLED)) {
870 retval = -ENODEV;
871 goto error_exit;
872 }
873 }
819 if (!wIndex || wIndex > ports) 874 if (!wIndex || wIndex > ports)
820 goto error; 875 goto error;
821 wIndex--; 876 wIndex--;
@@ -832,6 +887,24 @@ static int ehci_hub_control (
832 || (temp & PORT_RESET) != 0) 887 || (temp & PORT_RESET) != 0)
833 goto error; 888 goto error;
834 ehci_writel(ehci, temp | PORT_SUSPEND, status_reg); 889 ehci_writel(ehci, temp | PORT_SUSPEND, status_reg);
890 /* After above check the port must be connected.
891 * Set appropriate bit thus could put phy into low power
892 * mode if we have hostpc feature
893 */
894 if (hostpc_reg) {
895 temp &= ~PORT_WKCONN_E;
896 temp |= (PORT_WKDISC_E | PORT_WKOC_E);
897 ehci_writel(ehci, temp | PORT_SUSPEND,
898 status_reg);
899 msleep(5);/* 5ms for HCD enter low pwr mode */
900 temp1 = ehci_readl(ehci, hostpc_reg);
901 ehci_writel(ehci, temp1 | HOSTPC_PHCD,
902 hostpc_reg);
903 temp1 = ehci_readl(ehci, hostpc_reg);
904 ehci_dbg(ehci, "Port%d phy low pwr mode %s\n",
905 wIndex, (temp1 & HOSTPC_PHCD) ?
906 "succeeded" : "failed");
907 }
835 set_bit(wIndex, &ehci->suspended_ports); 908 set_bit(wIndex, &ehci->suspended_ports);
836 break; 909 break;
837 case USB_PORT_FEAT_POWER: 910 case USB_PORT_FEAT_POWER:
@@ -894,6 +967,7 @@ error:
894 /* "stall" on error */ 967 /* "stall" on error */
895 retval = -EPIPE; 968 retval = -EPIPE;
896 } 969 }
970error_exit:
897 spin_unlock_irqrestore (&ehci->lock, flags); 971 spin_unlock_irqrestore (&ehci->lock, flags);
898 return retval; 972 return retval;
899} 973}