diff options
author | Florian Fainelli <florian@openwrt.org> | 2007-06-17 14:04:15 +0000 |
---|---|---|
committer | Florian Fainelli <florian@openwrt.org> | 2007-06-17 14:04:15 +0000 |
commit | c6f23822eda274fd99e5ffc2ff081aaf51f60ce2 (patch) | |
tree | 93c6456f260c2066d355ca12e676492f644a2289 /target | |
parent | 0a2f96fd2e73bf09b86a94c7b8514474688e590f (diff) | |
download | upstream-c6f23822eda274fd99e5ffc2ff081aaf51f60ce2.tar.gz upstream-c6f23822eda274fd99e5ffc2ff081aaf51f60ce2.tar.bz2 upstream-c6f23822eda274fd99e5ffc2ff081aaf51f60ce2.zip |
New PCI fixup version, should better assign IRQs for boards, thanks Gabor !
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@7654 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'target')
-rw-r--r-- | target/linux/adm5120-2.6/files/arch/mips/pci/fixup-adm5120.c | 131 |
1 files changed, 109 insertions, 22 deletions
diff --git a/target/linux/adm5120-2.6/files/arch/mips/pci/fixup-adm5120.c b/target/linux/adm5120-2.6/files/arch/mips/pci/fixup-adm5120.c index 07119ef3ad..e8389152b5 100644 --- a/target/linux/adm5120-2.6/files/arch/mips/pci/fixup-adm5120.c +++ b/target/linux/adm5120-2.6/files/arch/mips/pci/fixup-adm5120.c @@ -40,32 +40,62 @@ #include <asm/mach-adm5120/adm5120_defs.h> #include <asm/mach-adm5120/adm5120_irq.h> -static void adm5120_pci_fixup(struct pci_dev *dev) -{ - if (dev->devfn !=0) - return; +struct adm5120_pci_irq { + u8 slot; + u8 func; + u8 pin; + unsigned irq; +}; - /* setup COMMAND register */ - pci_write_config_word(dev, PCI_COMMAND, - (PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER)); +#define PCIIRQ(s,f,p,i) { \ + .slot = (s), \ + .func = (f), \ + .pin = (p), \ + .irq = (i) \ + } - /* setup CACHE_LINE_SIZE register */ - pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 4); +static struct adm5120_pci_irq default_pci_irqs[] __initdata = { + PCIIRQ(2, 0, 1, ADM5120_IRQ_PCI0), +}; - /* setting up BARS */ - pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, 0); - pci_write_config_dword(dev, PCI_BASE_ADDRESS_1, 0); -} +static struct adm5120_pci_irq rb1xx_pci_irqs[] __initdata = { + PCIIRQ(1, 0, 1, ADM5120_IRQ_PCI0), + PCIIRQ(2, 0, 1, ADM5120_IRQ_PCI1), + PCIIRQ(3, 0, 1, ADM5120_IRQ_PCI2) +}; -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ADMTEK, PCI_DEVICE_ID_ADMTEK_ADM5120, - adm5120_pci_fixup); +static struct adm5120_pci_irq cas771_pci_irqs[] __initdata = { + PCIIRQ(2, 0, 1, ADM5120_IRQ_PCI0), + PCIIRQ(3, 0, 1, ADM5120_IRQ_PCI1), + PCIIRQ(3, 2, 3, ADM5120_IRQ_PCI2) +}; + +static struct adm5120_pci_irq np28g_pci_irqs[] __initdata = { + PCIIRQ(2, 0, 1, ADM5120_IRQ_PCI0), + PCIIRQ(3, 0, 1, ADM5120_IRQ_PCI0), + PCIIRQ(3, 1, 2, ADM5120_IRQ_PCI1), + PCIIRQ(3, 2, 3, ADM5120_IRQ_PCI2) +}; +#define GETMAP(n) do { \ + nr_irqs = ARRAY_SIZE(n ## _pci_irqs); \ + p = n ## _pci_irqs; \ + } while (0) int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) { + struct adm5120_pci_irq *p; + int nr_irqs; + int i; int irq; irq = -1; + if (slot < 1 || slot > 3) { + printk("PCI: slot number %u is not supported\n", slot); + goto out; + } + + GETMAP(default); switch (mips_machtype) { case MACH_ADM5120_RB_111: @@ -73,21 +103,78 @@ int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) case MACH_ADM5120_RB_133: case MACH_ADM5120_RB_133C: case MACH_ADM5120_RB_153: - if (slot > 0 && slot < 4) - irq = slot + 5; + GETMAP(rb1xx); + break; + case MACH_ADM5120_NP28G: + GETMAP(np28g); + break; + case MACH_ADM5120_P335: + case MACH_ADM5120_P334WT: + /* using default mapping */ break; +#if 0 + case MACH_ADM5120_CAS771: + GETMAP(cas771) + break; + case MACH_ADM5120_CAS630: + case MACH_ADM5120_CAS670: + case MACH_ADM5120_CAS700: + case MACH_ADM5120_CAS790: + case MACH_ADM5120_CAS861: +#endif + case MACH_ADM5120_NP27G: + case MACH_ADM5120_NP28GHS: + case MACH_ADM5120_WP54AG: + case MACH_ADM5120_WP54G: + case MACH_ADM5120_WP54G_WRT: + case MACH_ADM5120_WPP54AG: + case MACH_ADM5120_WPP54G: default: - if (slot > 1 && slot < 5) - irq = ADM5120_IRQ_PCI0+slot-1; + printk("PCI: irq map is unknown for %s, using defaults.\n", + adm5120_board_name()); break; } - printk(KERN_INFO "PCI: mapping irq for device %s, slot:%u, pin:%u, " - "irq:%d\n", pci_name(dev), slot, pin, irq); - + for (i=0; i<nr_irqs; i++, p++) { + if ((p->slot == slot) && (PCI_FUNC(dev->devfn) == p->func) && + (p->pin == pin)) { + irq = p->irq; + break; + } + } + + if (irq < 0) { + printk(KERN_INFO "PCI: no irq found for %s pin:%u\n", + pci_name(dev), pin); + } else { + printk(KERN_INFO "PCI: mapping irq for %s pin:%u, irq:%d\n", + pci_name(dev), pin, irq); + } + +out: return irq; } +static void adm5120_pci_fixup(struct pci_dev *dev) +{ + if (dev->devfn != 0) + return; + + /* setup COMMAND register */ + pci_write_config_word(dev, PCI_COMMAND, + (PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER)); + + /* setup CACHE_LINE_SIZE register */ + pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 4); + + /* setting up BARS */ + pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, 0); + pci_write_config_dword(dev, PCI_BASE_ADDRESS_1, 0); +} + +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ADMTEK, PCI_DEVICE_ID_ADMTEK_ADM5120, + adm5120_pci_fixup); + int pcibios_plat_dev_init(struct pci_dev *dev) { return 0; |