]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
xhci: prevent bus_suspend if SS port resuming in phase 1
authorZhuang Jin Can <jin.can.zhuang@intel.com>
Tue, 21 Jul 2015 14:20:29 +0000 (17:20 +0300)
committerSasha Levin <sasha.levin@oracle.com>
Thu, 27 Aug 2015 17:25:48 +0000 (13:25 -0400)
[ Upstream commit fac4271d1126c45ceaceb7f4a336317b771eb121 ]

When the link is just waken, it's in Resume state, and driver sets PLS to
U0. This refers to Phase 1. Phase 2 refers to when the link has completed
the transition from Resume state to U0.

With the fix of xhci: report U3 when link is in resume state, it also
exposes an issue that usb3 roothub and controller can suspend right
after phase 1, and this causes a hard hang in controller.

To fix the issue, we need to prevent usb3 bus suspend if any port is
resuming in phase 1.

[merge separate USB2 and USB3 port resume checking to one -Mathias]
Cc: <stable@vger.kernel.org>
Signed-off-by: Zhuang Jin Can <jin.can.zhuang@intel.com>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
drivers/usb/host/xhci-hub.c

index 7ff97c39c8b4d2d7d174d4325bdca51080d61627..f24bdf3a422ef9c1100e81a0e7a4bed63fa00c3f 100644 (file)
@@ -484,10 +484,13 @@ static void xhci_hub_report_usb3_link_state(struct xhci_hcd *xhci,
        u32 pls = status_reg & PORT_PLS_MASK;
 
        /* resume state is a xHCI internal state.
-        * Do not report it to usb core.
+        * Do not report it to usb core, instead, pretend to be U3,
+        * thus usb core knows it's not ready for transfer
         */
-       if (pls == XDEV_RESUME)
+       if (pls == XDEV_RESUME) {
+               *status |= USB_SS_PORT_LS_U3;
                return;
+       }
 
        /* When the CAS bit is set then warm reset
         * should be performed on port