[parisc-linux-cvs] EISA interrupt support

Matthew Wilcox willy@ldl.fc.hp.com
Fri, 12 Oct 2001 00:45:35 -0600


-pa49:
 * Use IRQ region 0 for EISA IRQs.
 * Tidy up Asp register handling.
 * Report Asp version 4 as Cutoff.
 * Remove ASP hack from busdevice_alloc_irq since it's now short-circuited.
 * Change Dino, Lasi & Wax over to choosing IRQ based on sversion, not hpa.
 * Claim the right memory space for EISA on 64-bit machines (not tested).

Index: arch/parisc/kernel/irq.c
===================================================================
RCS file: /home/cvs/parisc/linux/arch/parisc/kernel/irq.c,v
retrieving revision 1.45
diff -u -p -r1.45 irq.c
--- arch/parisc/kernel/irq.c	2001/09/06 09:44:07	1.45
+++ arch/parisc/kernel/irq.c	2001/10/12 06:27:46
@@ -535,7 +535,7 @@ int request_irq(unsigned int irq,
 		return -EINVAL;
 	}
 
-	if ((IRQ_REGION(irq) == 0) || irq_region[IRQ_REGION(irq)] == NULL) {
+	if (irq_region[IRQ_REGION(irq)] == NULL) {
 		/*
 		** Bug catcher for drivers which use "char" or u8 for
 		** the IRQ number. They lose the region number which
Index: drivers/gsc/asp.c
===================================================================
RCS file: /home/cvs/parisc/linux/drivers/gsc/asp.c,v
retrieving revision 1.12
diff -u -p -r1.12 asp.c
--- drivers/gsc/asp.c	2001/10/11 23:43:28	1.12
+++ drivers/gsc/asp.c	2001/10/12 06:27:47
@@ -24,10 +24,9 @@
 
 #define ASP_GSC_IRQ	3		/* hardcoded interrupt for GSC */
 
-#define ASP_HPA_HARD	0xF0800000	/* hardcoded HPA for ASP */
-#define ASP_VER_OFFSET 	0x2F020		/* offset of ASP version */
+#define ASP_VER_OFFSET 	0x20		/* offset of ASP version */
 
-#define OFFSET_ASP_LED	0x20		/* offset to HPA of the LED */ 
+#define ASP_LED_ADDR	0xf0800020
 
 #define VIPER_INT_WORD  0xFFFBF088      /* addr of viper interrupt word */
 
@@ -68,6 +67,14 @@ static void fixup_bus(struct parisc_devi
 	}
 }
 
+/* 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
+ * the purposes of interrupt handling, we have to tell other bits of
+ * the kernel to look at the other registers.
+ */
+#define ASP_INTERRUPT_ADDR 0xf0800000
+
 int __init
 asp_init_chip(struct parisc_device *dev)
 {
@@ -79,15 +86,13 @@ asp_init_chip(struct parisc_device *dev)
 	if(!asp)
 		return -ENOMEM;
 
-	asp->name = "Asp";
+	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;
 
-	/*  The PDC-Firmware reports the ASP at 0xF082F000, 
-	    but we must use a HPA of 0xF0820000 */
-	asp->hpa = ASP_HPA_HARD;
-	asp->version = gsc_readb(asp->hpa + ASP_VER_OFFSET);
 	printk(KERN_INFO "%s version %d at 0x%lx found.\n", 
-		asp->name, asp->version, asp->hpa);
+		asp->name, asp->version, dev->hpa);
 
 	/* the IRQ ASP should use */
 	ret = -EBUSY;
@@ -119,7 +124,7 @@ asp_init_chip(struct parisc_device *dev)
 	/* initialize the chassis LEDs */ 
 #ifdef CONFIG_CHASSIS_LCD_LED	
 	register_led_driver(DISPLAY_MODEL_OLD_ASP, LED_CMD_REG_NONE, 
-		    (char *)(asp->hpa + OFFSET_ASP_LED));
+		    (char *)ASP_LED_ADDR);
 #endif
 
 	return 0;
Index: drivers/gsc/busdevice.c
===================================================================
RCS file: /home/cvs/parisc/linux/drivers/gsc/busdevice.c,v
retrieving revision 1.27
diff -u -p -r1.27 busdevice.c
--- drivers/gsc/busdevice.c	2001/10/11 23:43:28	1.27
+++ drivers/gsc/busdevice.c	2001/10/12 06:27:47
@@ -67,10 +67,7 @@ int busdevice_alloc_irq(struct parisc_de
 	}
 
 	/* See if this Device belongs to a LASI/ASP/WAX we know about */
