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);
 
