On 11.05.2015 17:44, Ralf Jung wrote: > Hi, > >> Ok, xhci is reset in resume in your case (indicated by the "root hub lost power or was reset" messages) >> That patch adds an additional check that ensures there was some event before resuming the roothub. >> >> Could you try out the following and see if it helps? If the event is lost/cleared during reset >> then this change should work. > > Sure. What version is this patch against? I did "patch -p1" with > v4.1-rc2 checked out, and all three hunks fail. > Attached a testpatch based on 4.1-rc2 >> Can you try with auto-pm disabled for PCI xHCI host? >> >> # echo 'on' | tee /sys/bus/pci/devices/*/power/control > > I'll also try the PM settings mentioned by baolu. In fact, he reminded > me that I added the following udev rule to save some power (and powertop > got happy ;-): > > ACTION=="add", SUBSYSTEM=="pci", ATTR{power/control}="auto" > > Sorry that I forgot to mention this. No worries, we need to get the usb3 drive detected even if the controller is in runtime suspend. -Mathias
>From 7e0326dd33ab53edef694cb2ec0a4d6ec46b9c97 Mon Sep 17 00:00:00 2001 From: Mathias Nyman <mathias.nyman@xxxxxxxxxxxxxxx> Date: Tue, 12 May 2015 13:40:34 +0300 Subject: [PATCH] xhci: check if roothubs need to be resumed early in xhci resume Testpatch for Ralf Jung to check if we got a pending event interrupt early when resuming the host, and make sure resume the roothubs in that case. A theory is that the cases we need to re-initialize the xhci host in resume we will lose the event interrupt, and refuse to resume the roothubs as there are no pending event to handle. Signed-off-by: Mathias Nyman <mathias.nyman@xxxxxxxxxxxxxxx> --- drivers/usb/host/xhci.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index ec8ac16..2e0d6ba 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -982,6 +982,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) struct usb_hcd *secondary_hcd; int retval = 0; bool comp_timer_running = false; + int resume_hubs; /* Wait a bit if either of the roothubs need to settle from the * transition into bus suspend. @@ -1017,6 +1018,8 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated) temp = readl(&xhci->op_regs->status); } + resume_hubs = readl(&xhci->op_regs->status) & STS_EINT; + /* If restore operation fails, re-initialize the HC during resume */ if ((temp & STS_SRE) || hibernated) { @@ -1097,7 +1100,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); - if (status & STS_EINT) { + if (status & STS_EINT || resume_hubs) { usb_hcd_resume_root_hub(hcd); usb_hcd_resume_root_hub(xhci->shared_hcd); } -- 1.8.3.2