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.c33
1 files changed, 27 insertions, 6 deletions
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c
index 2c6571c05f35..19372673bf09 100644
--- a/drivers/usb/host/ehci-hub.c
+++ b/drivers/usb/host/ehci-hub.c
@@ -120,9 +120,26 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
120 del_timer_sync(&ehci->watchdog); 120 del_timer_sync(&ehci->watchdog);
121 del_timer_sync(&ehci->iaa_watchdog); 121 del_timer_sync(&ehci->iaa_watchdog);
122 122
123 port = HCS_N_PORTS (ehci->hcs_params);
124 spin_lock_irq (&ehci->lock); 123 spin_lock_irq (&ehci->lock);
125 124
125 /* Once the controller is stopped, port resumes that are already
126 * in progress won't complete. Hence if remote wakeup is enabled
127 * for the root hub and any ports are in the middle of a resume or
128 * remote wakeup, we must fail the suspend.
129 */
130 if (hcd->self.root_hub->do_remote_wakeup) {
131 port = HCS_N_PORTS(ehci->hcs_params);
132 while (port--) {
133 if (ehci->reset_done[port] != 0) {
134 spin_unlock_irq(&ehci->lock);
135 ehci_dbg(ehci, "suspend failed because "
136 "port %d is resuming\n",
137 port + 1);
138 return -EBUSY;
139 }
140 }
141 }
142
126 /* stop schedules, clean any completed work */ 143 /* stop schedules, clean any completed work */
127 if (HC_IS_RUNNING(hcd->state)) { 144 if (HC_IS_RUNNING(hcd->state)) {
128 ehci_quiesce (ehci); 145 ehci_quiesce (ehci);
@@ -138,6 +155,7 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
138 */ 155 */
139 ehci->bus_suspended = 0; 156 ehci->bus_suspended = 0;
140 ehci->owned_ports = 0; 157 ehci->owned_ports = 0;
158 port = HCS_N_PORTS(ehci->hcs_params);
141 while (port--) { 159 while (port--) {
142 u32 __iomem *reg = &ehci->regs->port_status [port]; 160 u32 __iomem *reg = &ehci->regs->port_status [port];
143 u32 t1 = ehci_readl(ehci, reg) & ~PORT_RWC_BITS; 161 u32 t1 = ehci_readl(ehci, reg) & ~PORT_RWC_BITS;
@@ -178,7 +196,9 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
178 if (hostpc_reg) { 196 if (hostpc_reg) {
179 u32 t3; 197 u32 t3;
180 198
199 spin_unlock_irq(&ehci->lock);
181 msleep(5);/* 5ms for HCD enter low pwr mode */ 200 msleep(5);/* 5ms for HCD enter low pwr mode */
201 spin_lock_irq(&ehci->lock);
182 t3 = ehci_readl(ehci, hostpc_reg); 202 t3 = ehci_readl(ehci, hostpc_reg);
183 ehci_writel(ehci, t3 | HOSTPC_PHCD, hostpc_reg); 203 ehci_writel(ehci, t3 | HOSTPC_PHCD, hostpc_reg);
184 t3 = ehci_readl(ehci, hostpc_reg); 204 t3 = ehci_readl(ehci, hostpc_reg);
@@ -886,17 +906,18 @@ static int ehci_hub_control (
886 if ((temp & PORT_PE) == 0 906 if ((temp & PORT_PE) == 0
887 || (temp & PORT_RESET) != 0) 907 || (temp & PORT_RESET) != 0)
888 goto error; 908 goto error;
889 ehci_writel(ehci, temp | PORT_SUSPEND, status_reg); 909
890 /* After above check the port must be connected. 910 /* After above check the port must be connected.
891 * Set appropriate bit thus could put phy into low power 911 * Set appropriate bit thus could put phy into low power
892 * mode if we have hostpc feature 912 * mode if we have hostpc feature
893 */ 913 */
914 temp &= ~PORT_WKCONN_E;
915 temp |= PORT_WKDISC_E | PORT_WKOC_E;
916 ehci_writel(ehci, temp | PORT_SUSPEND, status_reg);
894 if (hostpc_reg) { 917 if (hostpc_reg) {
895 temp &= ~PORT_WKCONN_E; 918 spin_unlock_irqrestore(&ehci->lock, flags);
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 */ 919 msleep(5);/* 5ms for HCD enter low pwr mode */
920 spin_lock_irqsave(&ehci->lock, flags);
900 temp1 = ehci_readl(ehci, hostpc_reg); 921 temp1 = ehci_readl(ehci, hostpc_reg);
901 ehci_writel(ehci, temp1 | HOSTPC_PHCD, 922 ehci_writel(ehci, temp1 | HOSTPC_PHCD,
902 hostpc_reg); 923 hostpc_reg);