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 majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to