• Wang, Yu's avatar
    xhci: Fix runtime suspended xhci from blocking system suspend. · d6236f6d
    Wang, Yu authored
    The system suspend flow as following:
    1, Freeze all user processes and kenrel threads.
    2, Try to suspend all devices.
    2.1, If pci device is in RPM suspended state, then pci driver will try
    to resume it to RPM active state in the prepare stage.
    2.2, xhci_resume function calls usb_hcd_resume_root_hub to queue two
    workqueue items to resume usb2&usb3 roothub devices.
    2.3, Call suspend callbacks of devices.
    2.3.1, All suspend callbacks of all hcd's children, including
    roothub devices are called.
    2.3.2, Finally, hcd_pci_suspend callback is called.
    Due to workqueue threads were already frozen in step 1, the workqueue
    items can't be scheduled, and the roothub devices can't be resumed in
    this flow. The HCD_FLAG_WAKEUP_PENDING flag which is set in
    usb_hcd_resume_root_hub won't be cleared. Finally,
    hcd_pci_suspend will return -EBUSY, and system suspend fails.
    The reason why this issue doesn't show up very often is due to that
    choose_wakeup will be called in step 2.3.1. In step 2.3.1, if
    udev->do_remote_wakeup is not equal to device_may_wakeup(&udev->dev), then
    udev will resume to RPM active for changing the wakeup settings. This
    has been a lucky hit which hides this issue.
    For some special xHCI controllers which have no USB2 port, then roothub
    will not match hub driver due to probe failed. Then its
    do_remote_wakeup will be set to zero, and we won't be as lucky.
    xhci driver doesn't need to resume roothub devices everytime like in
    the above case. It's only needed when there are pending event TRBs.
    This patch should be back-ported to kernels as old as 3.2, that
    contains the commit f69e3120
    "USB: XHCI: resume root hubs when the controller resumes"
    Cc: stable@vger.kernel.org # 3.2
    Signed-off-by: default avatarWang, Yu <yu.y.wang@intel.com>
    Acked-by: default avatarAlan Stern <stern@rowland.harvard.edu>
    [use readl() instead of removed xhci_readl(), reword commit message -Mathias]
    Signed-off-by: default avatarMathias Nyman <mathias.nyman@linux.intel.com>
    Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
xhci.c 146 KB