USB: EHCI: use hrtimer for controller death
This patch (as1578) adds an hrtimer event to handle the death of an
EHCI controller. When a controller dies, it doesn't necessarily stop
running right away. The new event polls at 1-ms intervals to see when
all activity has safely stopped. This replaces a busy-wait polling
loop in the current code.
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index edcfd2c..1676c66 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -888,20 +888,20 @@
/* PCI errors [4.15.2.4] */
if (unlikely ((status & STS_FATAL) != 0)) {
ehci_err(ehci, "fatal error\n");
- ehci->rh_state = EHCI_RH_STOPPING;
dbg_cmd(ehci, "fatal", cmd);
dbg_status(ehci, "fatal", status);
- ehci_halt(ehci);
dead:
- ehci->enabled_hrtimer_events = 0;
- hrtimer_try_to_cancel(&ehci->hrtimer);
- ehci_reset(ehci);
- ehci_writel(ehci, 0, &ehci->regs->configured_flag);
usb_hc_died(hcd);
- /* generic layer kills/unlinks all urbs, then
- * uses ehci_stop to clean up the rest
- */
- bh = 1;
+
+ /* Don't let the controller do anything more */
+ ehci->rh_state = EHCI_RH_STOPPING;
+ ehci->command &= ~(CMD_RUN | CMD_ASE | CMD_PSE);
+ ehci_writel(ehci, ehci->command, &ehci->regs->command);
+ ehci_writel(ehci, 0, &ehci->regs->intr_enable);
+ ehci_handle_controller_death(ehci);
+
+ /* Handle completions when the controller stops */
+ bh = 0;
}
if (bh)