Patch "xhci: prevent bus_suspend if SS port resuming in phase 1" has been added to the 3.14-stable tree
From: <gregkh@linuxfoundation.org>
Date: 2015-08-08 21:06:39
This is a note to let you know that I've just added the patch titled
xhci: prevent bus_suspend if SS port resuming in phase 1
to the 3.14-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
xhci-prevent-bus_suspend-if-ss-port-resuming-in-phase-1.patch
and it can be found in the queue-3.14 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let [off-list ref] know about it.
From fac4271d1126c45ceaceb7f4a336317b771eb121 Mon Sep 17 00:00:00 2001
From: Zhuang Jin Can <redacted> Date: Tue, 21 Jul 2015 17:20:30 +0300 Subject: xhci: prevent bus_suspend if SS port resuming in phase 1 From: Zhuang Jin Can <redacted> commit fac4271d1126c45ceaceb7f4a336317b771eb121 upstream. 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] Signed-off-by: Zhuang Jin Can <redacted> Signed-off-by: Mathias Nyman <redacted> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> --- drivers/usb/host/xhci-hub.c | 6 +++--- drivers/usb/host/xhci-ring.c | 3 +++ drivers/usb/host/xhci.h | 1 + 3 files changed, 7 insertions(+), 3 deletions(-)
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c@@ -1117,10 +1117,10 @@ int xhci_bus_suspend(struct usb_hcd *hcd spin_lock_irqsave(&xhci->lock, flags); if (hcd->self.root_hub->do_remote_wakeup) { - if (bus_state->resuming_ports) { + if (bus_state->resuming_ports || /* USB2 */ + bus_state->port_remote_wakeup) { /* USB3 */ spin_unlock_irqrestore(&xhci->lock, flags); - xhci_dbg(xhci, "suspend failed because " - "a port is resuming\n"); + xhci_dbg(xhci, "suspend failed because a port is resuming\n"); return -EBUSY; } } --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c
@@ -1740,6 +1740,9 @@ static void handle_port_status(struct xh usb_hcd_resume_root_hub(hcd); } + if (hcd->speed == HCD_USB3 && (temp & PORT_PLS_MASK) == XDEV_INACTIVE) + bus_state->port_remote_wakeup &= ~(1 << faked_port_index); + if ((temp & PORT_PLC) && (temp & PORT_PLS_MASK) == XDEV_RESUME) { xhci_dbg(xhci, "port resume event for port %d\n", port_id); --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h
@@ -285,6 +285,7 @@ struct xhci_op_regs { #define XDEV_U0 (0x0 << 5) #define XDEV_U2 (0x2 << 5) #define XDEV_U3 (0x3 << 5) +#define XDEV_INACTIVE (0x6 << 5) #define XDEV_RESUME (0xf << 5) /* true: port has power (see HCC_PPC) */ #define PORT_POWER (1 << 9)
Patches currently in stable-queue which might be from jin.can.zhuang@intel.com are queue-3.14/xhci-do-not-report-plc-when-link-is-in-internal-resume-state.patch queue-3.14/xhci-prevent-bus_suspend-if-ss-port-resuming-in-phase-1.patch queue-3.14/xhci-report-u3-when-link-is-in-resume-state.patch