summaryrefslogtreecommitdiff
path: root/target/linux
diff options
context:
space:
mode:
authorflorian <florian@3c298f89-4303-0410-b956-a3cf2f4a3e73>2007-06-17 14:04:15 +0000
committerflorian <florian@3c298f89-4303-0410-b956-a3cf2f4a3e73>2007-06-17 14:04:15 +0000
commit23314df94957bf3c355b60b66ea7a6fee7ebaecf (patch)
tree93c6456f260c2066d355ca12e676492f644a2289 /target/linux
parent489f3e1bc37f08a07bf5a38549e0fbd29ef7b6ae (diff)
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/linux')
-rw-r--r--target/linux/adm5120-2.6/files/arch/mips/pci/fixup-adm5120.c131
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;