From: Ganesan Ramalingam <ganesanr@broadcom.com>
MSI interrupts do not work on XLS after commit a776c49, because
the change disables MSI interrupts on the XLS PCIe bridges at boot-up.
Fix this by enabling MSI interrupts on the bridge in the
arch_setup_msi_irq() function. Earlier, this was done from firmware
and we did not need to change the configuration in linux.
Signed-off-by: Ganesan Ramalingam <ganesanr@broadcom.com>
Signed-off-by: Jayachandran C <jayachandranc@netlogicmicro.com>
---
arch/mips/pci/pci-xlr.c | 30 +++++++++++++++++++++++++-----
1 file changed, 25 insertions(+), 5 deletions(-)
diff --git a/arch/mips/pci/pci-xlr.c b/arch/mips/pci/pci-xlr.c
index 50ff4dc..003e053 100644
--- a/arch/mips/pci/pci-xlr.c
+++ b/arch/mips/pci/pci-xlr.c
@@ -41,6 +41,7 @@
#include <linux/irq.h>
#include <linux/irqdesc.h>
#include <linux/console.h>
+#include <linux/pci_regs.h>
#include <asm/io.h>
@@ -168,17 +169,17 @@ static int get_irq_vector(const struct pci_dev *dev)
if (dev->bus->self == NULL)
return 0;
- switch (dev->bus->self->devfn) {
- case 0x0:
+ switch (PCI_SLOT(dev->bus->self->devfn)) {
+ case 0:
return PIC_PCIE_LINK0_IRQ;
- case 0x8:
+ case 1:
return PIC_PCIE_LINK1_IRQ;
- case 0x10:
+ case 2:
if (nlm_chip_is_xls_b())
return PIC_PCIE_XLSB0_LINK2_IRQ;
else
return PIC_PCIE_LINK2_IRQ;
- case 0x18:
+ case 3:
if (nlm_chip_is_xls_b())
return PIC_PCIE_XLSB0_LINK3_IRQ;
else
@@ -202,7 +203,26 @@ void arch_teardown_msi_irq(unsigned int irq)
int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
{
struct msi_msg msg;
+ struct pci_bus *bus, *p;
int irq, ret;
+ u16 val;
+
+ /* Find the bridge on bus 0 */
+ bus = dev->bus;
+ for (p = bus->parent; p && p->number != 0; p = p->parent)
+ bus = p;
+ if (p == NULL)
+ return 1;
+
+ /*
+ * Enable MSI which was disabled at enumeration, the bridge
+ * MSI capability is at 0x50
+ */
+ pci_read_config_word(bus->self, 0x50 + PCI_MSI_FLAGS, &val);
+ if ((val & PCI_MSI_FLAGS_ENABLE) == 0) {
+ val |= PCI_MSI_FLAGS_ENABLE;
+ pci_write_config_word(bus->self, 0x50 + PCI_MSI_FLAGS, val);
+ }
irq = get_irq_vector(dev);
if (irq <= 0)
--
1.7.9.5
|