diff --git a/arch/arm/include/asm/mach/pci.h b/arch/arm/include/asm/mach/pci.h
index 7fc4278..59b0d87 100644
--- a/arch/arm/include/asm/mach/pci.h
+++ b/arch/arm/include/asm/mach/pci.h
@@ -22,6 +22,9 @@ struct hw_pci {
#ifdef CONFIG_PCI_DOMAINS
int domain;
#endif
+#ifdef CONFIG_PCI_MSI
+ struct msi_chip *msi_chip;
+#endif
struct pci_ops *ops;
int nr_controllers;
void **private_data;@@ -47,6 +50,9 @@ struct pci_sys_data {
#ifdef CONFIG_PCI_DOMAINS
int domain;
#endif
+#ifdef CONFIG_PCI_MSI
+ struct msi_chip *msi_chip;
+#endif
struct list_head node;
int busnr; /* primary bus number */
u64 mem_offset; /* bus->cpu memory mapping offset */diff --git a/arch/arm/include/asm/pci.h b/arch/arm/include/asm/pci.h
index 7e95d85..b562c09 100644
--- a/arch/arm/include/asm/pci.h
+++ b/arch/arm/include/asm/pci.h
@@ -31,6 +31,15 @@ static inline int pci_proc_domain(struct pci_bus *bus)
}
#endif /* CONFIG_PCI_DOMAINS */
+#ifdef CONFIG_PCI_MSI
+static inline struct msi_chip *pci_msi_chip(struct pci_bus *bus)
+{
+ struct pci_sys_data *root = bus->sysdata;
+
+ return root->msi_chip;
+}
+#endif
+
/*
* The PCI address space does equal the physical memory address space.
* The networking and block device layers use this boolean for bouncediff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
index 17a26c1..a19038d 100644
--- a/arch/arm/kernel/bios32.c
+++ b/arch/arm/kernel/bios32.c
@@ -471,6 +471,9 @@ static void pcibios_init_hw(struct device *parent, struct hw_pci *hw,
#ifdef CONFIG_PCI_DOMAINS
sys->domain = hw->domain;
#endif
+#ifdef CONFIG_PCI_MSI
+ sys->msi_chip = hw->msi_chip;
+#endif
sys->busnr = busnr;
sys->swizzle = hw->swizzle;
sys->map_irq = hw->map_irq;
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 22e413c..f11108c 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -35,6 +35,9 @@ int __weak arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
struct msi_chip *chip = dev->bus->msi;
int err;
+ if (!chip)
+ chip = pci_msi_chip(dev->bus);
+
if (!chip || !chip->setup_irq)
return -EINVAL;
@@ -50,6 +53,9 @@ void __weak arch_teardown_msi_irq(unsigned int irq)
struct msi_desc *entry = irq_get_msi_desc(irq);
struct msi_chip *chip = entry->dev->bus->msi;
+ if (!chip)
+ chip = pci_msi_chip(entry->dev->bus);
+
if (!chip || !chip->teardown_irq)
return;
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 9cd2721..7a48b40 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1433,6 +1433,15 @@ static inline int pci_get_new_domain_nr(void) { return -ENOSYS; }
#include <asm/pci.h>
+/* Just avoid compile error, will be clean up later */
+#ifdef CONFIG_PCI_MSI
+
+#ifndef pci_msi_chip
+#define pci_msi_chip(bus) NULL
+#endif
+#endif