hi,
this will bring you following:
* Indy interrupt handling works now better. the only visible change is
look of /proc/interrupts
CPU0
2: 0 CPU_irq local0 cascade
3: 0 CPU_irq local1 cascade
6: 0 CPU_irq Bus Error
9: 2758 IP22 local 0 SGI WD93
11: 2197 IP22 local 0 SGI Seeq8003
15: 0 IP22 local 0 mappable0 cascade
17: 4 IP22 local 1 Front Panel
28: 6754 IP22 local 2 keyboard
29: 0 IP22 local 2 Zilog8530
ERR: 0
one question: should be cascade interrupts counted too?
note, that timer irqs are not present. i'll do so once i'll implement
CONFIG_NEW_TIME_C for Indy.
* I removed irq 'space' for HPC and GIO interrupts. They weren't
implemented and doing so will make interrupt routine _very_ slow.
Driver should register HPC/MC/GIO interrupt as shareable and look
to the proper register to see what happened (currently there is no such
driver, except of HAL2 sitting on my hardisk)
* Various definitions of IP22 interrups were added to sgint23.h
* other minor fixes.
note for those, who are waiting for VINO driver: at the beginning I was
unable to start DMA transfer. now i'm unable to stop it... so to bring my
ego from dust, i decided to write HAL2 driver, which needs HPC interupts.
this patch is HAL2 driver by-product...
any comments and/or suggestions are welcome,
ladis
Index: linux/include/asm-mips/sgi/sgint23.h
===================================================================
RCS file: /cvs/linux/include/asm-mips/sgi/sgint23.h,v
retrieving revision 1.4
diff -u -r1.4 sgint23.h
--- linux/include/asm-mips/sgi/sgint23.h 2001/10/06 22:33:12 1.4
+++ linux/include/asm-mips/sgi/sgint23.h 2001/11/16 12:10:02
@@ -8,100 +8,123 @@
* Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
* Copyright (C) 1997, 98, 1999, 2000 Ralf Baechle
* Copyright (C) 1999 Andrew R. Baker (andrewb@uab.edu) - INT2 corrections
+ * Copyright (C) 2001 Ladislav Michl (ladis@psi.cz)
*/
#ifndef _ASM_SGI_SGINT23_H
#define _ASM_SGI_SGINT23_H
/* These are the virtual IRQ numbers, we divide all IRQ's into
* 'spaces', the 'space' determines where and how to enable/disable
- * that particular IRQ on an SGI machine. Add new 'spaces' as new
- * IRQ hardware is supported.
+ * that particular IRQ on an SGI machine. HPC DMA and MC DMA interrups
+ * are not supported this way. Driver is supposed to allocate HPC/MC
+ * interrupt as shareable and then look to proper status bit (see
+ * HAL2 driver). This will prevent many complications, trust me ;-)
+ * --ladis
*/
-#define SGINT_LOCAL0 0 /* INDY has 8 local0 irq levels */
-#define SGINT_LOCAL1 8 /* INDY has 8 local1 irq levels */
-#define SGINT_LOCAL2 16 /* INDY has 8 local2 vectored irq levels */
-#define SGINT_LOCAL3 24 /* INDY has 8 local3 vectored irq levels */
-#define SGINT_GIO 32 /* INDY has 9 GIO irq levels */
-#define SGINT_HPCDMA 41 /* INDY has 11 HPCDMA irq _sources_ */
-#define SGINT_END 52 /* End of 'spaces' */
+#define SGINT_CPU 0 /* MIPS CPU define 8 interrupt sources */
+#define SGINT_LOCAL0 8 /* INDY has 8 local0 irq levels */
+#define SGINT_LOCAL1 16 /* INDY has 8 local1 irq levels */
+#define SGINT_LOCAL2 24 /* INDY has 8 local2 vectored irq levels */
+#define SGINT_LOCAL3 32 /* INDY has 8 local3 vectored irq levels */
+#define SGINT_END 40 /* End of 'spaces' */
/*
* Individual interrupt definitions for the INDY and Indigo2
*/
-#define SGI_WD93_0_IRQ SGINT_LOCAL0 + 1 /* 1st onboard WD93 */
-#define SGI_WD93_1_IRQ SGINT_LOCAL0 + 2 /* 2nd onboard WD93 */
-#define SGI_ENET_IRQ SGINT_LOCAL0 + 3 /* onboard ethernet */
-
-#define SGI_PANEL_IRQ SGINT_LOCAL1 + 1 /* front panel */
-#define SGI_VINO_IRQ SGINT_LOCAL1 + 6 /* Indy VINO */
-
-#define SGI_EISA_IRQ SGINT_LOCAL2 + 3 /* EISA interrupts */
+#define SGI_LOCAL_0_IRQ SGINT_CPU + 2
+#define SGI_LOCAL_1_IRQ SGINT_CPU + 3
+#define SGI_BUSERR_IRQ SGINT_CPU + 6
+#define SGI_TIMER_IRQ SGINT_CPU + 7
+
+#define SGI_FIFO_IRQ SGINT_LOCAL0 + 0 /* FIFO full */
+#define SGI_GIO_0_IRQ SGI_FIFO_IRQ /* GIO-0 */
+#define SGI_WD93_0_IRQ SGINT_LOCAL0 + 1 /* 1st onboard WD93 */
+#define SGI_WD93_1_IRQ SGINT_LOCAL0 + 2 /* 2nd onboard WD93 */
+#define SGI_ENET_IRQ SGINT_LOCAL0 + 3 /* onboard ethernet */
+#define SGI_MCDMA_IRQ SGINT_LOCAL0 + 4 /* MC DMA done */
+#define SGI_PARPORT_IRQ SGINT_LOCAL0 + 5 /* Parallel port */
+#define SGI_GIO_1_IRQ SGINT_LOCAL0 + 6 /* GE / GIO-1 / 2nd-HPC */
+#define SGI_MAP_0_IRQ SGINT_LOCAL0 + 7 /* Mappable interrupt 0 */
+
+#define SGI_GPL0_IRQ SGINT_LOCAL1 + 0 /* General Purpose LOCAL1_N<0>
*/
+#define SGI_PANEL_IRQ SGINT_LOCAL1 + 1 /* front panel */
+#define SGI_GPL2_IRQ SGINT_LOCAL1 + 2 /* General Purpose LOCAL1_N<2>
*/
+#define SGI_MAP_1_IRQ SGINT_LOCAL1 + 3 /* Mappable interrupt 1 */
+#define SGI_HPCDMA_IRQ SGINT_LOCAL1 + 4 /* HPC DMA done */
+#define SGI_ACFAIL_IRQ SGINT_LOCAL1 + 5 /* AC fail */
+#define SGI_VINO_IRQ SGINT_LOCAL1 + 6 /* Indy VINO */
+#define SGI_GIO_2_IRQ SGINT_LOCAL1 + 7 /* Vert retrace / GIO-2 */
+
+/* Mapped interrupts. These interrupts may be mapped to either 0, or 1
+ * We map them to 0 */
+#define SGI_VERT_IRQ SGINT_LOCAL2 + 0 /* INT3: newport vertical
status */
+#define SGI_EISA_IRQ SGINT_LOCAL2 + 3 /* EISA interrupts */
#define SGI_KEYBOARD_IRQ SGINT_LOCAL2 + 4 /* keyboard */
-#define SGI_SERIAL_IRQ SGINT_LOCAL2 + 5 /* onboard serial */
+#define SGI_SERIAL_IRQ SGINT_LOCAL2 + 5 /* onboard serial */
/* INT2 occupies HPC PBUS slot 4, INT3 uses slot 6. */
-#define SGI_INT2_BASE 0x1fbd9000 /* physical */
-#define SGI_INT3_BASE 0x1fbd9880 /* physical */
+#define SGI_INT2_BASE 0x1fbd9000 /* physical */
+#define SGI_INT3_BASE 0x1fbd9880 /* physical */
struct sgi_ioc_ints {
#ifdef __MIPSEB__
unsigned char _unused0[3];
- volatile unsigned char istat0; /* Interrupt status zero */
+ volatile unsigned char istat0; /* Interrupt status zero */
#else
- volatile unsigned char istat0; /* Interrupt status zero */
+ volatile unsigned char istat0; /* Interrupt status zero */
unsigned char _unused0[3];
#endif
-#define ISTAT0_FFULL 0x01
-#define ISTAT0_SCSI0 0x02
-#define ISTAT0_SCSI1 0x04
-#define ISTAT0_ENET 0x08
-#define ISTAT0_GFXDMA 0x10
-#define ISTAT0_LPR 0x20
-#define ISTAT0_HPC2 0x40
-#define ISTAT0_LIO2 0x80
-
+#define ISTAT0_FFULL 0x01
+#define ISTAT0_SCSI0 0x02
+#define ISTAT0_SCSI1 0x04
+#define ISTAT0_ENET 0x08
+#define ISTAT0_GFXDMA 0x10
+#define ISTAT0_LPR 0x20
+#define ISTAT0_HPC2 0x40
+#define ISTAT0_LIO2 0x80
+
#ifdef __MIPSEB__
unsigned char _unused1[3];
- volatile unsigned char imask0; /* Interrupt mask zero */
+ volatile unsigned char imask0; /* Interrupt mask zero */
unsigned char _unused2[3];
- volatile unsigned char istat1; /* Interrupt status one */
+ volatile unsigned char istat1; /* Interrupt status one */
#else
- volatile unsigned char imask0; /* Interrupt mask zero */
+ volatile unsigned char imask0; /* Interrupt mask zero */
unsigned char _unused1[3];
- volatile unsigned char istat1; /* Interrupt status one */
+ volatile unsigned char istat1; /* Interrupt status one */
unsigned char _unused2[3];
#endif
-#define ISTAT1_ISDNI 0x01
-#define ISTAT1_PWR 0x02
-#define ISTAT1_ISDNH 0x04
-#define ISTAT1_LIO3 0x08
-#define ISTAT1_HPC3 0x10
-#define ISTAT1_AFAIL 0x20
-#define ISTAT1_VIDEO 0x40
-#define ISTAT1_GIO2 0x80
-
+#define ISTAT1_ISDNI 0x01
+#define ISTAT1_PWR 0x02
+#define ISTAT1_ISDNH 0x04
+#define ISTAT1_LIO3 0x08
+#define ISTAT1_HPC3 0x10
+#define ISTAT1_AFAIL 0x20
+#define ISTAT1_VIDEO 0x40
+#define ISTAT1_GIO2 0x80
+
#ifdef __MIPSEB__
unsigned char _unused3[3];
- volatile unsigned char imask1; /* Interrupt mask one */
+ volatile unsigned char imask1; /* Interrupt mask one */
unsigned char _unused4[3];
- volatile unsigned char vmeistat; /* VME interrupt status */
+ volatile unsigned char vmeistat; /* VME interrupt status */
unsigned char _unused5[3];
- volatile unsigned char cmeimask0; /* VME interrupt mask zero */
+ volatile unsigned char cmeimask0; /* VME interrupt mask zero */
unsigned char _unused6[3];
- volatile unsigned char cmeimask1; /* VME interrupt mask one */
+ volatile unsigned char cmeimask1; /* VME interrupt mask one */
unsigned char _unused7[3];
- volatile unsigned char cmepol; /* VME polarity */
+ volatile unsigned char cmepol; /* VME polarity */
#else
- volatile unsigned char imask1; /* Interrupt mask one */
+ volatile unsigned char imask1; /* Interrupt mask one */
unsigned char _unused3[3];
- volatile unsigned char vmeistat; /* VME interrupt status */
+ volatile unsigned char vmeistat; /* VME interrupt status */
unsigned char _unused4[3];
- volatile unsigned char cmeimask0; /* VME interrupt mask zero */
+ volatile unsigned char cmeimask0; /* VME interrupt mask zero */
unsigned char _unused5[3];
- volatile unsigned char cmeimask1; /* VME interrupt mask one */
+ volatile unsigned char cmeimask1; /* VME interrupt mask one */
unsigned char _unused6[3];
- volatile unsigned char cmepol; /* VME polarity */
+ volatile unsigned char cmepol; /* VME polarity */
unsigned char _unused7[3];
#endif
};
@@ -109,21 +132,21 @@
struct sgi_ioc_timers {
#ifdef __MIPSEB__
unsigned char _unused0[3];
- volatile unsigned char tcnt0; /* counter 0 */
+ volatile unsigned char tcnt0; /* counter 0 */
unsigned char _unused1[3];
- volatile unsigned char tcnt1; /* counter 1 */
+ volatile unsigned char tcnt1; /* counter 1 */
unsigned char _unused2[3];
- volatile unsigned char tcnt2; /* counter 2 */
+ volatile unsigned char tcnt2; /* counter 2 */
unsigned char _unused3[3];
- volatile unsigned char tcword; /* control word */
+ volatile unsigned char tcword; /* control word */
#else
- volatile unsigned char tcnt0; /* counter 0 */
+ volatile unsigned char tcnt0; /* counter 0 */
unsigned char _unused0[3];
- volatile unsigned char tcnt1; /* counter 1 */
+ volatile unsigned char tcnt1; /* counter 1 */
unsigned char _unused1[3];
- volatile unsigned char tcnt2; /* counter 2 */
+ volatile unsigned char tcnt2; /* counter 2 */
unsigned char _unused2[3];
- volatile unsigned char tcword; /* control word */
+ volatile unsigned char tcword; /* control word */
unsigned char _unused3[3];
#endif
};
@@ -156,22 +179,22 @@
struct sgi_int2_regs {
struct sgi_ioc_ints ints;
- volatile u32 ledbits; /* LED control bits */
-#define INT2_LED_TXCLK 0x01 /* GPI to TXCLK enable */
-#define INT2_LED_SERSLCT0 0x02 /* serial port0: 0=apple 1=pc */
-#define INT2_LED_SERSLCT1 0x04 /* serial port1: 0=apple 1=pc */
-#define INT2_LED_CHEAPER 0x08 /* 0=cheapernet 1=ethernet */
-#define INT2_LED_POWEROFF 0x10 /* Power-off request, active high */
+ volatile u32 ledbits; /* LED control bits */
+#define INT2_LED_TXCLK 0x01 /* GPI to TXCLK enable */
+#define INT2_LED_SERSLCT0 0x02 /* serial port0: 0=apple 1=pc */
+#define INT2_LED_SERSLCT1 0x04 /* serial port1: 0=apple 1=pc */
+#define INT2_LED_CHEAPER 0x08 /* 0=cheapernet 1=ethernet */
+#define INT2_LED_POWEROFF 0x10 /* Power-off request, active high */
#ifdef __MIPSEB__
unsigned char _unused0[3];
- volatile unsigned char tclear; /* Timer clear strobe address */
+ volatile unsigned char tclear; /* Timer clear strobe address */
#else
- volatile unsigned char tclear; /* Timer clear strobe address */
+ volatile unsigned char tclear; /* Timer clear strobe address */
unsigned char _unused0[3];
#endif
-#define INT2_TCLEAR_T0CLR 0x1 /* Clear timer0 IRQ */
-#define INT2_TCLEAR_T1CLR 0x2 /* Clear timer1 IRQ */
+#define INT2_TCLEAR_T0CLR 0x1 /* Clear timer0 IRQ */
+#define INT2_TCLEAR_T1CLR 0x2 /* Clear timer1 IRQ */
/* I am guesing there are only two unused registers here
* but I could be wrong... - andrewb
*/
@@ -185,12 +208,12 @@
#ifdef __MIPSEB__
unsigned char _unused0[3];
- volatile unsigned char tclear; /* Timer clear strobe address */
+ volatile unsigned char tclear; /* Timer clear strobe address */
#else
- volatile unsigned char tclear; /* Timer clear strobe address */
+ volatile unsigned char tclear; /* Timer clear strobe address */
unsigned char _unused0[3];
#endif
- volatile u32 estatus; /* Error status reg */
+ volatile u32 estatus; /* Error status reg */
u32 _unused1[2];
struct sgi_ioc_timers timers;
};
Index: linux/arch/mips/sgi/kernel/indy_int.c
===================================================================
RCS file: /cvs/linux/arch/mips/sgi/kernel/indy_int.c,v
retrieving revision 1.30
diff -u -r1.30 indy_int.c
--- linux/arch/mips/sgi/kernel/indy_int.c 2001/11/14 02:40:09 1.30
+++ linux/arch/mips/sgi/kernel/indy_int.c 2001/11/16 12:10:03
@@ -7,54 +7,26 @@
* Copyright (C) 1999 Andrew R. Baker (andrewb@uab.edu)
* - Indigo2 changes
* - Interrupt handling fixes
+ * Copyright (C) 2001 Ladislav Michl (ladis@psi.cz)
*/
-#include <linux/init.h>
-#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/init.h>
#include <linux/kernel_stat.h>
#include <linux/signal.h>
#include <linux/sched.h>
-#include <linux/types.h>
#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/timex.h>
-#include <linux/slab.h>
-#include <linux/random.h>
-#include <linux/smp.h>
-#include <linux/smp_lock.h>
-
-#include <asm/bitops.h>
-#include <asm/bootinfo.h>
-#include <asm/io.h>
+
#include <asm/irq.h>
#include <asm/mipsregs.h>
-#include <asm/system.h>
-
-#include <asm/ptrace.h>
-#include <asm/processor.h>
-#include <asm/sgi/sgi.h>
-#include <asm/sgi/sgihpc.h>
-#include <asm/sgi/sgint23.h>
-#include <asm/sgialib.h>
+#include <asm/addrspace.h>
#include <asm/gdb-stub.h>
-/*
- * Linux has a controller-independent x86 interrupt architecture.
- * every controller has a 'controller-template', that is used
- * by the main code to do the right thing. Each driver-visible
- * interrupt source is transparently wired to the apropriate
- * controller. Thus drivers need not be aware of the
- * interrupt-controller.
- *
- * Various interrupt controllers we handle: 8259 PIC, SMP IO-APIC,
- * PIIX4's internal 8259 PIC and SGI's Visual Workstation Cobalt (IO-)APIC.
- * (IO-APICs assumed to be messaging to Pentium local-APICs)
- *
- * the code is designed to be easily extended with new/different
- * interrupt controllers, without having to do assembly magic.
- */
+#include <asm/sgi/sgint23.h>
+#include <asm/sgi/sgihpc.h>
/* #define DEBUG_SGINT */
+#undef I_REALLY_NEED_THIS_IRQ
struct sgi_int2_regs *sgi_i2regs;
struct sgi_int3_regs *sgi_i3regs;
@@ -68,30 +40,23 @@
static char lc3msk_to_irqnr[256];
extern asmlinkage void indyIRQ(void);
+extern void do_IRQ(int irq, struct pt_regs *regs);
-/* Local IRQ's are layed out logically like this:
- *
- * 0 --> 7 == local 0 interrupts
- * 8 --> 15 == local 1 interrupts
- * 16 --> 23 == vectored level 2 interrupts
- * 24 --> 31 == vectored level 3 interrupts (not used)
- * 32 --> 40 == vectored GIO interrupts
- * 41 --> 52 == vectored HPCDMA interrupts
- */
-
static void enable_local0_irq(unsigned int irq)
{
unsigned long flags;
save_and_cli(flags);
- ioc_icontrol->imask0 |= (1 << (irq - SGINT_LOCAL0));
+ /* 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));
restore_flags(flags);
}
static unsigned int startup_local0_irq(unsigned int irq)
{
enable_local0_irq(irq);
-
return 0; /* Never anything pending */
}
@@ -129,14 +94,16 @@
unsigned long flags;
save_and_cli(flags);
- ioc_icontrol->imask1 |= (1 << (irq - SGINT_LOCAL1));
+ /* 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));
restore_flags(flags);
}
static unsigned int startup_local1_irq(unsigned int irq)
{
enable_local1_irq(irq);
-
return 0; /* Never anything pending */
}
@@ -145,7 +112,7 @@
unsigned long flags;
save_and_cli(flags);
- ioc_icontrol->imask1 &= ~(1 << (irq- SGINT_LOCAL1));
+ ioc_icontrol->imask1 &= ~(1 << (irq - SGINT_LOCAL1));
restore_flags(flags);
}
@@ -174,7 +141,7 @@
unsigned long flags;
save_and_cli(flags);
- enable_local0_irq(7);
+ ioc_icontrol->imask0 |= (1 << (SGI_MAP_0_IRQ - SGINT_LOCAL0));
ioc_icontrol->cmeimask0 |= (1 << (irq - SGINT_LOCAL2));
restore_flags(flags);
}
@@ -182,7 +149,6 @@
static unsigned int startup_local2_irq(unsigned int irq)
{
enable_local2_irq(irq);
-
return 0; /* Never anything pending */
}
@@ -192,6 +158,8 @@
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));
restore_flags(flags);
}
@@ -217,18 +185,21 @@
static void enable_local3_irq(unsigned int irq)
{
+#ifdef I_REALLY_NEED_THIS_IRQ
unsigned long flags;
-
+
save_and_cli(flags);
- printk("Yeeee, got passed irq_nr %d at enable_local3_irq\n", irq);
- panic("Invalid IRQ level!");
+ ioc_icontrol->imask1 |= (1 << (SGI_MAP_1_IRQ - SGINT_LOCAL1));
+ ioc_icontrol->cmeimask1 |= (1 << (irq - SGINT_LOCAL3));
restore_flags(flags);
+#else
+ panic("Who need local 3 irq? see indy_int.c\n");
+#endif
}
static unsigned int startup_local3_irq(unsigned int irq)
{
enable_local3_irq(irq);
-
return 0; /* Never anything pending */
}
@@ -237,12 +208,9 @@
unsigned long flags;
save_and_cli(flags);
- /*
- * This way we'll see if anyone would ever want vectored level 3
- * interrupts. Highly unlikely.
- */
- printk("Yeeee, got passed irq_nr %d at disable_local3_irq\n", irq);
- panic("Invalid IRQ level!");
+ ioc_icontrol->cmeimask1 &= ~(1 << (irq - SGINT_LOCAL3));
+ if (!ioc_icontrol->cmeimask1)
+ ioc_icontrol->imask1 &= ~(1 << (SGI_MAP_1_IRQ - SGINT_LOCAL1));
restore_flags(flags);
}
@@ -266,80 +234,6 @@
NULL
};
-void enable_gio_irq(unsigned int irq)
-{
- /* XXX TODO XXX */
-}
-
-static unsigned int startup_gio_irq(unsigned int irq)
-{
- enable_gio_irq(irq);
-
- return 0; /* Never anything pending */
-}
-
-void disable_gio_irq(unsigned int irq)
-{
- /* XXX TODO XXX */
-}
-
-#define shutdown_gio_irq disable_gio_irq
-#define mask_and_ack_gio_irq disable_gio_irq
-
-static void end_gio_irq (unsigned int irq)
-{
- if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
- enable_gio_irq(irq);
-}
-
-static struct hw_interrupt_type ip22_gio_irq_type = {
- "IP22 GIO",
- startup_gio_irq,
- shutdown_gio_irq,
- enable_gio_irq,
- disable_gio_irq,
- mask_and_ack_gio_irq,
- end_gio_irq,
- NULL
-};
-
-void enable_hpcdma_irq(unsigned int irq)
-{
- /* XXX TODO XXX */
-}
-
-static unsigned int startup_hpcdma_irq(unsigned int irq)
-{
- enable_hpcdma_irq(irq);
-
- return 0; /* Never anything pending */
-}
-
-void disable_hpcdma_irq(unsigned int irq)
-{
- /* XXX TODO XXX */
-}
-
-#define shutdown_hpcdma_irq disable_hpcdma_irq
-#define mask_and_ack_hpcdma_irq disable_hpcdma_irq
-
-static void end_hpcdma_irq (unsigned int irq)
-{
- if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
- enable_hpcdma_irq(irq);
-}
-
-static struct hw_interrupt_type ip22_hpcdma_irq_type = {
- "IP22 HPC DMA",
- startup_hpcdma_irq,
- shutdown_hpcdma_irq,
- enable_hpcdma_irq,
- disable_hpcdma_irq,
- mask_and_ack_hpcdma_irq,
- end_hpcdma_irq,
- NULL
-};
-
void indy_local0_irqdispatch(struct pt_regs *regs)
{
unsigned char mask = ioc_icontrol->istat0;
@@ -369,16 +263,17 @@
mask &= ioc_icontrol->imask1;
if (mask & ISTAT1_LIO3) {
- printk("WHee: Got an LIO3 irq, winging it...\n");
+#ifndef I_REALLY_NEED_THIS_IRQ
+ printk("Whee: Got an LIO3 irq, winging it...\n");
+#endif
mask2 = ioc_icontrol->vmeistat;
mask2 &= ioc_icontrol->cmeimask1;
- irq = lc3msk_to_irqnr[ioc_icontrol->vmeistat];
+ irq = lc3msk_to_irqnr[mask2];
} else {
irq = lc1msk_to_irqnr[mask];
}
/* if irq == 0, then the interrupt has already been cleared */
- /* not sure if it is needed here, but it is needed for local0 */
if (irq)
do_IRQ(irq, regs);
return;
@@ -387,16 +282,35 @@
void indy_buserror_irq(struct pt_regs *regs)
{
int cpu = smp_processor_id();
- int irq = 6;
+ int irq = SGI_BUSERR_IRQ;
irq_enter(cpu, irq);
- kstat.irqs[0][irq]++;
+ kstat.irqs[cpu][irq]++;
die("Got a bus error IRQ, shouldn't happen yet\n", regs);
printk("Spinning...\n");
while(1);
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 timer =
+ { no_action, SA_INTERRUPT, 0, "R4k Timer", 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 };
+#endif
+
+extern int setup_irq(unsigned int irq, struct irqaction *irqaction);
+extern void mips_cpu_irq_init(u32 irq_base);
+extern void init_generic_irq(void);
+
void __init init_IRQ(void)
{
int i;
@@ -407,45 +321,45 @@
/* Init local mask --> irq tables. */
for (i = 0; i < 256; i++) {
if (i & 0x80) {
- lc0msk_to_irqnr[i] = 7;
- lc1msk_to_irqnr[i] = 15;
- lc2msk_to_irqnr[i] = 23;
- lc3msk_to_irqnr[i] = 31;
+ lc0msk_to_irqnr[i] = SGINT_LOCAL0 + 7;
+ lc1msk_to_irqnr[i] = SGINT_LOCAL1 + 7;
+ lc2msk_to_irqnr[i] = SGINT_LOCAL2 + 7;
+ lc3msk_to_irqnr[i] = SGINT_LOCAL3 + 7;
} else if (i & 0x40) {
- lc0msk_to_irqnr[i] = 6;
- lc1msk_to_irqnr[i] = 14;
- lc2msk_to_irqnr[i] = 22;
- lc3msk_to_irqnr[i] = 30;
+ lc0msk_to_irqnr[i] = SGINT_LOCAL0 + 6;
+ lc1msk_to_irqnr[i] = SGINT_LOCAL1 + 6;
+ lc2msk_to_irqnr[i] = SGINT_LOCAL2 + 6;
+ lc3msk_to_irqnr[i] = SGINT_LOCAL3 + 6;
} else if (i & 0x20) {
- lc0msk_to_irqnr[i] = 5;
- lc1msk_to_irqnr[i] = 13;
- lc2msk_to_irqnr[i] = 21;
- lc3msk_to_irqnr[i] = 29;
+ lc0msk_to_irqnr[i] = SGINT_LOCAL0 + 5;
+ lc1msk_to_irqnr[i] = SGINT_LOCAL1 + 5;
+ lc2msk_to_irqnr[i] = SGINT_LOCAL2 + 5;
+ lc3msk_to_irqnr[i] = SGINT_LOCAL3 + 5;
} else if (i & 0x10) {
- lc0msk_to_irqnr[i] = 4;
- lc1msk_to_irqnr[i] = 12;
- lc2msk_to_irqnr[i] = 20;
- lc3msk_to_irqnr[i] = 28;
+ lc0msk_to_irqnr[i] = SGINT_LOCAL0 + 4;
+ lc1msk_to_irqnr[i] = SGINT_LOCAL1 + 4;
+ lc2msk_to_irqnr[i] = SGINT_LOCAL2 + 4;
+ lc3msk_to_irqnr[i] = SGINT_LOCAL3 + 4;
} else if (i & 0x08) {
- lc0msk_to_irqnr[i] = 3;
- lc1msk_to_irqnr[i] = 11;
- lc2msk_to_irqnr[i] = 19;
- lc3msk_to_irqnr[i] = 27;
+ lc0msk_to_irqnr[i] = SGINT_LOCAL0 + 3;
+ lc1msk_to_irqnr[i] = SGINT_LOCAL1 + 3;
+ lc2msk_to_irqnr[i] = SGINT_LOCAL2 + 3;
+ lc3msk_to_irqnr[i] = SGINT_LOCAL3 + 3;
} else if (i & 0x04) {
- lc0msk_to_irqnr[i] = 2;
- lc1msk_to_irqnr[i] = 10;
- lc2msk_to_irqnr[i] = 18;
- lc3msk_to_irqnr[i] = 26;
+ lc0msk_to_irqnr[i] = SGINT_LOCAL0 + 2;
+ lc1msk_to_irqnr[i] = SGINT_LOCAL1 + 2;
+ lc2msk_to_irqnr[i] = SGINT_LOCAL2 + 2;
+ lc3msk_to_irqnr[i] = SGINT_LOCAL3 + 2;
} else if (i & 0x02) {
- lc0msk_to_irqnr[i] = 1;
- lc1msk_to_irqnr[i] = 9;
- lc2msk_to_irqnr[i] = 17;
- lc3msk_to_irqnr[i] = 25;
+ lc0msk_to_irqnr[i] = SGINT_LOCAL0 + 1;
+ lc1msk_to_irqnr[i] = SGINT_LOCAL1 + 1;
+ lc2msk_to_irqnr[i] = SGINT_LOCAL2 + 1;
+ lc3msk_to_irqnr[i] = SGINT_LOCAL3 + 1;
} else if (i & 0x01) {
- lc0msk_to_irqnr[i] = 0;
- lc1msk_to_irqnr[i] = 8;
- lc2msk_to_irqnr[i] = 16;
- lc3msk_to_irqnr[i] = 24;
+ lc0msk_to_irqnr[i] = SGINT_LOCAL0 + 0;
+ lc1msk_to_irqnr[i] = SGINT_LOCAL1 + 0;
+ lc2msk_to_irqnr[i] = SGINT_LOCAL2 + 0;
+ lc3msk_to_irqnr[i] = SGINT_LOCAL3 + 0;
} else {
lc0msk_to_irqnr[i] = 0;
lc1msk_to_irqnr[i] = 0;
@@ -474,6 +388,8 @@
set_except_vector(0, indyIRQ);
init_generic_irq();
+ /* init CPU irqs */
+ mips_cpu_irq_init(SGINT_CPU);
for (i = SGINT_LOCAL0; i < SGINT_END; i++) {
hw_irq_controller *handler;
@@ -484,16 +400,27 @@
handler = &ip22_local1_irq_type;
else if (i < SGINT_LOCAL3)
handler = &ip22_local2_irq_type;
- else if (i < SGINT_GIO)
+ else
handler = &ip22_local3_irq_type;
- else if (i < SGINT_HPCDMA)
- handler = &ip22_gio_irq_type;
- else if (i < SGINT_END)
- handler = &ip22_hpcdma_irq_type;
irq_desc[i].status = IRQ_DISABLED;
irq_desc[i].action = 0;
irq_desc[i].depth = 1;
irq_desc[i].handler = handler;
}
+
+ /* vector handler. this register the IRQ as non-sharable */
+ setup_irq(SGI_LOCAL_0_IRQ, &local0_cascade);
+ setup_irq(SGI_LOCAL_1_IRQ, &local1_cascade);
+ setup_irq(SGI_BUSERR_IRQ, &buserr);
+/* This can't be enabled yet. we need to use CONFIG_NEW_TIME_C
+ * hopefully i'll rewrite it in couple of days. --ladis
+ setup_irq(SGI_TIMER_IRQ, &timer);
+*/
+
+ /* cascade in cascade. i love Indy ;-) */
+ setup_irq(SGI_MAP_0_IRQ, &map0_cascade);
+#ifdef I_REALLY_NEED_THIS_IRQ
+ setup_irq(SGI_MAP_1_IRQ, &map1_cascade);
+#endif
}
Index: linux/arch/mips/sgi/kernel/setup.c
===================================================================
RCS file: /cvs/linux/arch/mips/sgi/kernel/setup.c,v
retrieving revision 1.46
diff -u -r1.46 setup.c
--- linux/arch/mips/sgi/kernel/setup.c 2001/08/23 22:24:24 1.46
+++ linux/arch/mips/sgi/kernel/setup.c 2001/11/16 12:10:08
@@ -302,7 +302,4 @@
#ifdef CONFIG_PSMOUSE
aux_device_present = 0xaa;
#endif
-#ifdef CONFIG_VIDEO_VINO
- init_vino();
-#endif
}
Index: linux/arch/mips/sgi/kernel/time.c
===================================================================
RCS file: /cvs/linux/arch/mips/sgi/kernel/time.c,v
retrieving revision 1.6
diff -u -r1.6 time.c
--- linux/arch/mips/sgi/kernel/time.c 2001/03/18 04:20:23 1.6
+++ linux/arch/mips/sgi/kernel/time.c 2001/11/16 12:10:08
@@ -13,7 +13,7 @@
int irq = 4;
irq_enter(cpu, irq);
- kstat.irqs[0][irq]++;
+ kstat.irqs[cpu][irq]++;
printk("indy_8254timer_irq: Whoops, should not have gotten this IRQ\n");
prom_getchar();
ArcEnterInteractiveMode();
Index: linux/arch/mips/config.in
===================================================================
RCS file: /cvs/linux/arch/mips/config.in,v
retrieving revision 1.144
diff -u -r1.144 config.in
--- linux/arch/mips/config.in 2001/11/13 05:40:00 1.144
+++ linux/arch/mips/config.in 2001/11/16 12:43:33
@@ -177,6 +177,7 @@
define_bool CONFIG_BOARD_SCACHE y
define_bool CONFIG_PC_KEYB y
define_bool CONFIG_SGI y
+ define_bool CONFIG_IRQ_CPU y
define_bool CONFIG_NEW_IRQ y
define_bool CONFIG_OLD_TIME_C y
fi
|