diff options
-rw-r--r-- | drivers/acpi/pci_mcfg.c | 11 | ||||
-rw-r--r-- | drivers/pci/ecam.c | 12 | ||||
-rw-r--r-- | include/linux/pci-ecam.h | 4 |
3 files changed, 27 insertions, 0 deletions
diff --git a/drivers/acpi/pci_mcfg.c b/drivers/acpi/pci_mcfg.c index 1ef72857b710..cee33b078d3d 100644 --- a/drivers/acpi/pci_mcfg.c +++ b/drivers/acpi/pci_mcfg.c @@ -51,6 +51,17 @@ struct mcfg_fixup { static struct mcfg_fixup mcfg_quirks[] = { /* { OEM_ID, OEM_TABLE_ID, REV, SEGMENT, BUS_RANGE, ops, cfgres }, */ + +#define QCOM_ECAM32(seg) \ + { "QCOM ", "QDF2432 ", 1, seg, MCFG_BUS_ANY, &pci_32b_ops } + QCOM_ECAM32(0), + QCOM_ECAM32(1), + QCOM_ECAM32(2), + QCOM_ECAM32(3), + QCOM_ECAM32(4), + QCOM_ECAM32(5), + QCOM_ECAM32(6), + QCOM_ECAM32(7), }; static char mcfg_oem_id[ACPI_OEM_ID_SIZE]; diff --git a/drivers/pci/ecam.c b/drivers/pci/ecam.c index 43ed08dd8b01..2fee61bb6559 100644 --- a/drivers/pci/ecam.c +++ b/drivers/pci/ecam.c @@ -162,3 +162,15 @@ struct pci_ecam_ops pci_generic_ecam_ops = { .write = pci_generic_config_write, } }; + +#if defined(CONFIG_ACPI) && defined(CONFIG_PCI_QUIRKS) +/* ECAM ops for 32-bit access only (non-compliant) */ +struct pci_ecam_ops pci_32b_ops = { + .bus_shift = 20, + .pci_ops = { + .map_bus = pci_ecam_map_bus, + .read = pci_generic_config_read32, + .write = pci_generic_config_write32, + } +}; +#endif diff --git a/include/linux/pci-ecam.h b/include/linux/pci-ecam.h index 7adad206b1f4..739d2330fd9e 100644 --- a/include/linux/pci-ecam.h +++ b/include/linux/pci-ecam.h @@ -59,6 +59,10 @@ void __iomem *pci_ecam_map_bus(struct pci_bus *bus, unsigned int devfn, /* default ECAM ops */ extern struct pci_ecam_ops pci_generic_ecam_ops; +#if defined(CONFIG_ACPI) && defined(CONFIG_PCI_QUIRKS) +extern struct pci_ecam_ops pci_32b_ops; /* 32-bit accesses only */ +#endif + #ifdef CONFIG_PCI_HOST_GENERIC /* for DT-based PCI controllers that support ECAM */ int pci_host_common_probe(struct platform_device *pdev, |