patch-2.1.110 linux/arch/arm/kernel/irq.c

Next file: linux/arch/arm/kernel/process.c
Previous file: linux/arch/arm/kernel/iic.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.109/linux/arch/arm/kernel/irq.c linux/arch/arm/kernel/irq.c
@@ -2,7 +2,8 @@
  *  linux/arch/arm/kernel/irq.c
  *
  *  Copyright (C) 1992 Linus Torvalds
- *  Modifications for ARM processor Copyright (C) 1995, 1996 Russell King.
+ *  Modifications for ARM processor Copyright (C) 1995-1998 Russell King.
+ *  FIQ support written by Philip Blundell <philb@gnu.org>, 1998.
  *
  * This file contains the code used by various IRQ handling routines:
  * asking for different IRQ's should be done through these routines
@@ -30,14 +31,20 @@
 #include <linux/smp_lock.h>
 #include <linux/init.h>
 
+#include <asm/fiq.h>
+#include <asm/hardware.h>
 #include <asm/io.h>
+#include <asm/pgtable.h>
 #include <asm/system.h>
-#include <asm/hardware.h>
 #include <asm/arch/irq.h>
 
 unsigned int local_bh_count[NR_CPUS];
 unsigned int local_irq_count[NR_CPUS];
 spinlock_t irq_controller_lock;
+static struct fiq_handler *current_fiq;
+static unsigned long no_fiq_insn;
+
+#define FIQ_VECTOR ((unsigned long *)0x1c)
 
 #ifndef SMP
 #define irq_enter(cpu, irq)	(++local_irq_count[cpu])
@@ -46,6 +53,20 @@
 #error SMP not supported
 #endif
 
+#ifdef CONFIG_ARCH_ACORN
+/* Bitmask indicating valid interrupt numbers
+ * (to be moved to include/asm-arm/arch-*)
+ */
+unsigned long validirqs[NR_IRQS / 32] = {
+	0x003ffe7f,	0x000001ff,	0x000000ff,	0x00000000
+};
+
+#define valid_irq(x) ((x) < NR_IRQS && validirqs[(x) >> 5] & (1 << ((x) & 31)))
+#else
+
+#define valid_irq(x) ((x) < NR_IRQS)
+#endif
+
 void disable_irq(unsigned int irq_nr)
 {
 	unsigned long flags;
@@ -74,21 +95,6 @@
 
 struct irqaction *irq_action[NR_IRQS];
 
-#ifdef CONFIG_ARCH_ACORN
-/* Bitmask indicating valid interrupt numbers
- * (to be moved to include/asm-arm/arch-*)
- */
-unsigned long validirqs[NR_IRQS / 32] = {
-	0x003ffe7f,	0x000001ff,	0x000000ff,	0x00000000
-};
-
-#define valid_irq(x) ((x) < NR_IRQS && validirqs[(x) >> 5] & (1 << ((x) & 31)))
-#else
-
-#define valid_irq(x) ((x) < NR_IRQS)
-
-#endif
-
 int get_irq_list(char *buf)
 {
 	int i;
@@ -106,6 +112,8 @@
 		}
 		*p++ = '\n';
 	}
+	p += sprintf(p, "FIQ:              %s\n",
+		     current_fiq?current_fiq->name:"unused");
 	return p - buf;
 }
 
@@ -186,7 +194,7 @@
 	}
 }
 
-#if defined(HAS_IOMD) || defined(HAS_IOC)
+#if defined(CONFIG_ARCH_ACORN)
 void do_ecard_IRQ(int irq, struct pt_regs *regs)
 {
 	struct irqaction * action;
@@ -336,9 +344,41 @@
 	return i;
 }
 
+int claim_fiq(struct fiq_handler *f)
+{
+	if (current_fiq) {
+		if (current_fiq->callback == NULL || (*current_fiq->callback)())
+			return -EBUSY;
+	}
+	current_fiq = f;
+	return 0;
+}
+
+void release_fiq(struct fiq_handler *f)
+{
+	if (current_fiq != f) {
+		printk(KERN_ERR "%s tried to release FIQ when not owner!\n",
+		       f->name);
+#ifdef CONFIG_DEBUG_ERRORS
+		__backtrace();
+#endif
+		return;
+	}
+	current_fiq = NULL;
+
+	*FIQ_VECTOR = no_fiq_insn;
+	__flush_entry_to_ram(FIQ_VECTOR);
+}
+
 __initfunc(void init_IRQ(void))
 {
 	extern void init_dma(void);
+
 	irq_init_irq();
+
+	current_fiq = NULL;
+	no_fiq_insn = *FIQ_VECTOR;
+
 	init_dma();
 }
+

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov