aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/ehci-hcd.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host/ehci-hcd.c')
-rw-r--r--drivers/usb/host/ehci-hcd.c20
1 files changed, 19 insertions, 1 deletions
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index ac4c8ddde20a..e44ca5453aa2 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -343,6 +343,7 @@ static void ehci_shutdown(struct usb_hcd *hcd)
343 struct ehci_hcd *ehci = hcd_to_ehci(hcd); 343 struct ehci_hcd *ehci = hcd_to_ehci(hcd);
344 344
345 spin_lock_irq(&ehci->lock); 345 spin_lock_irq(&ehci->lock);
346 ehci->shutdown = true;
346 ehci->rh_state = EHCI_RH_STOPPING; 347 ehci->rh_state = EHCI_RH_STOPPING;
347 ehci->enabled_hrtimer_events = 0; 348 ehci->enabled_hrtimer_events = 0;
348 spin_unlock_irq(&ehci->lock); 349 spin_unlock_irq(&ehci->lock);
@@ -823,6 +824,7 @@ dead:
823 usb_hc_died(hcd); 824 usb_hc_died(hcd);
824 825
825 /* Don't let the controller do anything more */ 826 /* Don't let the controller do anything more */
827 ehci->shutdown = true;
826 ehci->rh_state = EHCI_RH_STOPPING; 828 ehci->rh_state = EHCI_RH_STOPPING;
827 ehci->command &= ~(CMD_RUN | CMD_ASE | CMD_PSE); 829 ehci->command &= ~(CMD_RUN | CMD_ASE | CMD_PSE);
828 ehci_writel(ehci, ehci->command, &ehci->regs->command); 830 ehci_writel(ehci, ehci->command, &ehci->regs->command);
@@ -1129,6 +1131,9 @@ static int __maybe_unused ehci_resume(struct usb_hcd *hcd, bool hibernated)
1129 /* Mark hardware accessible again as we are back to full power by now */ 1131 /* Mark hardware accessible again as we are back to full power by now */
1130 set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); 1132 set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
1131 1133
1134 if (ehci->shutdown)
1135 return 0; /* Controller is dead */
1136
1132 /* 1137 /*
1133 * If CF is still set and we aren't resuming from hibernation 1138 * If CF is still set and we aren't resuming from hibernation
1134 * then we maintained suspend power. 1139 * then we maintained suspend power.
@@ -1139,10 +1144,17 @@ static int __maybe_unused ehci_resume(struct usb_hcd *hcd, bool hibernated)
1139 int mask = INTR_MASK; 1144 int mask = INTR_MASK;
1140 1145
1141 ehci_prepare_ports_for_controller_resume(ehci); 1146 ehci_prepare_ports_for_controller_resume(ehci);
1147
1148 spin_lock_irq(&ehci->lock);
1149 if (ehci->shutdown)
1150 goto skip;
1151
1142 if (!hcd->self.root_hub->do_remote_wakeup) 1152 if (!hcd->self.root_hub->do_remote_wakeup)
1143 mask &= ~STS_PCD; 1153 mask &= ~STS_PCD;
1144 ehci_writel(ehci, mask, &ehci->regs->intr_enable); 1154 ehci_writel(ehci, mask, &ehci->regs->intr_enable);
1145 ehci_readl(ehci, &ehci->regs->intr_enable); 1155 ehci_readl(ehci, &ehci->regs->intr_enable);
1156 skip:
1157 spin_unlock_irq(&ehci->lock);
1146 return 0; 1158 return 0;
1147 } 1159 }
1148 1160
@@ -1154,14 +1166,20 @@ static int __maybe_unused ehci_resume(struct usb_hcd *hcd, bool hibernated)
1154 (void) ehci_halt(ehci); 1166 (void) ehci_halt(ehci);
1155 (void) ehci_reset(ehci); 1167 (void) ehci_reset(ehci);
1156 1168
1169 spin_lock_irq(&ehci->lock);
1170 if (ehci->shutdown)
1171 goto skip;
1172
1157 ehci_writel(ehci, ehci->command, &ehci->regs->command); 1173 ehci_writel(ehci, ehci->command, &ehci->regs->command);
1158 ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag); 1174 ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag);
1159 ehci_readl(ehci, &ehci->regs->command); /* unblock posted writes */ 1175 ehci_readl(ehci, &ehci->regs->command); /* unblock posted writes */
1160 1176
1177 ehci->rh_state = EHCI_RH_SUSPENDED;
1178 spin_unlock_irq(&ehci->lock);
1179
1161 /* here we "know" root ports should always stay powered */ 1180 /* here we "know" root ports should always stay powered */
1162 ehci_port_power(ehci, 1); 1181 ehci_port_power(ehci, 1);
1163 1182
1164 ehci->rh_state = EHCI_RH_SUSPENDED;
1165 return 1; 1183 return 1;
1166} 1184}
1167 1185