Index: arch/parisc/kernel/drivers.c =================================================================== RCS file: /home/cvs/parisc/linux/arch/parisc/kernel/drivers.c,v retrieving revision 1.31 diff -u -p -r1.31 drivers.c --- arch/parisc/kernel/drivers.c 2001/10/22 21:38:05 1.31 +++ arch/parisc/kernel/drivers.c 2001/10/23 14:39:06 @@ -37,9 +37,6 @@ static spinlock_t pa_lock = SPIN_LOCK_UN #define for_each_padev(dev) \ for (dev = root.child; dev != NULL; dev = next_dev(dev)) -#define bus_for_each(dev) \ - for (; dev != NULL; dev = dev->sibling) - #define check_dev(dev) \ (dev->id.hw_type != HPHW_FAULTY) ? dev : next_dev(dev) @@ -381,6 +378,21 @@ void walk_native_bus(unsigned long addr, void walk_central_bus(void) { walk_native_bus(CENTRAL_BUS_ADDR, &root); +} + +void fixup_child_irqs(struct parisc_device *parent, int base, + int (*choose_irq)(struct parisc_device *)) +{ + struct parisc_device *dev; + for (dev = next_dev(parent); dev; dev = dev->sibling) { + int irq = choose_irq(dev); + if (irq > 0) { +#ifdef __LP64__ + irq += 32; +#endif + dev->irq = base + irq; + } + } } static void print_parisc_device(struct parisc_device *dev) Index: drivers/gsc/asp.c =================================================================== RCS file: /home/cvs/parisc/linux/drivers/gsc/asp.c,v retrieving revision 1.13 diff -u -p -r1.13 asp.c --- drivers/gsc/asp.c 2001/10/12 06:35:44 1.13 +++ drivers/gsc/asp.c 2001/10/23 14:39:08 @@ -30,43 +30,27 @@ #define VIPER_INT_WORD 0xFFFBF088 /* addr of viper interrupt word */ -static int -asp_find_irq(struct busdevice *busdev_dev, struct parisc_device *dev) +static int asp_choose_irq(struct parisc_device *dev) { - int irq = 0; + int irq = -1; switch (dev->id.sversion) { - case 0x71: irq = 22; break; /* SCSI */ - case 0x72: irq = 23; break; /* LAN */ - case 0x73: irq = 30; break; /* HIL */ - case 0x74: irq = 24; break; /* Centronics */ - case 0x75: if ((dev->hpa & 0xffff) == 0x3000) - irq = 26; /* RS232 A */ - else - irq = 25; /* RS232 B */ - break; - case 0x76: irq = 21; break; /* EISA BA */ - case 0x77: irq = 20; break; /* Graphics1 */ - case 0x7a: irq = 18; break; /* Audio (Bushmaster) */ - case 0x7b: irq = 18; break; /* Audio (Scorpio) */ - case 0x7c: irq = 28; break; /* FW SCSI */ - case 0x7d: irq = 27; break; /* FDDI */ - case 0x7f: irq = 18; break; /* Audio (Outfield) */ + case 0x71: irq = 22; break; /* SCSI */ + case 0x72: irq = 23; break; /* LAN */ + case 0x73: irq = 30; break; /* HIL */ + case 0x74: irq = 24; break; /* Centronics */ + case 0x75: irq = (dev->hw_path == 4) ? 26 : 25; break; /* RS232 */ + case 0x76: irq = 21; break; /* EISA BA */ + case 0x77: irq = 20; break; /* Graphics1 */ + case 0x7a: irq = 18; break; /* Audio (Bushmaster) */ + case 0x7b: irq = 18; break; /* Audio (Scorpio) */ + case 0x7c: irq = 28; break; /* FW SCSI */ + case 0x7d: irq = 27; break; /* FDDI */ + case 0x7f: irq = 18; break; /* Audio (Outfield) */ } return irq; } -static void fixup_bus(struct parisc_device *dev, int base) -{ - while (dev) { - int irq = asp_find_irq(NULL, dev); - if (irq) { - dev->irq = base + irq; - } - dev = dev->sibling; - } -} - /* There are two register ranges we're interested in. Interrupt / * Status / LED are at 0xf080xxxx and Asp special registers are at * 0xf082fxxx. PDC only tells us that Asp is at 0xf082f000, so for @@ -88,7 +72,6 @@ asp_init_chip(struct parisc_device *dev) asp->version = gsc_readb(dev->hpa + ASP_VER_OFFSET) & 0xf; asp->name = (asp->version == 1) ? "Asp" : "Cutoff"; - asp->find_irq = asp_find_irq; asp->hpa = ASP_INTERRUPT_ADDR; printk(KERN_INFO "%s version %d at 0x%lx found.\n", @@ -118,8 +101,10 @@ asp_init_chip(struct parisc_device *dev) if (ret) goto out; - fixup_bus(dev->child, asp->busdev_region->data.irqbase); - fixup_bus(dev, asp->busdev_region->data.irqbase); + fixup_child_irqs(dev, asp->busdev_region->data.irqbase, asp_choose_irq); + /* Mongoose is a sibling of Asp, not a child... */ + fixup_child_irqs(dev->parent, asp->busdev_region->data.irqbase, + asp_choose_irq); /* initialize the chassis LEDs */ #ifdef CONFIG_CHASSIS_LCD_LED Index: drivers/gsc/busdevice.c =================================================================== RCS file: /home/cvs/parisc/linux/drivers/gsc/busdevice.c,v retrieving revision 1.28 diff -u -p -r1.28 busdevice.c --- drivers/gsc/busdevice.c 2001/10/12 06:35:44 1.28 +++ drivers/gsc/busdevice.c 2001/10/23 14:39:08 @@ -49,49 +49,11 @@ static struct busdevice *busdev_list = N int busdevice_alloc_irq(struct parisc_device *dev) { - struct busdevice *busdev = busdev_list; - int irq; - int hpa = dev->hpa; - if (dev->irq) return dev->irq; - - if (dev->parent) { - hpa = dev->parent->hpa; - } - - if (!busdev) { - printk(KERN_ERR "%s(0x%p): No LASI/ASP/WAX found in system yet !\n", - __FUNCTION__, dev); - return 0; - } - - /* See if this Device belongs to a LASI/ASP/WAX we know about */ - while (busdev && ((busdev->hpa & ~0xffff) != (hpa & ~0xffff))) { - busdev = busdev->next; - } - - if (!busdev) { - printk(KERN_WARNING "%s(0x%p): No known LASI/ASP/WAX owns device at 0x%lx !\n", - __FUNCTION__, dev, dev->hpa); - return 0; - } - - /* find the correspondig IRQ */ - irq = busdev->find_irq(busdev, dev); - - if (irq < 0) { - printk(KERN_ERR "%s(0x%lx): %s has never seen the HPA offset of 0x%lx.\n", - __FUNCTION__, dev->hpa, busdev->name, dev->hpa & 0xffff ); - return (0); - } - - DEBPRINTK (KERN_INFO "%s(0x%p) on %s 0x%x + %d = %d\n", - __FUNCTION__, dev->hpa, busdev->name, - busdev->busdev_region->data.irqbase, irq, - busdev->busdev_region->data.irqbase + irq); - - return busdev->busdev_region->data.irqbase + irq; + printk("Awooga! Awooga! No IRQ assigned to device %s %p\n", + dev->name, dev->hpa); + return 0; } @@ -188,8 +150,8 @@ struct irq_region_ops busdev_irq_ops = { } while (0) -int register_busdevice( struct parisc_device *gsc_parent, - struct busdevice *busdev ) +int register_busdevice(struct parisc_device *gsc_parent, + struct busdevice *busdev) { struct resource *res; Index: drivers/gsc/busdevice.h =================================================================== RCS file: /home/cvs/parisc/linux/drivers/gsc/busdevice.h,v retrieving revision 1.5 diff -u -p -r1.5 busdevice.h --- drivers/gsc/busdevice.h 2001/08/14 16:54:54 1.5 +++ drivers/gsc/busdevice.h 2001/10/23 14:39:08 @@ -24,7 +24,6 @@ struct busdevice { int eim; struct irq_region *busdev_region; spinlock_t spinlock; - int (*find_irq) (struct busdevice *this_dev, struct parisc_device *dev); }; /* short cut to keep the compiler happy */ Index: drivers/gsc/dino.c =================================================================== RCS file: /home/cvs/parisc/linux/drivers/gsc/dino.c,v retrieving revision 1.44 diff -u -p -r1.44 dino.c --- drivers/gsc/dino.c 2001/10/22 05:10:02 1.44 +++ drivers/gsc/dino.c 2001/10/23 14:39:09 @@ -449,15 +449,14 @@ ilr_again: } } -static int -dino_find_irq(struct busdevice *dino_dev, struct parisc_device *dev) -{ +static int dino_choose_irq(struct parisc_device *dev) +{ int irq = -1; switch (dev->id.sversion) { - case 0x00084: irq = 8; break; /* PS/2 */ + case 0x00084: irq = 8; break; /* PS/2 */ case 0x0008c: irq = 10; break; /* RS232 */ - case 0x00096: irq = 8; break; /* PS/2 */ + case 0x00096: irq = 8; break; /* PS/2 */ } return irq; @@ -732,7 +731,7 @@ dino_bridge_init(struct dino_device *din } static int __init -dino_common_init(struct parisc_device *d, struct dino_device *dino_dev) +dino_common_init(struct parisc_device *dev, struct dino_device *dino_dev) { int status; u32 eim; @@ -755,9 +754,7 @@ dino_common_init(struct parisc_device *d return -ENOMEM; dino_busdevice->name = "Dino"; - dino_busdevice->hpa = d->hpa; - dino_busdevice->find_irq = dino_find_irq; - + dino_busdevice->hpa = dev->hpa; /* ** Note: SMP systems can make use of IRR1/IAR1 registers @@ -807,10 +804,10 @@ dino_common_init(struct parisc_device *d dino_busdevice->parent_irq = gsc_irq.irq; dino_busdevice->eim = ((u32) gsc_irq.txn_addr) | gsc_irq.txn_data; - ret = register_busdevice(d,dino_busdevice); + ret = register_busdevice(dev, dino_busdevice); if (ret) { - kfree(dino_busdevice); - return ret; + kfree(dino_busdevice); + return ret; } /* @@ -820,8 +817,10 @@ dino_common_init(struct parisc_device *d */ /* kfree(dino_busdevice->busdev_region); */ dino_busdevice->busdev_region = dino_dev->dino_region; - + fixup_child_irqs(dev, dino_busdevice->busdev_region->data.irqbase, + dino_choose_irq); + /* ** This enables DINO to generate interrupts when it sees ** any of it's inputs *change*. Just asserting an IRQ @@ -837,7 +836,7 @@ dino_common_init(struct parisc_device *d /* allocate I/O Port resource region */ res = &dino_dev->hba.io_space; - if(d->id.hversion == 0x680) { + if (dev->id.hversion == 0x680) { res->name = "Dino"; } else { res->name = "Cujo"; @@ -849,10 +848,10 @@ dino_common_init(struct parisc_device *d if (request_resource(&ioport_resource, res) < 0) { printk(KERN_ERR "DINO: request I/O Port region failed 0x%lx/%lx (hpa 0x%lx)\n" , res->start, res->end, dino_dev->hba.base_addr); - return(1); + return 1; } - return(0); + return 0; } #define CUJO_RAVEN_ADDR 0xf1000000UL Index: drivers/gsc/eisa.c =================================================================== RCS file: /home/cvs/parisc/linux/drivers/gsc/eisa.c,v retrieving revision 1.6 diff -u -p -r1.6 eisa.c --- drivers/gsc/eisa.c 2001/10/13 23:32:13 1.6 +++ drivers/gsc/eisa.c 2001/10/23 14:39:09 @@ -157,16 +157,7 @@ static int __devinit eisa_probe(struct p } pcibios_register_hba(&eisa_dev.hba); - if (is_mongoose(dev)) { - irq = busdevice_alloc_irq(dev); - } else { - unsigned long old_hpa = dev->hpa; - /* Hack: Wax EISA on 712, 715/64, 715/80 and 715/100 (715/new) - * are bound to the Wax controller */ - dev->hpa = (unsigned long) 0xfffffffff0200000; - irq = busdevice_alloc_irq(dev); - dev->hpa = old_hpa; - } + irq = busdevice_alloc_irq(dev); if (!irq) { printk(KERN_ERR "EISA: failed to claim IRQ\n"); return -ENODEV; Index: drivers/gsc/lasi.c =================================================================== RCS file: /home/cvs/parisc/linux/drivers/gsc/lasi.c,v retrieving revision 1.30 diff -u -p -r1.30 lasi.c --- drivers/gsc/lasi.c 2001/10/22 15:45:37 1.30 +++ drivers/gsc/lasi.c 2001/10/23 14:39:09 @@ -35,8 +35,7 @@ #define LASI_IO_CONF 0x7FFFE /* LASI primary configuration register */ #define LASI_IO_CONF2 0x7FFFF /* LASI secondary configuration register */ -static int -lasi_find_irq(struct busdevice *lasi_dev, struct parisc_device *dev) +static int lasi_choose_irq(struct parisc_device *dev) { int irq; @@ -57,11 +56,7 @@ lasi_find_irq(struct busdevice *lasi_dev default: irq = -1; break; /* unknown */ } -#ifdef __LP64__ - return irq + 32; -#else return irq; -#endif } static void __init @@ -172,17 +167,6 @@ static void lasi_power_off(void) } -static void fixup_bus(struct parisc_device *dev, int base) -{ - while (dev) { - int irq = lasi_find_irq(NULL, dev); - if (irq) { - dev->irq = base + irq; - } - dev = dev->sibling; - } -} - int __init lasi_init_chip(struct parisc_device *dev) { @@ -197,7 +181,6 @@ lasi_init_chip(struct parisc_device *dev lasi->name = "Lasi"; lasi->hpa = dev->hpa; - lasi->find_irq = lasi_find_irq; /* Check the 4-bit (yes, only 4) version register */ lasi->version = gsc_readl(lasi->hpa + LASI_VER) & 0xf; @@ -238,10 +221,8 @@ lasi_init_chip(struct parisc_device *dev return ret; } - child = dev->child; - if (child->id.hw_type == HPHW_FAULTY) - child = child->child; - fixup_bus(child, lasi->busdev_region->data.irqbase); + fixup_child_irqs(dev, lasi->busdev_region->data.irqbase, + lasi_choose_irq); /* initialize the power off function */ /* FIXME: Record the LASI HPA for the power off function. This should Index: drivers/gsc/wax.c =================================================================== RCS file: /home/cvs/parisc/linux/drivers/gsc/wax.c,v retrieving revision 1.14 diff -u -p -r1.14 wax.c --- drivers/gsc/wax.c 2001/10/13 23:32:13 1.14 +++ drivers/gsc/wax.c 2001/10/23 14:39:09 @@ -30,7 +30,7 @@ #define WAX_GSC_IRQ 7 /* Hardcoded Interrupt for GSC */ #define WAX_GSC_NMI_IRQ 29 -static int wax_find_irq(struct busdevice *lasi_dev, struct parisc_device *dev) +static int wax_choose_irq(struct parisc_device *dev) { int irq = -1; @@ -90,7 +90,6 @@ wax_init_chip(struct parisc_device *dev) wax->name = "Wax"; wax->hpa = dev->hpa; - wax->find_irq = wax_find_irq; wax->version = 0; /* gsc_readb(wax->hpa+WAX_VER); */ printk(KERN_INFO "%s at 0x%lx found.\n", wax->name, wax->hpa); @@ -125,6 +124,15 @@ wax_init_chip(struct parisc_device *dev) kfree(wax); return ret; } + + fixup_child_irqs(dev, wax->busdev_region->data.irqbase, + wax_choose_irq); + /* On 715-class machines, Wax EISA is a sibling of Wax, not a child. + * On B/C/J class machines, wax_choose_irq won't match any device so + * no harm will be done. + */ + fixup_child_irqs(dev->parent, wax->busdev_region->data.irqbase, + wax_choose_irq); /* Register the HIL-Keyboard NMI-Handler */ #ifdef CONFIG_HIL Index: include/asm-parisc/hardware.h =================================================================== RCS file: /home/cvs/parisc/linux/include/asm-parisc/hardware.h,v retrieving revision 1.26 diff -u -p -r1.26 hardware.h --- include/asm-parisc/hardware.h 2001/10/22 21:38:06 1.26 +++ include/asm-parisc/hardware.h 2001/10/23 14:39:16 @@ -104,6 +104,8 @@ extern int register_parisc_driver(struct extern int unregister_parisc_driver(struct parisc_driver *driver); extern void walk_native_bus(unsigned long addr, struct parisc_device *parent); extern void walk_central_bus(void); +extern void fixup_child_irqs(struct parisc_device *parent, int irqbase, + int (*choose)(struct parisc_device *parent)); extern void print_subdevices(struct parisc_device *dev); extern void print_parisc_devices(void);