On Thu, 3 May 2018, Mathias Nyman wrote: > When everything is runtime suspended and start system suspend, we first suspend all > the usb devices, including the roothubs calling choose_wakeup() for the roothubs. > No flags are set yet. When pm continues suspending, and tries to suspend the xhci PCI > controller the PCI suspend code notices the device is runtime suspended, > it resumes it -> xhci_resume() -> usb_hcd_resume_root_hub() and WAKEUP_PENDING flag is set. > When PCI code then continues and tries to suspend the pci device it fails because the flag is set. Okay, I get the picture. And I just spent some time going over the core code and some of the other drivers. So yes, what I said earlier was wrong. The existing code in xhci_resume() is more or less correct; it should call usb_hcd_resume_root_hub() _only_ when there is a pending wakeup request from the root hub or a downstream device. Earlier you wrote: > If the check fails, then WAKEUP_PENDING bit is not set, and runtime PM > can suspend host controller again. when xhci driver finally gets to handle the interrupt > the controller may be in D3 already > > This should only happen if xhci_resume() is called before xhci driver sees a pending interrupt, > could be possible as xhci has interrupt moderation enabled. This is the real problem. You need to make sure that even with interrupt moderation, if there is a pending wakeup request then you can detect it properly. In other words, xhci_resume() may need to explicitly check the root-hub port statuses, because it can't rely on the interrupt handler to inform it that a wakeup request has been received. Does that make sense? Alan Stern -- 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