All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/3] xhci: add restart quirk for Intel Wildcatpoint PCH
       [not found] <1476976160-13230-1-git-send-email-mathias.nyman@linux.intel.com>
@ 2016-10-20 15:09 ` Mathias Nyman
  2016-10-20 15:09 ` [PATCH 2/3] xhci: workaround for hosts missing CAS bit Mathias Nyman
  2016-10-20 15:09 ` [PATCH 3/3] xhci: use default USB_RESUME_TIMEOUT when resuming ports Mathias Nyman
  2 siblings, 0 replies; 3+ messages in thread
From: Mathias Nyman @ 2016-10-20 15:09 UTC (permalink / raw)
  To: gregkh; +Cc: linux-usb, jagadish.krishnamoorthy, Mathias Nyman, stable

xHC in Wildcatpoint-LP PCH is similar to LynxPoint-LP and need the
same quirks to prevent machines from spurious restart while
shutting them down.

Reported-by: Hasan Mahmood <hasan.mahm@gmail.com>
CC: <stable@vger.kernel.org>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
---
 drivers/usb/host/xhci-pci.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index d7b0f97..314179b 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -45,6 +45,7 @@
 
 #define PCI_DEVICE_ID_INTEL_LYNXPOINT_XHCI	0x8c31
 #define PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI	0x9c31
+#define PCI_DEVICE_ID_INTEL_WILDCATPOINT_LP_XHCI	0x9cb1
 #define PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI		0x22b5
 #define PCI_DEVICE_ID_INTEL_SUNRISEPOINT_H_XHCI		0xa12f
 #define PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_XHCI	0x9d2f
@@ -153,7 +154,8 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
 		xhci->quirks |= XHCI_SPURIOUS_REBOOT;
 	}
 	if (pdev->vendor == PCI_VENDOR_ID_INTEL &&
-		pdev->device == PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI) {
+		(pdev->device == PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI ||
+		 pdev->device == PCI_DEVICE_ID_INTEL_WILDCATPOINT_LP_XHCI)) {
 		xhci->quirks |= XHCI_SPURIOUS_REBOOT;
 		xhci->quirks |= XHCI_SPURIOUS_WAKEUP;
 	}
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH 2/3] xhci: workaround for hosts missing CAS bit
       [not found] <1476976160-13230-1-git-send-email-mathias.nyman@linux.intel.com>
  2016-10-20 15:09 ` [PATCH 1/3] xhci: add restart quirk for Intel Wildcatpoint PCH Mathias Nyman
@ 2016-10-20 15:09 ` Mathias Nyman
  2016-10-20 15:09 ` [PATCH 3/3] xhci: use default USB_RESUME_TIMEOUT when resuming ports Mathias Nyman
  2 siblings, 0 replies; 3+ messages in thread
From: Mathias Nyman @ 2016-10-20 15:09 UTC (permalink / raw)
  To: gregkh; +Cc: linux-usb, jagadish.krishnamoorthy, Mathias Nyman, stable

If a device is unplugged and replugged during Sx system suspend
some  Intel xHC hosts will overwrite the CAS (Cold attach status) flag
and no device connection is noticed in resume.

A device in this state can be identified in resume if its link state
is in polling or compliance mode, and the current connect status is 0.
A device in this state needs to be warm reset.

Intel 100/c230 series PCH specification update Doc #332692-006 Errata #8

Observed on Cherryview and Apollolake as they go into compliance mode
if LFPS times out during polling, and re-plugged devices are not
discovered at resume.

Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
CC: <stable@vger.kernel.org>
---
 drivers/usb/host/xhci-hub.c | 37 +++++++++++++++++++++++++++++++++++++
 drivers/usb/host/xhci-pci.c |  6 ++++++
 drivers/usb/host/xhci.h     |  3 +++
 3 files changed, 46 insertions(+)

diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index 730b9fd..c047362 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -1355,6 +1355,35 @@ int xhci_bus_suspend(struct usb_hcd *hcd)
 	return 0;
 }
 
+/*
+ * Workaround for missing Cold Attach Status (CAS) if device re-plugged in S3.
+ * warm reset a USB3 device stuck in polling or compliance mode after resume.
+ * See Intel 100/c230 series PCH specification update Doc #332692-006 Errata #8
+ */
+static bool xhci_port_missing_cas_quirk(int port_index,
+					     __le32 __iomem **port_array)
+{
+	u32 portsc;
+
+	portsc = readl(port_array[port_index]);
+
+	/* if any of these are set we are not stuck */
+	if (portsc & (PORT_CONNECT | PORT_CAS))
+		return false;
+
+	if (((portsc & PORT_PLS_MASK) != XDEV_POLLING) &&
+	    ((portsc & PORT_PLS_MASK) != XDEV_COMP_MODE))
+		return false;
+
+	/* clear wakeup/change bits, and do a warm port reset */
+	portsc &= ~(PORT_RWC_BITS | PORT_CEC | PORT_WAKE_BITS);
+	portsc |= PORT_WR;
+	writel(portsc, port_array[port_index]);
+	/* flush write */
+	readl(port_array[port_index]);
+	return true;
+}
+
 int xhci_bus_resume(struct usb_hcd *hcd)
 {
 	struct xhci_hcd	*xhci = hcd_to_xhci(hcd);
@@ -1392,6 +1421,14 @@ int xhci_bus_resume(struct usb_hcd *hcd)
 		u32 temp;
 
 		temp = readl(port_array[port_index]);
+
+		/* warm reset CAS limited ports stuck in polling/compliance */
+		if ((xhci->quirks & XHCI_MISSING_CAS) &&
+		    (hcd->speed >= HCD_USB3) &&
+		    xhci_port_missing_cas_quirk(port_index, port_array)) {
+			xhci_dbg(xhci, "reset stuck port %d\n", port_index);
+			continue;
+		}
 		if (DEV_SUPERSPEED_ANY(temp))
 			temp &= ~(PORT_RWC_BITS | PORT_CEC | PORT_WAKE_BITS);
 		else
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index 314179b..e96ae80 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -51,6 +51,7 @@
 #define PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_XHCI	0x9d2f
 #define PCI_DEVICE_ID_INTEL_BROXTON_M_XHCI		0x0aa8
 #define PCI_DEVICE_ID_INTEL_BROXTON_B_XHCI		0x1aa8
+#define PCI_DEVICE_ID_INTEL_APL_XHCI			0x5aa8
 
 static const char hcd_name[] = "xhci_hcd";
 
@@ -171,6 +172,11 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
 		 pdev->device == PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI) {
 		xhci->quirks |= XHCI_SSIC_PORT_UNUSED;
 	}
