Some platform devices appear as PCI but are actually on the AMBA bus,
and they need fixup in drivers/pci/quirks.c handling iommu_fwnode.
Here introducing PCI_FIXUP_IOMMU, which is called after iommu_fwnode
is allocated, instead of reusing PCI_FIXUP_FINAL since it will slow
down iommu probing as all devices in fixup final list will be
reprocessed.

Suggested-by: Joerg Roedel <j...@8bytes.org>
Signed-off-by: Zhangfei Gao <zhangfei....@linaro.org>
---
 drivers/pci/quirks.c              | 7 +++++++
 include/asm-generic/vmlinux.lds.h | 3 +++
 include/linux/pci.h               | 8 ++++++++
 3 files changed, 18 insertions(+)

diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index ca9ed57..b037034 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -83,6 +83,8 @@ extern struct pci_fixup __start_pci_fixups_header[];
 extern struct pci_fixup __end_pci_fixups_header[];
 extern struct pci_fixup __start_pci_fixups_final[];
 extern struct pci_fixup __end_pci_fixups_final[];
+extern struct pci_fixup __start_pci_fixups_iommu[];
+extern struct pci_fixup __end_pci_fixups_iommu[];
 extern struct pci_fixup __start_pci_fixups_enable[];
 extern struct pci_fixup __end_pci_fixups_enable[];
 extern struct pci_fixup __start_pci_fixups_resume[];
@@ -118,6 +120,11 @@ void pci_fixup_device(enum pci_fixup_pass pass, struct 
pci_dev *dev)
                end = __end_pci_fixups_final;
                break;
 
+       case pci_fixup_iommu:
+               start = __start_pci_fixups_iommu;
+               end = __end_pci_fixups_iommu;
+               break;
+
        case pci_fixup_enable:
                start = __start_pci_fixups_enable;
                end = __end_pci_fixups_enable;
diff --git a/include/asm-generic/vmlinux.lds.h 
b/include/asm-generic/vmlinux.lds.h
index 71e387a..3da32d8 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -411,6 +411,9 @@
                __start_pci_fixups_final = .;                           \
                KEEP(*(.pci_fixup_final))                               \
                __end_pci_fixups_final = .;                             \
+               __start_pci_fixups_iommu = .;                           \
+               KEEP(*(.pci_fixup_iommu))                               \
+               __end_pci_fixups_iommu = .;                             \
                __start_pci_fixups_enable = .;                          \
                KEEP(*(.pci_fixup_enable))                              \
                __end_pci_fixups_enable = .;                            \
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 83ce1cd..0d5fbf8 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1892,6 +1892,7 @@ enum pci_fixup_pass {
        pci_fixup_early,        /* Before probing BARs */
        pci_fixup_header,       /* After reading configuration header */
        pci_fixup_final,        /* Final phase of device fixups */
+       pci_fixup_iommu,        /* After iommu_fwspec_init */
        pci_fixup_enable,       /* pci_enable_device() time */
        pci_fixup_resume,       /* pci_device_resume() */
        pci_fixup_suspend,      /* pci_device_suspend() */
@@ -1934,6 +1935,10 @@ enum pci_fixup_pass {
                                         class_shift, hook)             \
        DECLARE_PCI_FIXUP_SECTION(.pci_fixup_final,                     \
                hook, vendor, device, class, class_shift, hook)
+#define DECLARE_PCI_FIXUP_CLASS_IOMMU(vendor, device, class,           \
+                                        class_shift, hook)             \
+       DECLARE_PCI_FIXUP_SECTION(.pci_fixup_iommu,                     \
+               hook, vendor, device, class, class_shift, hook)
 #define DECLARE_PCI_FIXUP_CLASS_ENABLE(vendor, device, class,          \
                                         class_shift, hook)             \
        DECLARE_PCI_FIXUP_SECTION(.pci_fixup_enable,                    \
@@ -1964,6 +1969,9 @@ enum pci_fixup_pass {
 #define DECLARE_PCI_FIXUP_FINAL(vendor, device, hook)                  \
        DECLARE_PCI_FIXUP_SECTION(.pci_fixup_final,                     \
                hook, vendor, device, PCI_ANY_ID, 0, hook)
+#define DECLARE_PCI_FIXUP_IOMMU(vendor, device, hook)                  \
+       DECLARE_PCI_FIXUP_SECTION(.pci_fixup_iommu,                     \
+               hook, vendor, device, PCI_ANY_ID, 0, hook)
 #define DECLARE_PCI_FIXUP_ENABLE(vendor, device, hook)                 \
        DECLARE_PCI_FIXUP_SECTION(.pci_fixup_enable,                    \
                hook, vendor, device, PCI_ANY_ID, 0, hook)
-- 
2.7.4

Reply via email to