From: Mark Salter msalter@redhat.com
The current code provides placeholder weak functions for for raw_pci_read() and raw_pci_write(). This patch creates a global 'raw_pci_ops' variable which points to a struct containing read and write ops. The weak attribute is removed from raw_pci_read() and raw_pci_write() which will use the ops provided by the raw_pci_ops pointer.
Signed-off-by: Mark Salter msalter@redhat.com --- arch/arm64/include/asm/pci.h | 9 +++++++++ arch/arm64/pci/pci.c | 20 ++++++++++++++------ 2 files changed, 23 insertions(+), 6 deletions(-)
diff --git a/arch/arm64/include/asm/pci.h b/arch/arm64/include/asm/pci.h index fded096..9e23df3 100644 --- a/arch/arm64/include/asm/pci.h +++ b/arch/arm64/include/asm/pci.h @@ -39,5 +39,14 @@ static inline int pci_proc_domain(struct pci_bus *bus) } #endif /* CONFIG_PCI */
+struct pci_raw_ops { + int (*read)(unsigned int domain, unsigned int bus, unsigned int devfn, + int reg, int len, u32 *val); + int (*write)(unsigned int domain, unsigned int bus, unsigned int devfn, + int reg, int len, u32 val); +}; + +extern const struct pci_raw_ops *raw_pci_ops; + #endif /* __KERNEL__ */ #endif /* __ASM_PCI_H */ diff --git a/arch/arm64/pci/pci.c b/arch/arm64/pci/pci.c index b03b0eb..35d99b3 100644 --- a/arch/arm64/pci/pci.c +++ b/arch/arm64/pci/pci.c @@ -3,22 +3,30 @@ #include <linux/kernel.h> #include <linux/pci.h>
+const struct pci_raw_ops *__read_mostly raw_pci_ops; + /** * raw_pci_read - Platform-specific PCI config space access. * * Default empty implementation. Replace with an architecture-specific setup * routine, if necessary. */ -int __weak raw_pci_read(unsigned int domain, unsigned int bus, - unsigned int devfn, int reg, int len, u32 *val) +int raw_pci_read(unsigned int domain, unsigned int bus, + unsigned int devfn, int reg, int len, u32 *val) { - return -EINVAL; + if (!raw_pci_ops) + return -EINVAL; + + return raw_pci_ops->read(domain, bus, devfn, reg, len, val); }
-int __weak raw_pci_write(unsigned int domain, unsigned int bus, - unsigned int devfn, int reg, int len, u32 val) +int raw_pci_write(unsigned int domain, unsigned int bus, + unsigned int devfn, int reg, int len, u32 val) { - return -EINVAL; + if (!raw_pci_ops) + return -EINVAL; + + return raw_pci_ops->write(domain, bus, devfn, reg, len, val); }
/* Root bridge scanning */