From ea49b750d4d2038c8227dfb8bbf9a2ba3fd4c4c5 Mon Sep 17 00:00:00 2001 From: Jayachandran C Date: Thu, 15 Nov 2012 09:45:55 +0000 Subject: [PATCH] MIPS: PCI: Update XLR/XLS PCI for the new PIC code Use the nlm_set_pic_extra_ack() call to setup the extra interrupt ACK needed by XLR PCI and XLS PCIe. Simplify the code by adding nlm_pci_link_to_irq(). Signed-off-by: Jayachandran C Patchwork: http://patchwork.linux-mips.org/patch/4561 Signed-off-by: John Crispin --- arch/mips/pci/pci-xlr.c | 69 ++++++++++++++++++++--------------------- 1 file changed, 34 insertions(+), 35 deletions(-) diff --git a/arch/mips/pci/pci-xlr.c b/arch/mips/pci/pci-xlr.c index 18af021d289a..0c18ccc79623 100644 --- a/arch/mips/pci/pci-xlr.c +++ b/arch/mips/pci/pci-xlr.c @@ -47,6 +47,7 @@ #include #include +#include #include #include @@ -174,22 +175,9 @@ static struct pci_dev *xls_get_pcie_link(const struct pci_dev *dev) return p ? bus->self : NULL; } -static int get_irq_vector(const struct pci_dev *dev) +static int nlm_pci_link_to_irq(int link) { - struct pci_dev *lnk; - - if (!nlm_chip_is_xls()) - return PIC_PCIX_IRQ; /* for XLR just one IRQ */ - - /* - * For XLS PCIe, there is an IRQ per Link, find out which - * link the device is on to assign interrupts - */ - lnk = xls_get_pcie_link(dev); - if (lnk == NULL) - return 0; - - switch (PCI_SLOT(lnk->devfn)) { + switch (link) { case 0: return PIC_PCIE_LINK0_IRQ; case 1: @@ -205,10 +193,26 @@ static int get_irq_vector(const struct pci_dev *dev) else return PIC_PCIE_LINK3_IRQ; } - WARN(1, "Unexpected devfn %d\n", lnk->devfn); + WARN(1, "Unexpected link %d\n", link); return 0; } +static int get_irq_vector(const struct pci_dev *dev) +{ + struct pci_dev *lnk; + int link; + + if (!nlm_chip_is_xls()) + return PIC_PCIX_IRQ; /* for XLR just one IRQ */ + + lnk = xls_get_pcie_link(dev); + if (lnk == NULL) + return 0; + + link = PCI_SLOT(lnk->devfn); + return nlm_pci_link_to_irq(link); +} + #ifdef CONFIG_PCI_MSI void destroy_irq(unsigned int irq) { @@ -332,6 +336,9 @@ int pcibios_plat_dev_init(struct pci_dev *dev) static int __init pcibios_init(void) { + void (*extra_ack)(struct irq_data *); + int link, irq; + /* PSB assigns PCI resources */ pci_set_flags(PCI_PROBE_ONLY); pci_config_base = ioremap(DEFAULT_PCI_CONFIG_BASE, 16 << 20); @@ -350,27 +357,19 @@ static int __init pcibios_init(void) * For PCI interrupts, we need to ack the PCI controller too, overload * irq handler data to do this */ - if (nlm_chip_is_xls()) { - if (nlm_chip_is_xls_b()) { - irq_set_handler_data(PIC_PCIE_LINK0_IRQ, - xls_pcie_ack_b); - irq_set_handler_data(PIC_PCIE_LINK1_IRQ, - xls_pcie_ack_b); - irq_set_handler_data(PIC_PCIE_XLSB0_LINK2_IRQ, - xls_pcie_ack_b); - irq_set_handler_data(PIC_PCIE_XLSB0_LINK3_IRQ, - xls_pcie_ack_b); - } else { - irq_set_handler_data(PIC_PCIE_LINK0_IRQ, xls_pcie_ack); - irq_set_handler_data(PIC_PCIE_LINK1_IRQ, xls_pcie_ack); - irq_set_handler_data(PIC_PCIE_LINK2_IRQ, xls_pcie_ack); - irq_set_handler_data(PIC_PCIE_LINK3_IRQ, xls_pcie_ack); - } - } else { + if (!nlm_chip_is_xls()) { /* XLR PCI controller ACK */ - irq_set_handler_data(PIC_PCIX_IRQ, xlr_pci_ack); + nlm_set_pic_extra_ack(0, PIC_PCIX_IRQ, xlr_pci_ack); + } else { + if (nlm_chip_is_xls_b()) + extra_ack = xls_pcie_ack_b; + else + extra_ack = xls_pcie_ack; + for (link = 0; link < 4; link++) { + irq = nlm_pci_link_to_irq(link); + nlm_set_pic_extra_ack(0, irq, extra_ack); + } } - return 0; } -- 2.20.1