patch "xhci: prevent bus_suspend if SS port resuming in phase 1" added to usb-linus
Subsystems (3)
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 my usb git tree which can be found at
git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git
in the usb-linus branch.
The patch will show up in the next release of the linux-next tree (usually sometime within the next 24 hours during the week.)
The patch will hopefully also be merged in Linus's tree for the next -rc kernel release.
If you have any questions about this process, please let me know.
Quoted 1 line
From
fac4271d1126c45ceaceb7f4a336317b771eb121Mon Sep 17 00:00:00 2001
From: Zhuang Jin Can <[email protected]>
Date: Tue, 21 Jul 2015 17:20:30 +0300
Subject: xhci: prevent bus_suspend if SS port resuming in phase 1
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.
--- 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(-)
drivers/usb/host/xhci-hub.c +3 -3
@@ -1123,10 +1123,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 ; } }
drivers/usb/host/xhci-ring.c +3 -0
@@ -1546,6 +1546,9 @@ static void handle_port_status(struct xhci_hcd *xhci,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);
drivers/usb/host/xhci.h +1 -0
@@ -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)
Signature · 1 line
2.4.6