mirror of
https://github.com/raspberrypi/linux.git
synced 2025-12-06 01:49:46 +00:00
usb: xhci: handle both SSIC ports in PME stuck quirk
commitfa89537783upstream. Commitabce329c27("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. Signed-off-by: Zhuang Jin Can <jin.can.zhuang@intel.com> Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com> Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
7ab0e9d0a2
commit
bfa2ee5ddf
@@ -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)
|
||||
|
||||
@@ -322,28 +324,36 @@ 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 */
|
||||
val = readl(reg) & ~PROG_DONE;
|
||||
writel(val, reg);
|
||||
/*
|
||||
* Notify SSIC that SSIC profile programming
|
||||
* is not done.
|
||||
*/
|
||||
val = readl(reg) & ~PROG_DONE;
|
||||
writel(val, reg);
|
||||
|
||||
/* Mark SSIC port as unused(suspend) or used(resume) */
|
||||
val = readl(reg);
|
||||
if (suspend)
|
||||
val |= SSIC_PORT_UNUSED;
|
||||
else
|
||||
val &= ~SSIC_PORT_UNUSED;
|
||||
writel(val, reg);
|
||||
/* Mark SSIC port as unused(suspend) or used(resume) */
|
||||
val = readl(reg);
|
||||
if (suspend)
|
||||
val |= SSIC_PORT_UNUSED;
|
||||
else
|
||||
val &= ~SSIC_PORT_UNUSED;
|
||||
writel(val, reg);
|
||||
|
||||
/* Notify SSIC that SSIC profile programming is done */
|
||||
val = readl(reg) | PROG_DONE;
|
||||
writel(val, reg);
|
||||
readl(reg);
|
||||
/* Notify SSIC that SSIC profile programming is done */
|
||||
val = readl(reg) | PROG_DONE;
|
||||
writel(val, reg);
|
||||
readl(reg);
|
||||
}
|
||||
}
|
||||
|
||||
reg = (void __iomem *) xhci->cap_regs + 0x80a4;
|
||||
|
||||
Reference in New Issue
Block a user