[PATCH 02/12] MIPS: Netlogic: MSI enable fix for XLS

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Ganesan Ramalingam <ganesanr@xxxxxxxxxxxx>

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@xxxxxxxxxxxx>
Signed-off-by: Jayachandran C <jayachandranc@xxxxxxxxxxxxxxxxx>
---
 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





[Index of Archives]     [Linux MIPS Home]     [LKML Archive]     [Linux ARM Kernel]     [Linux ARM]     [Linux]     [Git]     [Yosemite News]     [Linux SCSI]     [Linux Hams]

  Powered by Linux