diff options
Diffstat (limited to 'arch/mips/pci/pci-xlr.c')
| -rw-r--r-- | arch/mips/pci/pci-xlr.c | 109 |
1 files changed, 50 insertions, 59 deletions
diff --git a/arch/mips/pci/pci-xlr.c b/arch/mips/pci/pci-xlr.c index 18af021d289..0dde80332d3 100644 --- a/arch/mips/pci/pci-xlr.c +++ b/arch/mips/pci/pci-xlr.c @@ -47,6 +47,7 @@ #include <asm/netlogic/interrupt.h> #include <asm/netlogic/haldefs.h> +#include <asm/netlogic/common.h> #include <asm/netlogic/xlr/msidef.h> #include <asm/netlogic/xlr/iomap.h> @@ -55,7 +56,7 @@ static void *pci_config_base; -#define pci_cfg_addr(bus, devfn, off) (((bus) << 16) | ((devfn) << 8) | (off)) +#define pci_cfg_addr(bus, devfn, off) (((bus) << 16) | ((devfn) << 8) | (off)) /* PCI ops */ static inline u32 pci_cfg_read_32bit(struct pci_bus *bus, unsigned int devfn, @@ -135,26 +136,26 @@ struct pci_ops nlm_pci_ops = { }; static struct resource nlm_pci_mem_resource = { - .name = "XLR PCI MEM", - .start = 0xd0000000UL, /* 256MB PCI mem @ 0xd000_0000 */ - .end = 0xdfffffffUL, - .flags = IORESOURCE_MEM, + .name = "XLR PCI MEM", + .start = 0xd0000000UL, /* 256MB PCI mem @ 0xd000_0000 */ + .end = 0xdfffffffUL, + .flags = IORESOURCE_MEM, }; static struct resource nlm_pci_io_resource = { - .name = "XLR IO MEM", - .start = 0x10000000UL, /* 16MB PCI IO @ 0x1000_0000 */ - .end = 0x100fffffUL, - .flags = IORESOURCE_IO, + .name = "XLR IO MEM", + .start = 0x10000000UL, /* 16MB PCI IO @ 0x1000_0000 */ + .end = 0x100fffffUL, + .flags = IORESOURCE_IO, }; struct pci_controller nlm_pci_controller = { - .index = 0, - .pci_ops = &nlm_pci_ops, - .mem_resource = &nlm_pci_mem_resource, - .mem_offset = 0x00000000UL, - .io_resource = &nlm_pci_io_resource, - .io_offset = 0x00000000UL, + .index = 0, + .pci_ops = &nlm_pci_ops, + .mem_resource = &nlm_pci_mem_resource, + .mem_offset = 0x00000000UL, + .io_resource = &nlm_pci_io_resource, + .io_offset = 0x00000000UL, }; /* @@ -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,19 +193,29 @@ 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; } -#ifdef CONFIG_PCI_MSI -void destroy_irq(unsigned int irq) +static int get_irq_vector(const struct pci_dev *dev) { - /* nothing to do yet */ + 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 arch_teardown_msi_irq(unsigned int irq) { - destroy_irq(irq); } int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc) @@ -255,14 +253,12 @@ int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc) MSI_ADDR_REDIRECTION_CPU; msg.data = MSI_DATA_TRIGGER_EDGE | - MSI_DATA_LEVEL_ASSERT | + MSI_DATA_LEVEL_ASSERT | MSI_DATA_DELIVERY_FIXED; ret = irq_set_msi_desc(irq, desc); - if (ret < 0) { - destroy_irq(irq); + if (ret < 0) return ret; - } write_msi_msg(irq, &msg); return 0; @@ -332,12 +328,15 @@ 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); /* Extend IO port for memory mapped io */ - ioport_resource.start = 0; + ioport_resource.start = 0; ioport_resource.end = ~0; set_io_port_base(CKSEG1); @@ -350,27 +349,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; } |
