patch-2.4.0-test2 linux/arch/arm/kernel/irq.c

Next file: linux/arch/arm/kernel/leds-ebsa110.c
Previous file: linux/arch/arm/kernel/ioport.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.0-test1/linux/arch/arm/kernel/irq.c linux/arch/arm/kernel/irq.c
@@ -15,7 +15,7 @@
  * IRQ's are in fact implemented a bit like signal handlers for the kernel.
  * Naturally it's not a 1:1 relation, but there are similarities.
  */
-#include <linux/config.h> /* for CONFIG_DEBUG_ERRORS */
+#include <linux/config.h>
 #include <linux/ptrace.h>
 #include <linux/errno.h>
 #include <linux/kernel_stat.h>
@@ -33,13 +33,6 @@
 #include <asm/io.h>
 #include <asm/system.h>
 
-#ifndef SMP
-#define irq_enter(cpu, irq)	(++local_irq_count[cpu])
-#define irq_exit(cpu, irq)	(--local_irq_count[cpu])
-#else
-#error SMP not supported
-#endif
-
 #ifndef cliIF
 #define cliIF()
 #endif
@@ -85,6 +78,7 @@
 };
 
 static struct irqdesc irq_desc[NR_IRQS];
+static volatile unsigned long irq_err_count;
 
 /*
  * Get architecture specific interrupt handlers
@@ -133,8 +127,8 @@
 	    	action = irq_desc[i].action;
 		if (!action)
 			continue;
-		p += sprintf(p, "%3d: %10u   %s",
-			     i, kstat_irqs(i), action->name);
+		p += sprintf(p, "%3d: %10u ", i, kstat_irqs(i));
+		p += sprintf(p, "  %s", action->name);
 		for (action = action->next; action; action = action->next) {
 			p += sprintf(p, ", %s", action->name);
 		}
@@ -144,6 +138,7 @@
 #ifdef CONFIG_ARCH_ACORN
 	p += get_fiq_list(p);
 #endif
+	p += sprintf(p, "Err: %10lu\n", irq_err_count);
 	return p - buf;
 }
 
@@ -181,10 +176,17 @@
 {
 	struct irqdesc * desc;
 	struct irqaction * action;
-	int status, cpu;
+	int cpu;
 
 	irq = fixup_irq(irq);
 
+	/*
+	 * Some hardware gives randomly wrong interrupts.  Rather
+	 * than crashing, do something sensible.
+	 */
+	if (irq >= NR_IRQS)
+		goto bad_irq;
+
 	desc = irq_desc + irq;
 
 	spin_lock(&irq_controller_lock);
@@ -197,10 +199,11 @@
 	desc->triggered = 1;
 
 	/* Return with this interrupt masked if no action */
-	status = 0;
 	action = desc->action;
 
 	if (action) {
+		int status = 0;
+
 		if (desc->nomask) {
 			spin_lock(&irq_controller_lock);
 			desc->unmask(irq);
@@ -237,9 +240,15 @@
 
 	if (softirq_state[cpu].active & softirq_state[cpu].mask)
 		do_softirq();
+	return;
+
+bad_irq:
+	irq_err_count += 1;
+	printk(KERN_ERR "IRQ: spurious interrupt %d\n", irq);
+	return;
 }
 
-#if defined(CONFIG_ARCH_ACORN)
+#ifdef CONFIG_ARCH_ACORN
 void do_ecard_IRQ(int irq, struct pt_regs *regs)
 {
 	struct irqdesc * desc;

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)