-	/* deller: Changed to test only the 3 highest nibbles of the
-	    address-range, since ASP uses hpa of 0xf080yyyy, but devices are 
-	    at adress 0xf082yyyy ! */
-	while (busdev && ((busdev->hpa & ~0xfffff) != (hpa & ~0xfffff))) {
+	while (busdev && ((busdev->hpa & ~0xffff) != (hpa & ~0xffff))) {
 		busdev = busdev->next;
 	}
 
Index: drivers/gsc/dino.c
===================================================================
RCS file: /home/cvs/parisc/linux/drivers/gsc/dino.c,v
retrieving revision 1.39
diff -u -p -r1.39 dino.c
--- drivers/gsc/dino.c	2001/09/18 16:12:10	1.39
+++ drivers/gsc/dino.c	2001/10/12 06:27:47
@@ -452,13 +452,12 @@ ilr_again:
 static int
 dino_find_irq(struct busdevice *dino_dev, struct parisc_device *dev)
 {	
-	int irq;
-	int off = dev->hpa & 0xffff;
+	int irq = -1;
 
-	switch (off) {
-	case 0x1000:	irq = 8;  break; /* PS/2 Keyboard and Mouse */
-	case 0x3000:	irq = 10; break; /* RS232 */
-	default:        irq = -1; break; /* unknown */
+	switch (dev->id.sversion) {
+		case 0x00084:	irq = 8;  break; /* PS/2 */
+		case 0x0008c:	irq = 10; break; /* RS232 */
+		case 0x00096:	irq = 8;  break; /* PS/2 */
 	}
 
 	return irq;
Index: drivers/gsc/eisa.c
===================================================================
RCS file: /home/cvs/parisc/linux/drivers/gsc/eisa.c,v
retrieving revision 1.2
diff -u -p -r1.2 eisa.c
--- drivers/gsc/eisa.c	2001/10/11 23:43:28	1.2
+++ drivers/gsc/eisa.c	2001/10/12 06:27:47
@@ -33,7 +34,6 @@
  */
 struct eisa_ba {
 	struct pci_hba_data	hba;
-	struct irq_region *region;
 } eisa_dev;
 
 /* Port ops */
@@ -89,17 +89,6 @@ void eisa_out32(u32 data, u16 port)
 
 /* Interrupt handling */
 
-static void eisa_irq(int _, void *intr_dev, struct pt_regs *regs)
-{
-	extern void do_irq(struct irqaction *a, int i, struct pt_regs *p);
-	int irq = gsc_readb(0xfc01f000);
-
-	printk(KERN_DEBUG "EISA irq %d\n", irq);
-
-	do_irq(&eisa_dev.region->action[irq],
-			eisa_dev.region->data.irqbase + irq, regs);
-}
-
 static void eisa_disable_irq(void *irq_dev, int irq)
 {
 	return;
@@ -119,14 +108,25 @@ static void eisa_unmask_irq(void *irq_de
 {
 	return;
 }
+
+struct irqaction action[16];
+
+#define EISA_IRQ_REGION 0 /* Compatibility */
 
-static struct irq_region_ops eisa_irq_ops = {
-	disable_irq:	eisa_disable_irq,
-	enable_irq:	eisa_enable_irq,
-	mask_irq:	eisa_mask_irq,
-	unmask_irq:	eisa_unmask_irq,
+static struct irq_region eisa_irq_region = {
+	{ eisa_disable_irq, eisa_enable_irq, eisa_mask_irq, eisa_unmask_irq },
+	{ NULL, "EISA", IRQ_REG_MASK|IRQ_REG_DIS, EISA_IRQ_REGION },
+	action,
 };
 
+static void eisa_irq(int _, void *intr_dev, struct pt_regs *regs)
+{
+	extern void do_irq(struct irqaction *a, int i, struct pt_regs *p);
+	int irq = gsc_readb(0xfc01f000) & 0xf; /* EISA supports 16 irqs */
+
+	do_irq(&eisa_irq_region.action[irq], EISA_IRQ_REGION + irq, regs);
+}
+
 /* Device initialisation */
 
 #define is_mongoose(dev) (dev->id.sversion == 0x00076)
@@ -139,8 +139,8 @@ static int __devinit eisa_probe(struct p
 	printk("%s EISA Adapter found at 0x%08lx\n", name, dev->hpa);
 
 	eisa_dev.hba.lmmio_space.name = "EISA";
-	eisa_dev.hba.lmmio_space.start = 0xfc000000;
-	eisa_dev.hba.lmmio_space.end = 0xffbfffff;
+	eisa_dev.hba.lmmio_space.start = (unsigned long) 0xfffffffffc000000;
+	eisa_dev.hba.lmmio_space.end = (unsigned long) 0xffffffffffbfffff;
 	eisa_dev.hba.lmmio_space.flags = IORESOURCE_MEM;
 	result = request_resource(&iomem_resource, &eisa_dev.hba.lmmio_space);
 	if (result < 0) {
@@ -167,13 +167,8 @@ static int __devinit eisa_probe(struct p
 	if (result) {
 		printk(KERN_ERR "EISA: request_irq failed!\n");
 		return result;
-	}
-	eisa_dev.region = alloc_irq_region(8, &eisa_irq_ops,
-			IRQ_REG_MASK|IRQ_REG_DIS, name, NULL);
-	if (eisa_dev.region == NULL) {
-		printk(KERN_ERR "EISA: Couldn't allocate IRQ region\n");
-		return -ENODEV;
 	}
+	irq_region[0] = &eisa_irq_region;
 
 	EISA_bus = 1;
 
Index: drivers/gsc/lasi.c
===================================================================
RCS file: /home/cvs/parisc/linux/drivers/gsc/lasi.c,v
retrieving revision 1.27
diff -u -p -r1.27 lasi.c
--- drivers/gsc/lasi.c	2001/10/04 13:57:31	1.27
+++ drivers/gsc/lasi.c	2001/10/12 06:27:47
@@ -39,23 +39,22 @@ static int
 lasi_find_irq(struct busdevice *lasi_dev, struct parisc_device *dev)
 {
 	int irq;
-	int off = dev->hpa & 0xffff;
 
 	/*
 	** "irq" bits below are numbered relative to most significant bit.
 	*/
-	switch (off) {
-	case 0x0000:	irq = 17; break; /* Lasi itself */
-	case 0x2000:	irq = 24; break; /* Centronics/Parallel Port on Lasi */
-	case 0x4000:	irq = 18; break; /* Audio */
-//	case 0x4???:	irq = 13; break; /* ISDN */
-	case 0x5000:	irq = 26; break; /* RS232 */
-	case 0x6000:	irq = 22; break; /* SCSI */
-	case 0x7000:	irq = 23; break; /* LAN */
-	case 0x8000:    irq =  5; break; /* PS/2 Keyboard */
-	case 0x8100:    irq =  5; break; /* PS/2 Mouse */
-	case 0xA000:	irq = 11; break; /* Floppy Disk Controller */
-	default: 	irq = -1; break; /* unknown */
+	switch (dev->id.sversion) {
+		case 0x74:	irq = 24; break; /* Centronics */
+		case 0x7B:	irq = 18; break; /* Audio */
+		case 0x81:	irq = 17; break; /* Lasi itself */
+		case 0x82:	irq = 22; break; /* SCSI */
+		case 0x83:	irq = 11; break; /* Floppy */
+		case 0x84:	irq =  5; break; /* PS/2 Keyboard */
+		case 0x87:	irq = 13; break; /* ISDN */
+		case 0x8A:	irq = 23; break; /* LAN */
+		case 0x8C:	irq = 26; break; /* RS232 */
+		case 0x8D:	irq = 15; break; /* Telephone 0 */
+		default: 	irq = -1; break; /* unknown */
 	}
 
 #ifdef __LP64__
Index: drivers/gsc/wax.c
===================================================================
RCS file: /home/cvs/parisc/linux/drivers/gsc/wax.c,v
retrieving revision 1.12
diff -u -p -r1.12 wax.c
--- drivers/gsc/wax.c	2001/10/10 20:10:12	1.12
+++ drivers/gsc/wax.c	2001/10/12 06:27:47
@@ -32,17 +32,11 @@
 
 static int wax_find_irq(struct busdevice *lasi_dev, struct parisc_device *dev)
 {
-	int irq;
-	int off = dev->hpa & 0xffff;
+	int irq = -1;
 
-	/*
-	** "irq" bits below are numbered relative to most significant bit.
-	*/
-	switch (off) {
-	case 0x0000:	irq = -1; break; /* FIXME? WAX itself */
-	case 0x1000:	irq = 30; break; /* HIL */
-	case 0x2000:	irq = 25; break; /* RS232 No.2 on WAX (No.1 is on Lasi) */
-	default: 	irq = -1; break; /* unknown */
+	switch (dev->id.sversion) {
+		case 0x00073:	irq = 30; break; /* HIL */
+		case 0x0008c:	irq = 25; break; /* RS232 */
 	}
 
 	return irq;