diff options
Diffstat (limited to 'drivers/usb/host/ehci-hub.c')
-rw-r--r-- | drivers/usb/host/ehci-hub.c | 27 |
1 files changed, 19 insertions, 8 deletions
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index 740835bb8575..218f9660d7ee 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c | |||
@@ -236,10 +236,8 @@ static int ehci_bus_resume (struct usb_hcd *hcd) | |||
236 | temp = ehci_readl(ehci, &ehci->regs->port_status [i]); | 236 | temp = ehci_readl(ehci, &ehci->regs->port_status [i]); |
237 | temp &= ~(PORT_RWC_BITS | PORT_WAKE_BITS); | 237 | temp &= ~(PORT_RWC_BITS | PORT_WAKE_BITS); |
238 | if (test_bit(i, &ehci->bus_suspended) && | 238 | if (test_bit(i, &ehci->bus_suspended) && |
239 | (temp & PORT_SUSPEND)) { | 239 | (temp & PORT_SUSPEND)) |
240 | ehci->reset_done [i] = jiffies + msecs_to_jiffies (20); | ||
241 | temp |= PORT_RESUME; | 240 | temp |= PORT_RESUME; |
242 | } | ||
243 | ehci_writel(ehci, temp, &ehci->regs->port_status [i]); | 241 | ehci_writel(ehci, temp, &ehci->regs->port_status [i]); |
244 | } | 242 | } |
245 | i = HCS_N_PORTS (ehci->hcs_params); | 243 | i = HCS_N_PORTS (ehci->hcs_params); |
@@ -482,10 +480,9 @@ ehci_hub_status_data (struct usb_hcd *hcd, char *buf) | |||
482 | * controller by the user. | 480 | * controller by the user. |
483 | */ | 481 | */ |
484 | 482 | ||
485 | if ((temp & mask) != 0 | 483 | if ((temp & mask) != 0 || test_bit(i, &ehci->port_c_suspend) |
486 | || ((temp & PORT_RESUME) != 0 | 484 | || (ehci->reset_done[i] && time_after_eq( |
487 | && time_after_eq(jiffies, | 485 | jiffies, ehci->reset_done[i]))) { |
488 | ehci->reset_done[i]))) { | ||
489 | if (i < 7) | 486 | if (i < 7) |
490 | buf [0] |= 1 << (i + 1); | 487 | buf [0] |= 1 << (i + 1); |
491 | else | 488 | else |
@@ -688,6 +685,7 @@ static int ehci_hub_control ( | |||
688 | /* resume completed? */ | 685 | /* resume completed? */ |
689 | else if (time_after_eq(jiffies, | 686 | else if (time_after_eq(jiffies, |
690 | ehci->reset_done[wIndex])) { | 687 | ehci->reset_done[wIndex])) { |
688 | clear_bit(wIndex, &ehci->suspended_ports); | ||
691 | set_bit(wIndex, &ehci->port_c_suspend); | 689 | set_bit(wIndex, &ehci->port_c_suspend); |
692 | ehci->reset_done[wIndex] = 0; | 690 | ehci->reset_done[wIndex] = 0; |
693 | 691 | ||
@@ -734,6 +732,9 @@ static int ehci_hub_control ( | |||
734 | ehci_readl(ehci, status_reg)); | 732 | ehci_readl(ehci, status_reg)); |
735 | } | 733 | } |
736 | 734 | ||
735 | if (!(temp & (PORT_RESUME|PORT_RESET))) | ||
736 | ehci->reset_done[wIndex] = 0; | ||
737 | |||
737 | /* transfer dedicated ports to the companion hc */ | 738 | /* transfer dedicated ports to the companion hc */ |
738 | if ((temp & PORT_CONNECT) && | 739 | if ((temp & PORT_CONNECT) && |
739 | test_bit(wIndex, &ehci->companion_ports)) { | 740 | test_bit(wIndex, &ehci->companion_ports)) { |
@@ -757,8 +758,17 @@ static int ehci_hub_control ( | |||
757 | } | 758 | } |
758 | if (temp & PORT_PE) | 759 | if (temp & PORT_PE) |
759 | status |= 1 << USB_PORT_FEAT_ENABLE; | 760 | status |= 1 << USB_PORT_FEAT_ENABLE; |
760 | if (temp & (PORT_SUSPEND|PORT_RESUME)) | 761 | |
762 | /* maybe the port was unsuspended without our knowledge */ | ||
763 | if (temp & (PORT_SUSPEND|PORT_RESUME)) { | ||
761 | status |= 1 << USB_PORT_FEAT_SUSPEND; | 764 | status |= 1 << USB_PORT_FEAT_SUSPEND; |
765 | } else if (test_bit(wIndex, &ehci->suspended_ports)) { | ||
766 | clear_bit(wIndex, &ehci->suspended_ports); | ||
767 | ehci->reset_done[wIndex] = 0; | ||
768 | if (temp & PORT_PE) | ||
769 | set_bit(wIndex, &ehci->port_c_suspend); | ||
770 | } | ||
771 | |||
762 | if (temp & PORT_OC) | 772 | if (temp & PORT_OC) |
763 | status |= 1 << USB_PORT_FEAT_OVER_CURRENT; | 773 | status |= 1 << USB_PORT_FEAT_OVER_CURRENT; |
764 | if (temp & PORT_RESET) | 774 | if (temp & PORT_RESET) |
@@ -803,6 +813,7 @@ static int ehci_hub_control ( | |||
803 | || (temp & PORT_RESET) != 0) | 813 | || (temp & PORT_RESET) != 0) |
804 | goto error; | 814 | goto error; |
805 | ehci_writel(ehci, temp | PORT_SUSPEND, status_reg); | 815 | ehci_writel(ehci, temp | PORT_SUSPEND, status_reg); |
816 | set_bit(wIndex, &ehci->suspended_ports); | ||
806 | break; | 817 | break; |
807 | case USB_PORT_FEAT_POWER: | 818 | case USB_PORT_FEAT_POWER: |
808 | if (HCS_PPC (ehci->hcs_params)) | 819 | if (HCS_PPC (ehci->hcs_params)) |