]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
MIPS: PCI: Support mapping of INTB/C/D for pci-xtalk-bridge
authorThomas Bogendoerfer <tbogendoerfer@suse.de>
Thu, 9 Jan 2020 10:34:27 +0000 (11:34 +0100)
committerPaul Burton <paulburton@kernel.org>
Thu, 9 Jan 2020 23:30:53 +0000 (15:30 -0800)
Implented mapping of PCI INTB/C/D, which is needed for PCI multifunction
devices, PCI-PCI bridges and IOC3.

Signed-off-by: Thomas Bogendoerfer <tbogendoerfer@suse.de>
Signed-off-by: Paul Burton <paulburton@kernel.org>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: James Hogan <jhogan@kernel.org>
Cc: linux-mips@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
arch/mips/include/asm/pci/bridge.h
arch/mips/pci/pci-xtalk-bridge.c

index 3bc630ff9ad46c0a141de35bb661af5257d6607c..9c476a0400e0c3365f73ec4cbbc5e0a640e286ff 100644 (file)
@@ -806,7 +806,8 @@ struct bridge_controller {
        unsigned long           baddr;
        unsigned long           intr_addr;
        struct irq_domain       *domain;
-       unsigned int            pci_int[8];
+       unsigned int            pci_int[8][2];
+       unsigned int            int_mapping[8][2];
        u32                     ioc3_sid[8];
        nasid_t                 nasid;
 };
index 5c1a196be0c54bf1d2565e1df3ade003e64ca2c7..ef5ca7c13ca56dded8fe26d8519fa39039c43e56 100644 (file)
@@ -437,17 +437,28 @@ static int bridge_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
        struct irq_alloc_info info;
        int irq;
 
-       irq = bc->pci_int[slot];
+       switch (pin) {
+       case PCI_INTERRUPT_UNKNOWN:
+       case PCI_INTERRUPT_INTA:
+       case PCI_INTERRUPT_INTC:
+               pin = 0;
+               break;
+       case PCI_INTERRUPT_INTB:
+       case PCI_INTERRUPT_INTD:
+               pin = 1;
+       }
+
+       irq = bc->pci_int[slot][pin];
        if (irq == -1) {
                info.ctrl = bc;
                info.nasid = bc->nasid;
-               info.pin = slot;
+               info.pin = bc->int_mapping[slot][pin];
 
                irq = irq_domain_alloc_irqs(bc->domain, 1, bc->nasid, &info);
                if (irq < 0)
                        return irq;
 
-               bc->pci_int[slot] = irq;
+               bc->pci_int[slot][pin] = irq;
        }
        return irq;
 }
@@ -458,21 +469,26 @@ static void bridge_setup_ip27_baseio6g(struct bridge_controller *bc)
 {
        bc->ioc3_sid[2] = IOC3_SID(IOC3_SUBSYS_IP27_BASEIO6G);
        bc->ioc3_sid[6] = IOC3_SID(IOC3_SUBSYS_IP27_MIO);
+       bc->int_mapping[2][1] = 4;
+       bc->int_mapping[6][1] = 6;
 }
 
 static void bridge_setup_ip27_baseio(struct bridge_controller *bc)
 {
        bc->ioc3_sid[2] = IOC3_SID(IOC3_SUBSYS_IP27_BASEIO);
+       bc->int_mapping[2][1] = 4;
 }
 
 static void bridge_setup_ip29_baseio(struct bridge_controller *bc)
 {
        bc->ioc3_sid[2] = IOC3_SID(IOC3_SUBSYS_IP29_SYSBOARD);
+       bc->int_mapping[2][1] = 3;
 }
 
 static void bridge_setup_ip30_sysboard(struct bridge_controller *bc)
 {
        bc->ioc3_sid[2] = IOC3_SID(IOC3_SUBSYS_IP30_SYSBOARD);
+       bc->int_mapping[2][1] = 4;
 }
 
 static void bridge_setup_menet(struct bridge_controller *bc)
@@ -655,7 +671,11 @@ static int bridge_probe(struct platform_device *pdev)
 
        for (slot = 0; slot < 8; slot++) {
                bridge_set(bc, b_device[slot].reg, BRIDGE_DEV_SWAP_DIR);
-               bc->pci_int[slot] = -1;
+               bc->pci_int[slot][0] = -1;
+               bc->pci_int[slot][1] = -1;
+               /* default interrupt pin mapping */
+               bc->int_mapping[slot][0] = slot;
+               bc->int_mapping[slot][1] = slot ^ 4;
        }
        bridge_read(bc, b_wid_tflush);    /* wait until Bridge PIO complete */