patch-2.4.19 linux-2.4.19/arch/mips64/sgi-ip32/ip32-irq.c
Next file: linux-2.4.19/arch/mips64/sgi-ip32/ip32-pci-dma.c
Previous file: linux-2.4.19/arch/mips64/sgi-ip32/ip32-berr.c
Back to the patch index
Back to the overall index
- Lines: 459
- Date:
Fri Aug 2 17:39:43 2002
- Orig file:
linux-2.4.18/arch/mips64/sgi-ip32/ip32-irq.c
- Orig date:
Sun Sep 9 10:43:02 2001
diff -urN linux-2.4.18/arch/mips64/sgi-ip32/ip32-irq.c linux-2.4.19/arch/mips64/sgi-ip32/ip32-irq.c
@@ -12,8 +12,12 @@
#include <linux/kernel_stat.h>
#include <linux/types.h>
#include <linux/interrupt.h>
-#include <linux/irq.h>
#include <linux/bitops.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/mm.h>
+#include <linux/random.h>
+#include <linux/sched.h>
#include <asm/bitops.h>
#include <asm/mipsregs.h>
@@ -110,30 +114,31 @@
0, "CRIME CPU error", NULL,
NULL };
-unsigned long spurious_count = 0;
extern void ip32_handle_int (void);
-extern void do_IRQ (unsigned int irq, struct pt_regs *regs);
+asmlinkage unsigned int do_IRQ(int irq, struct pt_regs *regs);
-/* For interrupts wired from a single device to the CPU. Only the clock
+/*
+ * For interrupts wired from a single device to the CPU. Only the clock
* uses this it seems, which is IRQ 0 and IP7.
*/
-static void enable_cpu_irq (unsigned int irq)
+static void enable_cpu_irq(unsigned int irq)
{
- set_cp0_status (STATUSF_IP7);
+ set_cp0_status(STATUSF_IP7);
}
-static unsigned int startup_cpu_irq (unsigned int irq) {
- enable_cpu_irq (irq);
+static unsigned int startup_cpu_irq(unsigned int irq)
+{
+ enable_cpu_irq(irq);
return 0;
}
-static void disable_cpu_irq (unsigned int irq)
+static void disable_cpu_irq(unsigned int irq)
{
- clear_cp0_status (STATUSF_IP7);
+ clear_cp0_status(STATUSF_IP7);
}
-static void end_cpu_irq (unsigned int irq)
+static void end_cpu_irq(unsigned int irq)
{
if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
enable_cpu_irq (irq);
@@ -158,34 +163,34 @@
* We get to split the register in half and do faster lookups.
*/
-static void enable_crime_irq (unsigned int irq)
+static void enable_crime_irq(unsigned int irq)
{
u64 crime_mask;
unsigned long flags;
- save_and_cli (flags);
- crime_mask = crime_read_64 (CRIME_INT_MASK);
+ save_and_cli(flags);
+ crime_mask = crime_read_64(CRIME_INT_MASK);
crime_mask |= 1 << (irq - 1);
- crime_write_64 (CRIME_INT_MASK, crime_mask);
- restore_flags (flags);
+ crime_write_64(CRIME_INT_MASK, crime_mask);
+ restore_flags(flags);
}
-static unsigned int startup_crime_irq (unsigned int irq)
+static unsigned int startup_crime_irq(unsigned int irq)
{
- enable_crime_irq (irq);
+ enable_crime_irq(irq);
return 0; /* This is probably not right; we could have pending irqs */
}
-static void disable_crime_irq (unsigned int irq)
+static void disable_crime_irq(unsigned int irq)
{
u64 crime_mask;
unsigned long flags;
- save_and_cli (flags);
- crime_mask = crime_read_64 (CRIME_INT_MASK);
+ save_and_cli(flags);
+ crime_mask = crime_read_64(CRIME_INT_MASK);
crime_mask &= ~(1 << (irq - 1));
- crime_write_64 (CRIME_INT_MASK, crime_mask);
- restore_flags (flags);
+ crime_write_64(CRIME_INT_MASK, crime_mask);
+ restore_flags(flags);
}
static void mask_and_ack_crime_irq (unsigned int irq)
@@ -197,16 +202,16 @@
if ((irq <= CRIME_GBE0_IRQ && irq >= CRIME_GBE3_IRQ)
|| (irq <= CRIME_RE_EMPTY_E_IRQ && irq >= CRIME_RE_IDLE_E_IRQ)
|| (irq <= CRIME_SOFT0_IRQ && irq >= CRIME_SOFT2_IRQ)) {
- save_and_cli (flags);
- crime_mask = crime_read_64 (CRIME_HARD_INT);
+ save_and_cli(flags);
+ crime_mask = crime_read_64(CRIME_HARD_INT);
crime_mask &= ~(1 << (irq - 1));
- crime_write_64 (CRIME_HARD_INT, crime_mask);
- restore_flags (flags);
+ crime_write_64(CRIME_HARD_INT, crime_mask);
+ restore_flags(flags);
}
- disable_crime_irq (irq);
+ disable_crime_irq(irq);
}
-
-static void end_crime_irq (unsigned int irq)
+
+static void end_crime_irq(unsigned int irq)
{
if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
enable_crime_irq (irq);
@@ -225,48 +230,52 @@
NULL
};
-/* This is for MACE PCI interrupts. We can decrease bus traffic by masking
+/*
+ * This is for MACE PCI interrupts. We can decrease bus traffic by masking
* as close to the source as possible. This also means we can take the
* next chunk of the CRIME register in one piece.
*/
-static void enable_macepci_irq (unsigned int irq)
+static void enable_macepci_irq(unsigned int irq)
{
u32 mace_mask;
u64 crime_mask;
unsigned long flags;
- save_and_cli (flags);
- mace_mask = mace_read_32 (MACEPCI_CONTROL);
- mace_mask |= MACEPCI_CONTROL_INT (irq - 9);
- mace_write_32 (MACEPCI_CONTROL, mace_mask);
- /* In case the CRIME interrupt isn't enabled, we must enable it;
+ save_and_cli(flags);
+ mace_mask = mace_read_32(MACEPCI_CONTROL);
+ mace_mask |= MACEPCI_CONTROL_INT(irq - 9);
+ mace_write_32(MACEPCI_CONTROL, mace_mask);
+ /*
+ * In case the CRIME interrupt isn't enabled, we must enable it;
* however, we never disable interrupts at that level.
*/
- crime_mask = crime_read_64 (CRIME_INT_MASK);
+ crime_mask = crime_read_64(CRIME_INT_MASK);
crime_mask |= 1 << (irq - 1);
- crime_write_64 (CRIME_INT_MASK, crime_mask);
- restore_flags (flags);
+ crime_write_64(CRIME_INT_MASK, crime_mask);
+ restore_flags(flags);
}
-static unsigned int startup_macepci_irq (unsigned int irq) {
+static unsigned int startup_macepci_irq(unsigned int irq)
+{
enable_macepci_irq (irq);
+
return 0; /* XXX */
}
-static void disable_macepci_irq (unsigned int irq)
+static void disable_macepci_irq(unsigned int irq)
{
u32 mace_mask;
unsigned long flags;
- save_and_cli (flags);
- mace_mask = mace_read_32 (MACEPCI_CONTROL);
- mace_mask &= ~MACEPCI_CONTROL_INT (irq - 9);
- mace_write_32 (MACEPCI_CONTROL, mace_mask);
- restore_flags (flags);
+ save_and_cli(flags);
+ mace_mask = mace_read_32(MACEPCI_CONTROL);
+ mace_mask &= ~MACEPCI_CONTROL_INT(irq - 9);
+ mace_write_32(MACEPCI_CONTROL, mace_mask);
+ restore_flags(flags);
}
-static void end_macepci_irq (unsigned int irq)
+static void end_macepci_irq(unsigned int irq)
{
if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
enable_macepci_irq (irq);
@@ -311,34 +320,35 @@
break;
}
DBG ("crime_int %016lx enabled\n", crime_int);
- save_and_cli (flags);
- crime_mask = crime_read_64 (CRIME_INT_MASK);
+ save_and_cli(flags);
+ crime_mask = crime_read_64(CRIME_INT_MASK);
crime_mask |= crime_int;
- crime_write_64 (CRIME_INT_MASK, crime_mask);
- mace_mask = mace_read_32 (MACEISA_INT_MASK);
+ crime_write_64(CRIME_INT_MASK, crime_mask);
+ mace_mask = mace_read_32(MACEISA_INT_MASK);
mace_mask |= 1 << (irq - 33);
- mace_write_32 (MACEISA_INT_MASK, mace_mask);
- restore_flags (flags);
+ mace_write_32(MACEISA_INT_MASK, mace_mask);
+ restore_flags(flags);
}
-static unsigned int startup_maceisa_irq (unsigned int irq) {
- enable_maceisa_irq (irq);
+static unsigned int startup_maceisa_irq (unsigned int irq)
+{
+ enable_maceisa_irq(irq);
return 0;
}
-static void disable_maceisa_irq (unsigned int irq)
+static void disable_maceisa_irq(unsigned int irq)
{
u32 mace_mask;
unsigned long flags;
save_and_cli (flags);
- mace_mask = mace_read_32 (MACEISA_INT_MASK);
+ mace_mask = mace_read_32(MACEISA_INT_MASK);
mace_mask &= ~(1 << (irq - 33));
- mace_write_32 (MACEISA_INT_MASK, mace_mask);
- restore_flags (flags);
+ mace_write_32(MACEISA_INT_MASK, mace_mask);
+ restore_flags(flags);
}
-static void mask_and_ack_maceisa_irq (unsigned int irq)
+static void mask_and_ack_maceisa_irq(unsigned int irq)
{
u32 mace_mask;
unsigned long flags;
@@ -347,17 +357,17 @@
case MACEISA_PARALLEL_IRQ:
case MACEISA_SERIAL1_TDMAPR_IRQ:
case MACEISA_SERIAL2_TDMAPR_IRQ:
- save_and_cli (flags);
- mace_mask = mace_read_32 (MACEISA_INT_STAT);
+ save_and_cli(flags);
+ mace_mask = mace_read_32(MACEISA_INT_STAT);
mace_mask &= ~(1 << (irq - 33));
- mace_write_32 (MACEISA_INT_STAT, mace_mask);
- restore_flags (flags);
+ mace_write_32(MACEISA_INT_STAT, mace_mask);
+ restore_flags(flags);
break;
}
- disable_maceisa_irq (irq);
+ disable_maceisa_irq(irq);
}
-static void end_maceisa_irq (unsigned irq)
+static void end_maceisa_irq(unsigned irq)
{
if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
enable_maceisa_irq (irq);
@@ -380,7 +390,7 @@
* bits 0-3 and 7 in the CRIME register.
*/
-static void enable_mace_irq (unsigned int irq)
+static void enable_mace_irq(unsigned int irq)
{
u64 crime_mask;
unsigned long flags;
@@ -392,13 +402,13 @@
restore_flags (flags);
}
-static unsigned int startup_mace_irq (unsigned int irq)
+static unsigned int startup_mace_irq(unsigned int irq)
{
- enable_mace_irq (irq);
+ enable_mace_irq(irq);
return 0;
}
-static void disable_mace_irq (unsigned int irq)
+static void disable_mace_irq(unsigned int irq)
{
u64 crime_mask;
unsigned long flags;
@@ -407,10 +417,10 @@
crime_mask = crime_read_64 (CRIME_INT_MASK);
crime_mask &= ~(1 << (irq - 1));
crime_write_64 (CRIME_INT_MASK, crime_mask);
- restore_flags (flags);
+ restore_flags(flags);
}
-static void end_mace_irq (unsigned int irq)
+static void end_mace_irq(unsigned int irq)
{
if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
enable_mace_irq (irq);
@@ -452,56 +462,16 @@
mace = mace_read_32 (MACEPCI_CONTROL);
printk ("MACE PCI control register: %08x\n", mace);
- printk ("Register dump:\n");
- show_regs (regs);
+ printk("Register dump:\n");
+ show_regs(regs);
- printk ("Please mail this report to linux-mips@oss.sgi.com\n");
- printk ("Spinning...");
- while (1) ;
-}
-
-void __init ip32_irq_init(void)
-{
- unsigned int irq;
- extern void init_generic_irq (void);
-
- /* Install our interrupt handler, then clear and disable all
- * CRIME and MACE interrupts.
- */
- crime_write_64 (CRIME_INT_MASK, 0);
- crime_write_64 (CRIME_HARD_INT, 0);
- crime_write_64 (CRIME_SOFT_INT, 0);
- mace_write_32 (MACEISA_INT_STAT, 0);
- mace_write_32 (MACEISA_INT_MASK, 0);
- set_except_vector(0, ip32_handle_int);
-
- init_generic_irq ();
-
- for (irq = 0; irq <= IP32_IRQ_MAX; irq++) {
- hw_irq_controller *controller;
-
- if (irq == CLOCK_IRQ)
- controller = &ip32_cpu_interrupt;
- else if (irq <= MACE_PCI_BRIDGE_IRQ && irq >= MACE_VID_IN1_IRQ)
- controller = &ip32_mace_interrupt;
- else if (irq <= MACEPCI_SHARED2_IRQ && irq >= MACEPCI_SCSI0_IRQ)
- controller = &ip32_macepci_interrupt;
- else if (irq <= CRIME_VICE_IRQ && irq >= CRIME_GBE0_IRQ)
- controller = &ip32_crime_interrupt;
- else
- controller = &ip32_maceisa_interrupt;
-
- irq_desc[irq].status = IRQ_DISABLED;
- irq_desc[irq].action = 0;
- irq_desc[irq].depth = 0;
- irq_desc[irq].handler = controller;
- }
- setup_irq (CRIME_MEMERR_IRQ, &memerr_irq);
- setup_irq (CRIME_CPUERR_IRQ, &cpuerr_irq);
+ printk("Please mail this report to linux-mips@oss.sgi.com\n");
+ printk("Spinning...");
+ while(1) ;
}
/* CRIME 1.1 appears to deliver all interrupts to this one pin. */
-void ip32_irq0 (struct pt_regs *regs)
+void ip32_irq0(struct pt_regs *regs)
{
u64 crime_int = crime_read_64 (CRIME_INT_STAT);
int irq = 0;
@@ -525,32 +495,77 @@
irq = ffs (crime_int) + 16;
}
if (irq == 0)
- ip32_unknown_interrupt (regs);
- DBG ("*irq %u*\n", irq);
- do_IRQ (irq, regs);
+ ip32_unknown_interrupt(regs);
+ DBG("*irq %u*\n", irq);
+ do_IRQ(irq, regs);
}
-void ip32_irq1 (struct pt_regs *regs)
+void ip32_irq1(struct pt_regs *regs)
{
ip32_unknown_interrupt (regs);
}
-void ip32_irq2 (struct pt_regs *regs)
+void ip32_irq2(struct pt_regs *regs)
{
ip32_unknown_interrupt (regs);
}
-void ip32_irq3 (struct pt_regs *regs)
+void ip32_irq3(struct pt_regs *regs)
{
ip32_unknown_interrupt (regs);
}
-void ip32_irq4 (struct pt_regs *regs)
+void ip32_irq4(struct pt_regs *regs)
{
ip32_unknown_interrupt (regs);
}
-void ip32_irq5 (struct pt_regs *regs)
+void ip32_irq5(struct pt_regs *regs)
{
do_IRQ (CLOCK_IRQ, regs);
}
+
+void __init init_IRQ(void)
+{
+ unsigned int irq;
+ int i;
+
+ /* Install our interrupt handler, then clear and disable all
+ * CRIME and MACE interrupts.
+ */
+ crime_write_64(CRIME_INT_MASK, 0);
+ crime_write_64(CRIME_HARD_INT, 0);
+ crime_write_64(CRIME_SOFT_INT, 0);
+ mace_write_32(MACEISA_INT_STAT, 0);
+ mace_write_32(MACEISA_INT_MASK, 0);
+ set_except_vector(0, ip32_handle_int);
+
+ for (i = 0; i < NR_IRQS; i++) {
+ irq_desc[i].status = IRQ_DISABLED;
+ irq_desc[i].action = NULL;
+ irq_desc[i].depth = 1;
+ irq_desc[i].handler = &no_irq_type;
+ }
+
+ for (irq = 0; irq <= IP32_IRQ_MAX; irq++) {
+ hw_irq_controller *controller;
+
+ if (irq == CLOCK_IRQ)
+ controller = &ip32_cpu_interrupt;
+ else if (irq <= MACE_PCI_BRIDGE_IRQ && irq >= MACE_VID_IN1_IRQ)
+ controller = &ip32_mace_interrupt;
+ else if (irq <= MACEPCI_SHARED2_IRQ && irq >= MACEPCI_SCSI0_IRQ)
+ controller = &ip32_macepci_interrupt;
+ else if (irq <= CRIME_VICE_IRQ && irq >= CRIME_GBE0_IRQ)
+ controller = &ip32_crime_interrupt;
+ else
+ controller = &ip32_maceisa_interrupt;
+
+ irq_desc[irq].status = IRQ_DISABLED;
+ irq_desc[irq].action = 0;
+ irq_desc[irq].depth = 0;
+ irq_desc[irq].handler = controller;
+ }
+ setup_irq(CRIME_MEMERR_IRQ, &memerr_irq);
+ setup_irq(CRIME_CPUERR_IRQ, &cpuerr_irq);
+}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)