Unverified Commit 2634e5a6 authored by Thomas Bogendoerfer's avatar Thomas Bogendoerfer Committed by Paul Burton
Browse files

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: default avatarThomas Bogendoerfer <tbogendoerfer@suse.de>
Signed-off-by: default avatarPaul 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
parent d96ee783
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -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;
};
+24 −4
Original line number Diff line number Diff line
@@ -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 */