patch-2.4.22 linux-2.4.22/arch/mips/sgi-ip22/ip22-int.c
Next file: linux-2.4.22/arch/mips/sgi-ip22/ip22-ksyms.c
Previous file: linux-2.4.22/arch/mips/sgi-ip22/ip22-hpc.c
Back to the patch index
Back to the overall index
- Lines: 395
- Date:
2003-08-25 04:44:40.000000000 -0700
- Orig file:
linux-2.4.21/arch/mips/sgi-ip22/ip22-int.c
- Orig date:
2002-11-28 15:53:10.000000000 -0800
diff -urN linux-2.4.21/arch/mips/sgi-ip22/ip22-int.c linux-2.4.22/arch/mips/sgi-ip22/ip22-int.c
@@ -7,7 +7,7 @@
* Copyright (C) 1999 Andrew R. Baker (andrewb@uab.edu)
* - Indigo2 changes
* - Interrupt handling fixes
- * Copyright (C) 2001 Ladislav Michl (ladis@psi.cz)
+ * Copyright (C) 2001, 2003 Ladislav Michl (ladis@linux-mips.org)
*/
#include <linux/types.h>
@@ -21,17 +21,16 @@
#include <asm/mipsregs.h>
#include <asm/addrspace.h>
-#include <asm/sgi/sgint23.h>
-#include <asm/sgi/sgihpc.h>
+#include <asm/sgi/ioc.h>
+#include <asm/sgi/hpc3.h>
+#include <asm/sgi/ip22.h>
/* #define DEBUG_SGINT */
-#undef I_REALLY_NEED_THIS_IRQ
-struct sgi_int2_regs *sgi_i2regs;
-struct sgi_int3_regs *sgi_i3regs;
-struct sgi_ioc_ints *ioc_icontrol;
-struct sgi_ioc_timers *ioc_timers;
-volatile unsigned char *ioc_tclear;
+/* So far nothing hangs here */
+#undef USE_LIO3_IRQ
+
+struct sgint_regs *sgint;
static char lc0msk_to_irqnr[256];
static char lc1msk_to_irqnr[256];
@@ -39,8 +38,7 @@
static char lc3msk_to_irqnr[256];
extern asmlinkage void indyIRQ(void);
-extern void do_IRQ(int irq, struct pt_regs *regs);
-extern int ip22_eisa_init (void);
+extern int ip22_eisa_init(void);
static void enable_local0_irq(unsigned int irq)
{
@@ -50,7 +48,7 @@
/* don't allow mappable interrupt to be enabled from setup_irq,
* we have our own way to do so */
if (irq != SGI_MAP_0_IRQ)
- ioc_icontrol->imask0 |= (1 << (irq - SGINT_LOCAL0));
+ sgint->imask0 |= (1 << (irq - SGINT_LOCAL0));
restore_flags(flags);
}
@@ -65,7 +63,7 @@
unsigned long flags;
save_and_cli(flags);
- ioc_icontrol->imask0 &= ~(1 << (irq - SGINT_LOCAL0));
+ sgint->imask0 &= ~(1 << (irq - SGINT_LOCAL0));
restore_flags(flags);
}
@@ -79,14 +77,13 @@
}
static struct hw_interrupt_type ip22_local0_irq_type = {
- "IP22 local 0",
- startup_local0_irq,
- shutdown_local0_irq,
- enable_local0_irq,
- disable_local0_irq,
- mask_and_ack_local0_irq,
- end_local0_irq,
- NULL
+ .typename = "IP22 local 0",
+ .startup = startup_local0_irq,
+ .shutdown = shutdown_local0_irq,
+ .enable = enable_local0_irq,
+ .disable = disable_local0_irq,
+ .ack = mask_and_ack_local0_irq,
+ .end = end_local0_irq,
};
static void enable_local1_irq(unsigned int irq)
@@ -97,7 +94,7 @@
/* don't allow mappable interrupt to be enabled from setup_irq,
* we have our own way to do so */
if (irq != SGI_MAP_1_IRQ)
- ioc_icontrol->imask1 |= (1 << (irq - SGINT_LOCAL1));
+ sgint->imask1 |= (1 << (irq - SGINT_LOCAL1));
restore_flags(flags);
}
@@ -112,7 +109,7 @@
unsigned long flags;
save_and_cli(flags);
- ioc_icontrol->imask1 &= ~(1 << (irq - SGINT_LOCAL1));
+ sgint->imask1 &= ~(1 << (irq - SGINT_LOCAL1));
restore_flags(flags);
}
@@ -126,14 +123,13 @@
}
static struct hw_interrupt_type ip22_local1_irq_type = {
- "IP22 local 1",
- startup_local1_irq,
- shutdown_local1_irq,
- enable_local1_irq,
- disable_local1_irq,
- mask_and_ack_local1_irq,
- end_local1_irq,
- NULL
+ .typename = "IP22 local 1",
+ .startup = startup_local1_irq,
+ .shutdown = shutdown_local1_irq,
+ .enable = enable_local1_irq,
+ .disable = disable_local1_irq,
+ .ack = mask_and_ack_local1_irq,
+ .end = end_local1_irq,
};
static void enable_local2_irq(unsigned int irq)
@@ -141,8 +137,8 @@
unsigned long flags;
save_and_cli(flags);
- ioc_icontrol->imask0 |= (1 << (SGI_MAP_0_IRQ - SGINT_LOCAL0));
- ioc_icontrol->cmeimask0 |= (1 << (irq - SGINT_LOCAL2));
+ sgint->imask0 |= (1 << (SGI_MAP_0_IRQ - SGINT_LOCAL0));
+ sgint->cmeimask0 |= (1 << (irq - SGINT_LOCAL2));
restore_flags(flags);
}
@@ -157,9 +153,9 @@
unsigned long flags;
save_and_cli(flags);
- ioc_icontrol->cmeimask0 &= ~(1 << (irq - SGINT_LOCAL2));
- if (!ioc_icontrol->cmeimask0)
- ioc_icontrol->imask0 &= ~(1 << (SGI_MAP_0_IRQ - SGINT_LOCAL0));
+ sgint->cmeimask0 &= ~(1 << (irq - SGINT_LOCAL2));
+ if (!sgint->cmeimask0)
+ sgint->imask0 &= ~(1 << (SGI_MAP_0_IRQ - SGINT_LOCAL0));
restore_flags(flags);
}
@@ -173,28 +169,23 @@
}
static struct hw_interrupt_type ip22_local2_irq_type = {
- "IP22 local 2",
- startup_local2_irq,
- shutdown_local2_irq,
- enable_local2_irq,
- disable_local2_irq,
- mask_and_ack_local2_irq,
- end_local2_irq,
- NULL
+ .typename = "IP22 local 2",
+ .startup = startup_local2_irq,
+ .shutdown = shutdown_local2_irq,
+ .enable = enable_local2_irq,
+ .disable = disable_local2_irq,
+ .ack = mask_and_ack_local2_irq,
+ .end = end_local2_irq,
};
static void enable_local3_irq(unsigned int irq)
{
-#ifdef I_REALLY_NEED_THIS_IRQ
unsigned long flags;
save_and_cli(flags);
- ioc_icontrol->imask1 |= (1 << (SGI_MAP_1_IRQ - SGINT_LOCAL1));
- ioc_icontrol->cmeimask1 |= (1 << (irq - SGINT_LOCAL3));
+ sgint->imask1 |= (1 << (SGI_MAP_1_IRQ - SGINT_LOCAL1));
+ sgint->cmeimask1 |= (1 << (irq - SGINT_LOCAL3));
restore_flags(flags);
-#else
- panic("Who need local 3 irq? see ip22-int.c");
-#endif
}
static unsigned int startup_local3_irq(unsigned int irq)
@@ -208,9 +199,9 @@
unsigned long flags;
save_and_cli(flags);
- ioc_icontrol->cmeimask1 &= ~(1 << (irq - SGINT_LOCAL3));
- if (!ioc_icontrol->cmeimask1)
- ioc_icontrol->imask1 &= ~(1 << (SGI_MAP_1_IRQ - SGINT_LOCAL1));
+ sgint->cmeimask1 &= ~(1 << (irq - SGINT_LOCAL3));
+ if (!sgint->cmeimask1)
+ sgint->imask1 &= ~(1 << (SGI_MAP_1_IRQ - SGINT_LOCAL1));
restore_flags(flags);
}
@@ -224,30 +215,26 @@
}
static struct hw_interrupt_type ip22_local3_irq_type = {
- "IP22 local 3",
- startup_local3_irq,
- shutdown_local3_irq,
- enable_local3_irq,
- disable_local3_irq,
- mask_and_ack_local3_irq,
- end_local3_irq,
- NULL
+ .typename = "IP22 local 3",
+ .startup = startup_local3_irq,
+ .shutdown = shutdown_local3_irq,
+ .enable = enable_local3_irq,
+ .disable = disable_local3_irq,
+ .ack = mask_and_ack_local3_irq,
+ .end = end_local3_irq,
};
void indy_local0_irqdispatch(struct pt_regs *regs)
{
- unsigned char mask = ioc_icontrol->istat0;
- unsigned char mask2 = 0;
+ u8 mask = sgint->istat0 & sgint->imask0;
+ u8 mask2;
int irq;
- mask &= ioc_icontrol->imask0;
- if (mask & ISTAT0_LIO2) {
- mask2 = ioc_icontrol->vmeistat;
- mask2 &= ioc_icontrol->cmeimask0;
+ if (mask & SGINT_ISTAT0_LIO2) {
+ mask2 = sgint->vmeistat & sgint->cmeimask0;
irq = lc2msk_to_irqnr[mask2];
- } else {
+ } else
irq = lc0msk_to_irqnr[mask];
- }
/* if irq == 0, then the interrupt has already been cleared */
if (irq)
@@ -257,21 +244,15 @@
void indy_local1_irqdispatch(struct pt_regs *regs)
{
- unsigned char mask = ioc_icontrol->istat1;
- unsigned char mask2 = 0;
+ u8 mask = sgint->istat1 & sgint->imask1;
+ u8 mask2;
int irq;
- mask &= ioc_icontrol->imask1;
- if (mask & ISTAT1_LIO3) {
-#ifndef I_REALLY_NEED_THIS_IRQ
- printk("Whee: Got an LIO3 irq, winging it...\n");
-#endif
- mask2 = ioc_icontrol->vmeistat;
- mask2 &= ioc_icontrol->cmeimask1;
+ if (mask & SGINT_ISTAT1_LIO3) {
+ mask2 = sgint->vmeistat & sgint->cmeimask1;
irq = lc3msk_to_irqnr[mask2];
- } else {
+ } else
irq = lc1msk_to_irqnr[mask];
- }
/* if irq == 0, then the interrupt has already been cleared */
if (irq)
@@ -279,7 +260,7 @@
return;
}
-extern void be_ip22_interrupt(int irq, struct pt_regs *regs);
+extern void ip22_be_interrupt(int irq, struct pt_regs *regs);
void indy_buserror_irq(struct pt_regs *regs)
{
@@ -288,21 +269,43 @@
irq_enter(cpu, irq);
kstat.irqs[cpu][irq]++;
- be_ip22_interrupt(irq, regs);
+ ip22_be_interrupt(irq, regs);
irq_exit(cpu, irq);
}
-static struct irqaction local0_cascade =
- { no_action, SA_INTERRUPT, 0, "local0 cascade", NULL, NULL };
-static struct irqaction local1_cascade =
- { no_action, SA_INTERRUPT, 0, "local1 cascade", NULL, NULL };
-static struct irqaction buserr =
- { no_action, SA_INTERRUPT, 0, "Bus Error", NULL, NULL };
-static struct irqaction map0_cascade =
- { no_action, SA_INTERRUPT, 0, "mappable0 cascade", NULL, NULL };
-#ifdef I_REALLY_NEED_THIS_IRQ
-static struct irqaction map1_cascade =
- { no_action, SA_INTERRUPT, 0, "mappable1 cascade", NULL, NULL };
+static struct irqaction local0_cascade = {
+ .handler = no_action,
+ .flags = SA_INTERRUPT,
+ .name = "local0 cascade",
+};
+
+static struct irqaction local1_cascade = {
+ .handler = no_action,
+ .flags = SA_INTERRUPT,
+ .name = "local1 cascade",
+};
+
+static struct irqaction buserr = {
+ .handler = no_action,
+ .flags = SA_INTERRUPT,
+ .name = "Bus Error",
+};
+
+static struct irqaction map0_cascade = {
+ .handler = no_action,
+ .flags = SA_INTERRUPT,
+ .name = "mapable0 cascade",
+};
+
+#ifdef USE_LIO3_IRQ
+static struct irqaction map1_cascade = {
+ .handler = no_action,
+ .flags = SA_INTERRUPT,
+ .name = "mapable1 cascade",
+};
+#define SGI_INTERRUPTS SGINT_END
+#else
+#define SGI_INTERRUPTS SGINT_LOCAL3
#endif
extern void mips_cpu_irq_init(unsigned int irq_base);
@@ -311,9 +314,6 @@
{
int i;
- sgi_i2regs = (struct sgi_int2_regs *) (KSEG1 + SGI_INT2_BASE);
- sgi_i3regs = (struct sgi_int3_regs *) (KSEG1 + SGI_INT3_BASE);
-
/* Init local mask --> irq tables. */
for (i = 0; i < 256; i++) {
if (i & 0x80) {
@@ -364,22 +364,11 @@
}
}
- /* Indy uses an INT3, Indigo2 uses an INT2 */
- if (sgi_guiness) {
- ioc_icontrol = &sgi_i3regs->ints;
- ioc_timers = &sgi_i3regs->timers;
- ioc_tclear = &sgi_i3regs->tclear;
- } else {
- ioc_icontrol = &sgi_i2regs->ints;
- ioc_timers = &sgi_i2regs->timers;
- ioc_tclear = &sgi_i2regs->tclear;
- }
-
/* Mask out all interrupts. */
- ioc_icontrol->imask0 = 0;
- ioc_icontrol->imask1 = 0;
- ioc_icontrol->cmeimask0 = 0;
- ioc_icontrol->cmeimask1 = 0;
+ sgint->imask0 = 0;
+ sgint->imask1 = 0;
+ sgint->cmeimask0 = 0;
+ sgint->cmeimask1 = 0;
set_except_vector(0, indyIRQ);
@@ -387,7 +376,7 @@
/* init CPU irqs */
mips_cpu_irq_init(SGINT_CPU);
- for (i = SGINT_LOCAL0; i < SGINT_END; i++) {
+ for (i = SGINT_LOCAL0; i < SGI_INTERRUPTS; i++) {
hw_irq_controller *handler;
if (i < SGINT_LOCAL1)
@@ -412,11 +401,12 @@
/* cascade in cascade. i love Indy ;-) */
setup_irq(SGI_MAP_0_IRQ, &map0_cascade);
-#ifdef I_REALLY_NEED_THIS_IRQ
+#ifdef USE_LIO3_IRQ
setup_irq(SGI_MAP_1_IRQ, &map1_cascade);
#endif
+
#ifdef CONFIG_IP22_EISA
- if (!sgi_guiness) /* Only Indigo-2 have EISA stuff */
+ if (ip22_is_fullhouse()) /* Only Indigo-2 have EISA stuff */
ip22_eisa_init ();
#endif
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)