diff options
| -rw-r--r-- | drivers/usb/host/ehci-hub.c | 20 | ||||
| -rw-r--r-- | drivers/usb/host/uhci-hcd.c | 15 |
2 files changed, 33 insertions, 2 deletions
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index 2c6571c05f35..c75d9270c752 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c | |||
| @@ -120,9 +120,26 @@ static int ehci_bus_suspend (struct usb_hcd *hcd) | |||
| 120 | del_timer_sync(&ehci->watchdog); | 120 | del_timer_sync(&ehci->watchdog); |
| 121 | del_timer_sync(&ehci->iaa_watchdog); | 121 | del_timer_sync(&ehci->iaa_watchdog); |
| 122 | 122 | ||
| 123 | port = HCS_N_PORTS (ehci->hcs_params); | ||
| 124 | spin_lock_irq (&ehci->lock); | 123 | spin_lock_irq (&ehci->lock); |
| 125 | 124 | ||
| 125 | /* Once the controller is stopped, port resumes that are already | ||
| 126 | * in progress won't complete. Hence if remote wakeup is enabled | ||
| 127 | * for the root hub and any ports are in the middle of a resume or | ||
| 128 | * remote wakeup, we must fail the suspend. | ||
| 129 | */ | ||
| 130 | if (hcd->self.root_hub->do_remote_wakeup) { | ||
| 131 | port = HCS_N_PORTS(ehci->hcs_params); | ||
| 132 | while (port--) { | ||
| 133 | if (ehci->reset_done[port] != 0) { | ||
| 134 | spin_unlock_irq(&ehci->lock); | ||
| 135 | ehci_dbg(ehci, "suspend failed because " | ||
| 136 | "port %d is resuming\n", | ||
| 137 | port + 1); | ||
| 138 | return -EBUSY; | ||
| 139 | } | ||
| 140 | } | ||
| 141 | } | ||
| 142 | |||
| 126 | /* stop schedules, clean any completed work */ | 143 | /* stop schedules, clean any completed work */ |
| 127 | if (HC_IS_RUNNING(hcd->state)) { | 144 | if (HC_IS_RUNNING(hcd->state)) { |
| 128 | ehci_quiesce (ehci); | 145 | ehci_quiesce (ehci); |
| @@ -138,6 +155,7 @@ static int ehci_bus_suspend (struct usb_hcd *hcd) | |||
| 138 | */ | 155 | */ |
| 139 | ehci->bus_suspended = 0; | 156 | ehci->bus_suspended = 0; |
| 140 | ehci->owned_ports = 0; | 157 | ehci->owned_ports = 0; |
| 158 | port = HCS_N_PORTS(ehci->hcs_params); | ||
| 141 | while (port--) { | 159 | while (port--) { |
| 142 | u32 __iomem *reg = &ehci->regs->port_status [port]; | 160 | u32 __iomem *reg = &ehci->regs->port_status [port]; |
| 143 | u32 t1 = ehci_readl(ehci, reg) & ~PORT_RWC_BITS; | 161 | u32 t1 = ehci_readl(ehci, reg) & ~PORT_RWC_BITS; |
diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c index 5cd0e48f67fb..99cd00fd3514 100644 --- a/drivers/usb/host/uhci-hcd.c +++ b/drivers/usb/host/uhci-hcd.c | |||
| @@ -749,7 +749,20 @@ static int uhci_rh_suspend(struct usb_hcd *hcd) | |||
| 749 | spin_lock_irq(&uhci->lock); | 749 | spin_lock_irq(&uhci->lock); |
| 750 | if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) | 750 | if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) |
| 751 | rc = -ESHUTDOWN; | 751 | rc = -ESHUTDOWN; |
| 752 | else if (!uhci->dead) | 752 | else if (uhci->dead) |
| 753 | ; /* Dead controllers tell no tales */ | ||
| 754 | |||
| 755 | /* Once the controller is stopped, port resumes that are already | ||
| 756 | * in progress won't complete. Hence if remote wakeup is enabled | ||
| 757 | * for the root hub and any ports are in the middle of a resume or | ||
| 758 | * remote wakeup, we must fail the suspend. | ||
| 759 | */ | ||
| 760 | else if (hcd->self.root_hub->do_remote_wakeup && | ||
| 761 | uhci->resuming_ports) { | ||
| 762 | dev_dbg(uhci_dev(uhci), "suspend failed because a port " | ||
| 763 | "is resuming\n"); | ||
| 764 | rc = -EBUSY; | ||
| 765 | } else | ||
| 753 | suspend_rh(uhci, UHCI_RH_SUSPENDED); | 766 | suspend_rh(uhci, UHCI_RH_SUSPENDED); |
| 754 | spin_unlock_irq(&uhci->lock); | 767 | spin_unlock_irq(&uhci->lock); |
| 755 | return rc; | 768 | return rc; |