+	if (pdev->vendor == PCI_VENDOR_ID_INTEL &&
+	    (pdev->device == PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI ||
+	     pdev->device == PCI_DEVICE_ID_INTEL_APL_XHCI))
+		xhci->quirks |= XHCI_MISSING_CAS;
+
 	if (pdev->vendor == PCI_VENDOR_ID_ETRON &&
 			pdev->device == PCI_DEVICE_ID_EJ168) {
 		xhci->quirks |= XHCI_RESET_ON_RESUME;
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index b2c1dc5..f945380 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -314,6 +314,8 @@ struct xhci_op_regs {
 #define XDEV_U2		(0x2 << 5)
 #define XDEV_U3		(0x3 << 5)
 #define XDEV_INACTIVE	(0x6 << 5)
+#define XDEV_POLLING	(0x7 << 5)
+#define XDEV_COMP_MODE  (0xa << 5)
 #define XDEV_RESUME	(0xf << 5)
 /* true: port has power (see HCC_PPC) */
 #define PORT_POWER	(1 << 9)
@@ -1653,6 +1655,7 @@ struct xhci_hcd {
 #define XHCI_MTK_HOST		(1 << 21)
 #define XHCI_SSIC_PORT_UNUSED	(1 << 22)
 #define XHCI_NO_64BIT_SUPPORT	(1 << 23)
+#define XHCI_MISSING_CAS	(1 << 24)
 	unsigned int		num_active_eps;
 	unsigned int		limit_active_eps;
 	/* There are two roothubs to keep track of bus suspend info for */
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH 3/3] xhci: use default USB_RESUME_TIMEOUT when resuming ports.
       [not found] <1476976160-13230-1-git-send-email-mathias.nyman@linux.intel.com>
  2016-10-20 15:09 ` [PATCH 1/3] xhci: add restart quirk for Intel Wildcatpoint PCH Mathias Nyman
  2016-10-20 15:09 ` [PATCH 2/3] xhci: workaround for hosts missing CAS bit Mathias Nyman
@ 2016-10-20 15:09 ` Mathias Nyman
  2 siblings, 0 replies; 3+ messages in thread
From: Mathias Nyman @ 2016-10-20 15:09 UTC (permalink / raw)
  To: gregkh; +Cc: linux-usb, jagadish.krishnamoorthy, Mathias Nyman, stable

USB2 host inititated resume, and system suspend bus resume
need to use the same USB_RESUME_TIMEOUT as elsewhere.

This resolves a device disconnect issue at system resume seen
on Intel Braswell and Apollolake, but is in no way limited to
those platforms.

Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
CC: <stable@vger.kernel.org>
---
 drivers/usb/host/xhci-hub.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index c047362..0ef1690 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -1166,7 +1166,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
 				xhci_set_link_state(xhci, port_array, wIndex,
 							XDEV_RESUME);
 				spin_unlock_irqrestore(&xhci->lock, flags);
-				msleep(20);
+				msleep(USB_RESUME_TIMEOUT);
 				spin_lock_irqsave(&xhci->lock, flags);
 				xhci_set_link_state(xhci, port_array, wIndex,
 							XDEV_U0);
@@ -1447,7 +1447,7 @@ int xhci_bus_resume(struct usb_hcd *hcd)
 
 	if (need_usb2_u3_exit) {
 		spin_unlock_irqrestore(&xhci->lock, flags);
-		msleep(20);
+		msleep(USB_RESUME_TIMEOUT);
 		spin_lock_irqsave(&xhci->lock, flags);
 	}
 
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2016-10-20 15:09 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <1476976160-13230-1-git-send-email-mathias.nyman@linux.intel.com>
2016-10-20 15:09 ` [PATCH 1/3] xhci: add restart quirk for Intel Wildcatpoint PCH Mathias Nyman
2016-10-20 15:09 ` [PATCH 2/3] xhci: workaround for hosts missing CAS bit Mathias Nyman
2016-10-20 15:09 ` [PATCH 3/3] xhci: use default USB_RESUME_TIMEOUT when resuming ports Mathias Nyman

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.