summaryrefslogtreecommitdiff
path: root/drivers/usb
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2006-08-11 11:33:58 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2006-09-27 11:58:54 -0700
commitde06a3b842b31b31220637c869f112cfbc1a5ef6 (patch)
tree3b179338903b5ad7ca0c0676f14d2ef6437eb545 /drivers/usb
parent64a21d025d3a979a8715f2ec7acabca7b5406c8a (diff)
UHCI: increase Resume-Detect-off delay
The UHCI controller in my laptop takes longer to turn off the Resume-Detect bit than the 4 us allowed by uhci-hcd. Presumably other computers will have the same problem. This patch (as752) increases the maximum delay to 10 us, which should be plenty, and uses polling to avoid penalizing systems which can turn the bit off more quickly. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/host/uhci-hub.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/drivers/usb/host/uhci-hub.c b/drivers/usb/host/uhci-hub.c
index c545ef92fe29..16fb72eb6fc9 100644
--- a/drivers/usb/host/uhci-hub.c
+++ b/drivers/usb/host/uhci-hub.c
@@ -84,6 +84,7 @@ static void uhci_finish_suspend(struct uhci_hcd *uhci, int port,
unsigned long port_addr)
{
int status;
+ int i;
if (inw(port_addr) & (USBPORTSC_SUSP | USBPORTSC_RD)) {
CLR_RH_PORTSTAT(USBPORTSC_SUSP | USBPORTSC_RD);
@@ -92,9 +93,14 @@ static void uhci_finish_suspend(struct uhci_hcd *uhci, int port,
/* The controller won't actually turn off the RD bit until
* it has had a chance to send a low-speed EOP sequence,
- * which takes 3 bit times (= 2 microseconds). We'll delay
- * slightly longer for good luck. */
- udelay(4);
+ * which is supposed to take 3 bit times (= 2 microseconds).
+ * Experiments show that some controllers take longer, so
+ * we'll poll for completion. */
+ for (i = 0; i < 10; ++i) {
+ if (!(inw(port_addr) & USBPORTSC_RD))
+ break;
+ udelay(1);
+ }
}
clear_bit(port, &uhci->resuming_ports);
}