From: Zhao Qunqin zhaoqunqin@loongson.cn
LoongArch inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/IBENRY CVE: NA
--------------------------------
The CPU may not be able to access the PCI header of the device if it is in low-power mode.
Signed-off-by: Zhao Qunqin zhaoqunqin@loongson.cn --- drivers/pci/quirks.c | 30 ++++++++++++++++++++++++++++++ include/linux/pci.h | 1 + 2 files changed, 31 insertions(+)
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index b8a8fbf15cdc..a86e7d791b7a 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -410,6 +410,36 @@ static void loongson_pcie_msi_quirk(struct pci_dev *dev) } DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LOONGSON, 0x7a59, loongson_pcie_msi_quirk);
+#define DEV_PCIE_PORT_4 0x7a39 +#define DEV_PCIE_PORT_5 0x7a49 +#define DEV_PCIE_PORT_6 0x7a59 +#define DEV_PCIE_PORT_7 0x7a69 +static void loongson_d3_and_link_quirk(struct pci_dev *dev) +{ + struct pci_bus *bus = dev->bus; + struct pci_dev *bridge; + static const struct pci_device_id bridge_devids[] = { + { PCI_VDEVICE(LOONGSON, DEV_PCIE_PORT_4) }, + { PCI_VDEVICE(LOONGSON, DEV_PCIE_PORT_5) }, + { PCI_VDEVICE(LOONGSON, DEV_PCIE_PORT_6) }, + { PCI_VDEVICE(LOONGSON, DEV_PCIE_PORT_7) }, + { 0, }, + }; + + /* look for the matching bridge */ + while (!pci_is_root_bus(bus)) { + bridge = bus->self; + bus = bus->parent; + if (bridge && pci_match_id(bridge_devids, bridge)) { + dev->dev_flags |= (PCI_DEV_FLAGS_NO_D3 | + PCI_DEV_FLAGS_NO_LINK_SPEED_CHANGE); + dev->no_d1d2 = 1; + break; + } + } +} +DECLARE_PCI_FIXUP_ENABLE(PCI_ANY_ID, PCI_ANY_ID, loongson_d3_and_link_quirk); + /* Chipsets where PCI->PCI transfers vanish or hang */ static void quirk_nopcipci(struct pci_dev *dev) { diff --git a/include/linux/pci.h b/include/linux/pci.h index 3eb0e343c16c..645229577081 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -246,6 +246,7 @@ enum pci_dev_flags { PCI_DEV_FLAGS_NO_RELAXED_ORDERING = (__force pci_dev_flags_t) (1 << 11), /* Device does honor MSI masking despite saying otherwise */ PCI_DEV_FLAGS_HAS_MSI_MASKING = (__force pci_dev_flags_t) (1 << 12), + PCI_DEV_FLAGS_NO_LINK_SPEED_CHANGE = (__force pci_dev_flags_t) (1 << 15), };
enum pci_irq_reroute_variant {