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