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.c27
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))