We don't want to runtime suspend a bus if there is an event pending. The roothub on a NEC uPD720200 host with a single USB3 device connected might go back to runtime suspend immediately after runtime resume as hub might not yet see any port changes in resume. Prevent this by checking if there is a unhandled event pending when calling runtime suspend. Cc: <stable@xxxxxxxxxxxxxxx> Tested-by: Mike Murdoch <main.haarp@xxxxxxxxx> Signed-off-by: Mathias Nyman <mathias.nyman@xxxxxxxxxxxxxxx> --- drivers/usb/host/xhci-hub.c | 6 ++++++ drivers/usb/host/xhci.c | 1 + 2 files changed, 7 insertions(+) diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index d61fcc4..7e8999a 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c @@ -1289,12 +1289,18 @@ int xhci_bus_suspend(struct usb_hcd *hcd) __le32 __iomem **port_array; struct xhci_bus_state *bus_state; unsigned long flags; + u32 status; max_ports = xhci_get_ports(hcd, &port_array); bus_state = &xhci->bus_state[hcd_index(hcd)]; spin_lock_irqsave(&xhci->lock, flags); + /* Don't suspend root hub if there's an event pending. */ + status = readl(&xhci->op_regs->status); + if (status & STS_EINT) + return -EBUSY; + if (hcd->self.root_hub->do_remote_wakeup) { if (bus_state->resuming_ports || /* USB2 */ bus_state->port_remote_wakeup) { /* USB3 */ diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index b609288..16366a9 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -1107,6 +1107,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) if (retval == 0) { /* Resume root hubs only when have pending events. */ status = readl(&xhci->op_regs->status); + xhci_dbg(xhci, "xhci_resume status reg = 0x%x\n", status); if (status & STS_EINT) { usb_hcd_resume_root_hub(xhci->shared_hcd); usb_hcd_resume_root_hub(hcd); -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html