Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

MIPS: PCI: Support mapping of INTB/C/D for pci-xtalk-bridge

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

authored by

Thomas Bogendoerfer and committed by
Paul Burton
2634e5a6 d96ee783

+26 -5
+2 -1
arch/mips/include/asm/pci/bridge.h
··· 806 806 unsigned long baddr; 807 807 unsigned long intr_addr; 808 808 struct irq_domain *domain; 809 - unsigned int pci_int[8]; 809 + unsigned int pci_int[8][2]; 810 + unsigned int int_mapping[8][2]; 810 811 u32 ioc3_sid[8]; 811 812 nasid_t nasid; 812 813 };
+24 -4
arch/mips/pci/pci-xtalk-bridge.c
··· 437 437 struct irq_alloc_info info; 438 438 int irq; 439 439 440 - irq = bc->pci_int[slot]; 440 + switch (pin) { 441 + case PCI_INTERRUPT_UNKNOWN: 442 + case PCI_INTERRUPT_INTA: 443 + case PCI_INTERRUPT_INTC: 444 + pin = 0; 445 + break; 446 + case PCI_INTERRUPT_INTB: 447 + case PCI_INTERRUPT_INTD: 448 + pin = 1; 449 + } 450 + 451 + irq = bc->pci_int[slot][pin]; 441 452 if (irq == -1) { 442 453 info.ctrl = bc; 443 454 info.nasid = bc->nasid; 444 - info.pin = slot; 455 + info.pin = bc->int_mapping[slot][pin]; 445 456 446 457 irq = irq_domain_alloc_irqs(bc->domain, 1, bc->nasid, &info); 447 458 if (irq < 0) 448 459 return irq; 449 460 450 - bc->pci_int[slot] = irq; 461 + bc->pci_int[slot][pin] = irq; 451 462 } 452 463 return irq; 453 464 } ··· 469 458 { 470 459 bc->ioc3_sid[2] = IOC3_SID(IOC3_SUBSYS_IP27_BASEIO6G); 471 460 bc->ioc3_sid[6] = IOC3_SID(IOC3_SUBSYS_IP27_MIO); 461 + bc->int_mapping[2][1] = 4; 462 + bc->int_mapping[6][1] = 6; 472 463 } 473 464 474 465 static void bridge_setup_ip27_baseio(struct bridge_controller *bc) 475 466 { 476 467 bc->ioc3_sid[2] = IOC3_SID(IOC3_SUBSYS_IP27_BASEIO); 468 + bc->int_mapping[2][1] = 4; 477 469 } 478 470 479 471 static void bridge_setup_ip29_baseio(struct bridge_controller *bc) 480 472 { 481 473 bc->ioc3_sid[2] = IOC3_SID(IOC3_SUBSYS_IP29_SYSBOARD); 474 + bc->int_mapping[2][1] = 3; 482 475 } 483 476 484 477 static void bridge_setup_ip30_sysboard(struct bridge_controller *bc) 485 478 { 486 479 bc->ioc3_sid[2] = IOC3_SID(IOC3_SUBSYS_IP30_SYSBOARD); 480 + bc->int_mapping[2][1] = 4; 487 481 } 488 482 489 483 static void bridge_setup_menet(struct bridge_controller *bc) ··· 671 655 672 656 for (slot = 0; slot < 8; slot++) { 673 657 bridge_set(bc, b_device[slot].reg, BRIDGE_DEV_SWAP_DIR); 674 - bc->pci_int[slot] = -1; 658 + bc->pci_int[slot][0] = -1; 659 + bc->pci_int[slot][1] = -1; 660 + /* default interrupt pin mapping */ 661 + bc->int_mapping[slot][0] = slot; 662 + bc->int_mapping[slot][1] = slot ^ 4; 675 663 } 676 664 bridge_read(bc, b_wid_tflush); /* wait until Bridge PIO complete */ 677 665