diff options
author | Vikram Pandita <vikram.pandita@ti.com> | 2008-10-24 14:11:30 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2009-01-07 12:59:50 -0500 |
commit | 3a4e72cbf2ac4435630a2b03bd25e60ef5967e99 (patch) | |
tree | 9e52159e2e759cd0b31ad1c67c6c85da1a08075c /drivers/usb/host/ehci-hub.c | |
parent | 8e8ce4b642ce4beb865fb1d67cd8ea883d9ae7d7 (diff) |
USB: Avoid 20ms delay in EHCI resume
For function ehci_bus_resume()
- Added flag resume_needed
No need to wait for 20ms if no port was suspended
- Change mdelay to msleep
- release and reacquire the spinlock around mdelay
Signed-off-by: vikram pandita <vikram.pandita@ti.com>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/host/ehci-hub.c')
-rw-r--r-- | drivers/usb/host/ehci-hub.c | 18 |
1 files changed, 15 insertions, 3 deletions
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index 218f9660d7ee..38650707dfe0 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) && |