blob: 8ad1e0afd26e354d908b9e1387ce8d50178bb33e [file] [log] [blame]
From a1e867e2f44fb386803ed2ee3541e62de66cfc1d Mon Sep 17 00:00:00 2001
From: Abhijeet Rao <abhijeet.rao@intel.corp-partner.google.com>
Date: Fri, 18 Mar 2022 02:56:36 +0000
Subject: [PATCH] Reland "FROMLIST: PCI/DPC: Disable DPC service when link is
in L2/L3 ready, L2 and L3 state"
This reverts commit c78ed2bbdacd3aa9d37d9c814ae839c0835f01fa.
Reason for revert: The hard hang issue will be fixed in CB. Hence these patches can be relanded
BUG=b:217419041
TEST=Connect Gatkex card and authorize it & run suspend_stress_test -c 10
Signed-off-by: Abhijeet Rao <abhijeet.rao@intel.corp-partner.google.com>
Original change's description:
> Revert "FROMLIST: PCI/DPC: Disable DPC service when link is in L2/L3 ready, L2 and L3 state"
>
> This reverts commit 93e7d232f85b0d597f8e9884386b9e3d43cedd3a.
>
> Reason for revert: debug patch : Causing regression with Soix, b/220796339
>
> BUG: b/220796339
>
> Original change's description:
> > FROMLIST: PCI/DPC: Disable DPC service when link is in L2/L3 ready, L2 and L3 state
> >
> > Since TLP and DLLP transmission is disabled for a Link in L2/L3 Ready,
> > L2 and L3 (i.e. device in D3hot and D3cold), and DPC depends on AER, so
> > also disable DPC here.
> >
> > Signed-off-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
> > Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> > (am from https://patchwork.kernel.org/patch/12726164/)
> > (also found at https://lore.kernel.org/r/20220127025418.1989642-2-kai.heng.feng@canonical.com)
> >
> > BUG=b:217419041
> > TEST=Connect Gatkex card and authorize it & run suspend_stress_test -c 10
> > . S0ix test passes 10 cycles
> >
> > Signed-off-by: Prashant Malani <pmalani@chromium.org>
> > Signed-off-by: George D Sworo <george.d.sworo@intel.com>
> > Change-Id: Idcadb2bcaf1421709ec13eb667c9d006e24cf3d5
> > Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/3437706
> > Reviewed-by: Sean Paul <seanpaul@chromium.org>
> > Reviewed-by: Rajat Jain <rajatja@google.com>
>
> Bug: b:217419041
> Change-Id: I889cb1fd1dba06ef1ccc6f76d3079651b52e528e
> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/3499774
> Reviewed-by: Rajat Jain <rajatja@google.com>
> Tested-by: Rajat Jain <rajatja@google.com>
> Commit-Queue: Rajat Jain <rajatja@google.com>
Bug: b:217419041
Change-Id: I3406f2fee4f2b5f7583528a5a3287fb29718c2e5
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/3535339
Reviewed-by: Sean Paul <seanpaul@chromium.org>
Reviewed-by: Rajat Jain <rajatja@google.com>
Commit-Queue: Rajat Jain <rajatja@google.com>
Tested-by: Rajat Jain <rajatja@google.com>
(cherry picked from commit 2336cd4cf7e1dfce9d956c4675fd9354144155fb)
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/3539623
---
drivers/pci/pcie/dpc.c | 62 ++++++++++++++++++++++++++++++------------
1 file changed, 44 insertions(+), 18 deletions(-)
diff --git a/drivers/pci/pcie/dpc.c b/drivers/pci/pcie/dpc.c
index 94111e4382413dc57ff10a079e1bdfc50c0e978e..354a7934ed3a66f2d76848285cfbd7e848231d55 100644
--- a/drivers/pci/pcie/dpc.c
+++ b/drivers/pci/pcie/dpc.c
@@ -358,13 +358,33 @@ void pci_dpc_init(struct pci_dev *pdev)
}
}
+static void dpc_enable(struct pcie_device *dev)
+{
+ struct pci_dev *pdev = dev->port;
+ u16 ctl;
+
+ pci_read_config_word(pdev, pdev->dpc_cap + PCI_EXP_DPC_CTL, &ctl);
+ ctl = (ctl & 0xfff4) | PCI_EXP_DPC_CTL_EN_FATAL | PCI_EXP_DPC_CTL_INT_EN;
+ pci_write_config_word(pdev, pdev->dpc_cap + PCI_EXP_DPC_CTL, ctl);
+}
+
+static void dpc_disable(struct pcie_device *dev)
+{
+ struct pci_dev *pdev = dev->port;
+ u16 ctl;
+
+ pci_read_config_word(pdev, pdev->dpc_cap + PCI_EXP_DPC_CTL, &ctl);
+ ctl &= ~(PCI_EXP_DPC_CTL_EN_FATAL | PCI_EXP_DPC_CTL_INT_EN);
+ pci_write_config_word(pdev, pdev->dpc_cap + PCI_EXP_DPC_CTL, ctl);
+}
+
#define FLAG(x, y) (((x) & (y)) ? '+' : '-')
static int dpc_probe(struct pcie_device *dev)
{
struct pci_dev *pdev = dev->port;
struct device *device = &dev->device;
int status;
- u16 ctl, cap;
+ u16 cap;
if (!pcie_aer_is_native(pdev) && !pcie_ports_dpc_native)
return -ENOTSUPP;
@@ -379,12 +399,7 @@ static int dpc_probe(struct pcie_device *dev)
}
pci_read_config_word(pdev, pdev->dpc_cap + PCI_EXP_DPC_CAP, &cap);
-
- pci_read_config_word(pdev, pdev->dpc_cap + PCI_EXP_DPC_CTL, &ctl);
- ctl &= ~PCI_EXP_DPC_CTL_EN_MASK;
- ctl |= PCI_EXP_DPC_CTL_EN_FATAL | PCI_EXP_DPC_CTL_INT_EN;
- pci_write_config_word(pdev, pdev->dpc_cap + PCI_EXP_DPC_CTL, ctl);
-
+ dpc_enable(dev);
pci_info(pdev, "enabled with IRQ %d\n", dev->irq);
pci_info(pdev, "error containment capabilities: Int Msg #%d, RPExt%c PoisonedTLP%c SwTrigger%c RP PIO Log %d, DL_ActiveErr%c\n",
cap & PCI_EXP_DPC_IRQ, FLAG(cap, PCI_EXP_DPC_CAP_RP_EXT),
@@ -396,22 +411,33 @@ static int dpc_probe(struct pcie_device *dev)
return status;
}
-static void dpc_remove(struct pcie_device *dev)
+static int dpc_suspend(struct pcie_device *dev)
{
- struct pci_dev *pdev = dev->port;
- u16 ctl;
+ dpc_disable(dev);
+ return 0;
+}
- pci_read_config_word(pdev, pdev->dpc_cap + PCI_EXP_DPC_CTL, &ctl);
- ctl &= ~(PCI_EXP_DPC_CTL_EN_FATAL | PCI_EXP_DPC_CTL_INT_EN);
- pci_write_config_word(pdev, pdev->dpc_cap + PCI_EXP_DPC_CTL, ctl);
+static int dpc_resume(struct pcie_device *dev)
+{
+ dpc_enable(dev);
+ return 0;
+}
+
+static void dpc_remove(struct pcie_device *dev)
+{
+ dpc_disable(dev);
}
static struct pcie_port_service_driver dpcdriver = {
- .name = "dpc",
- .port_type = PCIE_ANY_PORT,
- .service = PCIE_PORT_SERVICE_DPC,
- .probe = dpc_probe,
- .remove = dpc_remove,
+ .name = "dpc",
+ .port_type = PCIE_ANY_PORT,
+ .service = PCIE_PORT_SERVICE_DPC,
+ .probe = dpc_probe,
+ .suspend = dpc_suspend,
+ .resume = dpc_resume,
+ .runtime_suspend = dpc_suspend,
+ .runtime_resume = dpc_resume,
+ .remove = dpc_remove,
};
int __init pcie_dpc_init(void)
--
2.43.0.rc2.451.g8631bc7472-goog