On Tue, 1 Nov 2011, Sarah Sharp wrote: > Linus, Keith, and Paul, > > Can you try the attached patch and see if it helps your issues with > enabling runtime PM for the NEC USB 3.0 host controller? You may have > to increase the timeout for your system. > > > Hi Rafael, > > I mentioned I've been seeing failures when PCI runtime PM was enabled on > the xHCI host controller in my Lenovo x220. It turns out that several > people have the same NEC chipset in other Lenovo models, and are also > experiencing similar issues. When runtime PM is enabled for the host, > and you plug in a device, we get a steady stream of: > > Oct 31 16:11:31 puck kernel: [ 5196.504007] xhci_hcd 0000:0e:00.0: PME# enabled > Oct 31 16:11:40 puck kernel: [ 5205.503185] xhci_hcd 0000:0e:00.0: PME# disabled > Oct 31 16:11:40 puck kernel: [ 5205.503202] xhci_hcd 0000:0e:00.0: setting latency timer to 64 > > Those three lines are repeated, but the new USB device never enumerates. > > I've discovered that if I add a small delay in the xhci_resume function > (which is invoked by the dev_pm_ops resume method), then the host > controller has time to issue an interrupt about the port status change > before the runtime PM core puts it back into PCI suspend. > > I'm running Linus' latest tree as of yesterday (commit 839d8810), which > includes your commit 379021d "PCI / PM: Extend PME polling to all PCI > devices". Here is the promised test patch. It doesn't involve adding any funny delays. You might be able to improve this a little, but at least it should get things to work properly. Alan Stern Index: usb-3.2/drivers/usb/host/xhci.c =================================================================== --- usb-3.2.orig/drivers/usb/host/xhci.c +++ usb-3.2/drivers/usb/host/xhci.c @@ -799,7 +799,7 @@ int xhci_resume(struct xhci_hcd *xhci, b u32 command, temp = 0; struct usb_hcd *hcd = xhci_to_hcd(xhci); struct usb_hcd *secondary_hcd; - int retval; + int retval = 0; /* Wait a bit if either of the roothubs need to settle from the * transition into bus suspend. @@ -809,6 +809,9 @@ int xhci_resume(struct xhci_hcd *xhci, b xhci->bus_state[1].next_statechange)) msleep(100); + set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); + set_bit(HCD_FLAG_HW_ACCESSIBLE, &xhci->shared_hcd->flags); + spin_lock_irq(&xhci->lock); if (xhci->quirks & XHCI_RESET_ON_RESUME) hibernated = true; @@ -878,20 +881,13 @@ int xhci_resume(struct xhci_hcd *xhci, b return retval; xhci_dbg(xhci, "Start the primary HCD\n"); retval = xhci_run(hcd->primary_hcd); - if (retval) - goto failed_restart; - - xhci_dbg(xhci, "Start the secondary HCD\n"); - retval = xhci_run(secondary_hcd); if (!retval) { - set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); - set_bit(HCD_FLAG_HW_ACCESSIBLE, - &xhci->shared_hcd->flags); + xhci_dbg(xhci, "Start the secondary HCD\n"); + retval = xhci_run(secondary_hcd); } -failed_restart: hcd->state = HC_STATE_SUSPENDED; xhci->shared_hcd->state = HC_STATE_SUSPENDED; - return retval; + goto done; } /* step 4: set Run/Stop bit */ @@ -910,11 +906,14 @@ failed_restart: * Running endpoints by ringing their doorbells */ - set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); - set_bit(HCD_FLAG_HW_ACCESSIBLE, &xhci->shared_hcd->flags); - spin_unlock_irq(&xhci->lock); - return 0; + + done: + if (retval == 0) { + usb_hcd_resume_root_hub(hcd); + usb_hcd_resume_root_hub(xhci->shared_hcd); + } + return retval; } #endif /* CONFIG_PM */ -- To unsubscribe from this list: send the line "unsubscribe linux-pci" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html