diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-01-07 18:37:24 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-01-07 18:37:24 -0500 |
commit | 7c7758f99d39d529a64d4f60d22129bbf2f16d74 (patch) | |
tree | 8847b5e56812fe4c4c812cfffc78e391a91f4ebe /drivers/usb/host/ehci-hub.c | |
parent | 67acd8b4b7a3f1b183ae358e1dfdb8a80e170736 (diff) | |
parent | 8a70da82edc50aa7a4b54864babf2d72538ba1bb (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.c | 27 |
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 | } |