Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a6987a4c authored by Lu Baolu's avatar Lu Baolu Committed by Sasha Levin
Browse files

usb: xhci: handle both SSIC ports in PME stuck quirk



[ Upstream commit fa89537783cb442263fa5a14df6c7693eaf32f11 ]

Commit abce329c27b3 ("xhci: Workaround to get D3 working in Intel xHCI")
adds a workaround for a limitation of PME storm caused by SSIC port in
some Intel SoCs. This commit only handled one SSIC port, while there
are actually two SSIC ports in the chips. This patch handles both SSIC
ports. Without this fix, users still see PME storm.

Cc: stable@vger.kernel.org # v4.2+
Signed-off-by: default avatarZhuang Jin Can <jin.can.zhuang@intel.com>
Signed-off-by: default avatarLu Baolu <baolu.lu@linux.intel.com>
Signed-off-by: default avatarMathias Nyman <mathias.nyman@linux.intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: default avatarSasha Levin <sasha.levin@oracle.com>
parent 469a43f8
Loading
Loading
Loading
Loading
+29 −19
Original line number Diff line number Diff line
@@ -28,7 +28,9 @@
#include "xhci.h"
#include "xhci-trace.h"

#define PORT2_SSIC_CONFIG_REG2	0x883c
#define SSIC_PORT_NUM		2
#define SSIC_PORT_CFG2		0x880c
#define SSIC_PORT_CFG2_OFFSET	0x30
#define PROG_DONE		(1 << 30)
#define SSIC_PORT_UNUSED	(1 << 31)

@@ -317,13 +319,20 @@ static void xhci_pme_quirk(struct usb_hcd *hcd, bool suspend)
	struct pci_dev		*pdev = to_pci_dev(hcd->self.controller);
	u32 val;
	void __iomem *reg;
	int i;

	if (pdev->vendor == PCI_VENDOR_ID_INTEL &&
		 pdev->device == PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI) {

		reg = (void __iomem *) xhci->cap_regs + PORT2_SSIC_CONFIG_REG2;
		for (i = 0; i < SSIC_PORT_NUM; i++) {
			reg = (void __iomem *) xhci->cap_regs +
					SSIC_PORT_CFG2 +
					i * SSIC_PORT_CFG2_OFFSET;

		/* Notify SSIC that SSIC profile programming is not done */
			/*
			 * Notify SSIC that SSIC profile programming
			 * is not done.
			 */
			val = readl(reg) & ~PROG_DONE;
			writel(val, reg);

@@ -340,6 +349,7 @@ static void xhci_pme_quirk(struct usb_hcd *hcd, bool suspend)
			writel(val, reg);
			readl(reg);
		}
	}

	reg = (void __iomem *) xhci->cap_regs + 0x80a4;
	val = readl(reg);