aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/ehci-hub.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-01-07 18:37:24 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2009-01-07 18:37:24 -0500
commit7c7758f99d39d529a64d4f60d22129bbf2f16d74 (patch)
tree8847b5e56812fe4c4c812cfffc78e391a91f4ebe /drivers/usb/host/ehci-hub.c
parent67acd8b4b7a3f1b183ae358e1dfdb8a80e170736 (diff)
parent8a70da82edc50aa7a4b54864babf2d72538ba1bb (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6: (123 commits) wimax/i2400m: add CREDITS and MAINTAINERS entries wimax: export linux/wimax.h and linux/wimax/i2400m.h with headers_install i2400m: Makefile and Kconfig i2400m/SDIO: TX and RX path backends i2400m/SDIO: firmware upload backend i2400m/SDIO: probe/disconnect, dev init/shutdown and reset backends i2400m/SDIO: header for the SDIO subdriver i2400m/USB: TX and RX path backends i2400m/USB: firmware upload backend i2400m/USB: probe/disconnect, dev init/shutdown and reset backends i2400m/USB: header for the USB bus driver i2400m: debugfs controls i2400m: various functions for device management i2400m: RX and TX data/control paths i2400m: firmware loading and bootrom initialization i2400m: linkage to the networking stack i2400m: Generic probe/disconnect, reset and message passing i2400m: host/device procotol and core driver definitions i2400m: documentation and instructions for usage wimax: Makefile, Kconfig and docbook linkage for the stack ...
Diffstat (limited to 'drivers/usb/host/ehci-hub.c')
-rw-r--r--drivers/usb/host/ehci-hub.c27
1 files changed, 23 insertions, 4 deletions
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c
index 218f9660d7ee..97a53a48a3d8 100644
--- a/drivers/usb/host/ehci-hub.c
+++ b/drivers/usb/host/ehci-hub.c
@@ -194,6 +194,7 @@ static int ehci_bus_resume (struct usb_hcd *hcd)
194 u32 temp; 194 u32 temp;
195 u32 power_okay; 195 u32 power_okay;
196 int i; 196 int i;
197 u8 resume_needed = 0;
197 198
198 if (time_before (jiffies, ehci->next_statechange)) 199 if (time_before (jiffies, ehci->next_statechange))
199 msleep(5); 200 msleep(5);
@@ -228,7 +229,9 @@ static int ehci_bus_resume (struct usb_hcd *hcd)
228 229
229 /* Some controller/firmware combinations need a delay during which 230 /* Some controller/firmware combinations need a delay during which
230 * they set up the port statuses. See Bugzilla #8190. */ 231 * they set up the port statuses. See Bugzilla #8190. */
231 mdelay(8); 232 spin_unlock_irq(&ehci->lock);
233 msleep(8);
234 spin_lock_irq(&ehci->lock);
232 235
233 /* manually resume the ports we suspended during bus_suspend() */ 236 /* manually resume the ports we suspended during bus_suspend() */
234 i = HCS_N_PORTS (ehci->hcs_params); 237 i = HCS_N_PORTS (ehci->hcs_params);
@@ -236,12 +239,21 @@ static int ehci_bus_resume (struct usb_hcd *hcd)
236 temp = ehci_readl(ehci, &ehci->regs->port_status [i]); 239 temp = ehci_readl(ehci, &ehci->regs->port_status [i]);
237 temp &= ~(PORT_RWC_BITS | PORT_WAKE_BITS); 240 temp &= ~(PORT_RWC_BITS | PORT_WAKE_BITS);
238 if (test_bit(i, &ehci->bus_suspended) && 241 if (test_bit(i, &ehci->bus_suspended) &&
239 (temp & PORT_SUSPEND)) 242 (temp & PORT_SUSPEND)) {
240 temp |= PORT_RESUME; 243 temp |= PORT_RESUME;
244 resume_needed = 1;
245 }
241 ehci_writel(ehci, temp, &ehci->regs->port_status [i]); 246 ehci_writel(ehci, temp, &ehci->regs->port_status [i]);
242 } 247 }
248
249 /* msleep for 20ms only if code is trying to resume port */
250 if (resume_needed) {
251 spin_unlock_irq(&ehci->lock);
252 msleep(20);
253 spin_lock_irq(&ehci->lock);
254 }
255
243 i = HCS_N_PORTS (ehci->hcs_params); 256 i = HCS_N_PORTS (ehci->hcs_params);
244 mdelay (20);
245 while (i--) { 257 while (i--) {
246 temp = ehci_readl(ehci, &ehci->regs->port_status [i]); 258 temp = ehci_readl(ehci, &ehci->regs->port_status [i]);
247 if (test_bit(i, &ehci->bus_suspended) && 259 if (test_bit(i, &ehci->bus_suspended) &&
@@ -422,8 +434,15 @@ static int check_reset_complete (
422 port_status &= ~PORT_RWC_BITS; 434 port_status &= ~PORT_RWC_BITS;
423 ehci_writel(ehci, port_status, status_reg); 435 ehci_writel(ehci, port_status, status_reg);
424 436
425 } else 437 /* ensure 440EPX ohci controller state is operational */
438 if (ehci->has_amcc_usb23)
439 set_ohci_hcfs(ehci, 1);
440 } else {
426 ehci_dbg (ehci, "port %d high speed\n", index + 1); 441 ehci_dbg (ehci, "port %d high speed\n", index + 1);
442 /* ensure 440EPx ohci controller state is suspended */
443 if (ehci->has_amcc_usb23)
444 set_ohci_hcfs(ehci, 0);
445 }
427 446
428 return port_status; 447 return port_status;
429} 448}