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.c50
1 files changed, 32 insertions, 18 deletions
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c
index 3cfba69e0767..0d83c6df1a3b 100644
--- a/drivers/usb/host/ehci-hub.c
+++ b/drivers/usb/host/ehci-hub.c
@@ -379,8 +379,8 @@ ehci_hub_status_data (struct usb_hcd *hcd, char *buf)
379 ehci->reset_done [i] = 0; 379 ehci->reset_done [i] = 0;
380 if ((temp & mask) != 0 380 if ((temp & mask) != 0
381 || ((temp & PORT_RESUME) != 0 381 || ((temp & PORT_RESUME) != 0
382 && time_after (jiffies, 382 && time_after_eq(jiffies,
383 ehci->reset_done [i]))) { 383 ehci->reset_done[i]))) {
384 if (i < 7) 384 if (i < 7)
385 buf [0] |= 1 << (i + 1); 385 buf [0] |= 1 << (i + 1);
386 else 386 else
@@ -554,31 +554,45 @@ static int ehci_hub_control (
554 status |= 1 << USB_PORT_FEAT_C_OVER_CURRENT; 554 status |= 1 << USB_PORT_FEAT_C_OVER_CURRENT;
555 555
556 /* whoever resumes must GetPortStatus to complete it!! */ 556 /* whoever resumes must GetPortStatus to complete it!! */
557 if ((temp & PORT_RESUME) 557 if (temp & PORT_RESUME) {
558 && time_after (jiffies,
559 ehci->reset_done [wIndex])) {
560 status |= 1 << USB_PORT_FEAT_C_SUSPEND;
561 ehci->reset_done [wIndex] = 0;
562 558
563 /* stop resume signaling */ 559 /* Remote Wakeup received? */
564 temp = ehci_readl(ehci, status_reg); 560 if (!ehci->reset_done[wIndex]) {
565 ehci_writel(ehci, 561 /* resume signaling for 20 msec */
562 ehci->reset_done[wIndex] = jiffies
563 + msecs_to_jiffies(20);
564 /* check the port again */
565 mod_timer(&ehci_to_hcd(ehci)->rh_timer,
566 ehci->reset_done[wIndex]);
567 }
568
569 /* resume completed? */
570 else if (time_after_eq(jiffies,
571 ehci->reset_done[wIndex])) {
572 status |= 1 << USB_PORT_FEAT_C_SUSPEND;
573 ehci->reset_done[wIndex] = 0;
574
575 /* stop resume signaling */
576 temp = ehci_readl(ehci, status_reg);
577 ehci_writel(ehci,
566 temp & ~(PORT_RWC_BITS | PORT_RESUME), 578 temp & ~(PORT_RWC_BITS | PORT_RESUME),
567 status_reg); 579 status_reg);
568 retval = handshake(ehci, status_reg, 580 retval = handshake(ehci, status_reg,
569 PORT_RESUME, 0, 2000 /* 2msec */); 581 PORT_RESUME, 0, 2000 /* 2msec */);
570 if (retval != 0) { 582 if (retval != 0) {
571 ehci_err (ehci, "port %d resume error %d\n", 583 ehci_err(ehci,
572 wIndex + 1, retval); 584 "port %d resume error %d\n",
573 goto error; 585 wIndex + 1, retval);
586 goto error;
587 }
588 temp &= ~(PORT_SUSPEND|PORT_RESUME|(3<<10));
574 } 589 }
575 temp &= ~(PORT_SUSPEND|PORT_RESUME|(3<<10));
576 } 590 }
577 591
578 /* whoever resets must GetPortStatus to complete it!! */ 592 /* whoever resets must GetPortStatus to complete it!! */
579 if ((temp & PORT_RESET) 593 if ((temp & PORT_RESET)
580 && time_after (jiffies, 594 && time_after_eq(jiffies,
581 ehci->reset_done [wIndex])) { 595 ehci->reset_done[wIndex])) {
582 status |= 1 << USB_PORT_FEAT_C_RESET; 596 status |= 1 << USB_PORT_FEAT_C_RESET;
583 ehci->reset_done [wIndex] = 0; 597 ehci->reset_done [wIndex] = 0;
584 598