summaryrefslogtreecommitdiffstats
path: root/arch/cris/arch-v10/kernel/irq.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/cris/arch-v10/kernel/irq.c')
-rw-r--r--arch/cris/arch-v10/kernel/irq.c76
1 files changed, 43 insertions, 33 deletions
diff --git a/arch/cris/arch-v10/kernel/irq.c b/arch/cris/arch-v10/kernel/irq.c
index b2f16d6fc87..4b368a12201 100644
--- a/arch/cris/arch-v10/kernel/irq.c
+++ b/arch/cris/arch-v10/kernel/irq.c
@@ -1,4 +1,4 @@
-/* $Id: irq.c,v 1.2 2004/06/09 05:30:27 starvik Exp $
+/* $Id: irq.c,v 1.4 2005/01/04 12:22:28 starvik Exp $
*
* linux/arch/cris/kernel/irq.c
*
@@ -12,11 +12,13 @@
*/
#include <asm/irq.h>
+#include <linux/irq.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/config.h>
-irqvectptr irq_shortcuts[NR_IRQS]; /* vector of shortcut jumps after the irq prologue */
+#define mask_irq(irq_nr) (*R_VECT_MASK_CLR = 1 << (irq_nr));
+#define unmask_irq(irq_nr) (*R_VECT_MASK_SET = 1 << (irq_nr));
/* don't use set_int_vector, it bypasses the linux interrupt handlers. it is
* global just so that the kernel gdb can use it.
@@ -102,41 +104,52 @@ static void (*interrupt[NR_IRQS])(void) = {
IRQ31_interrupt
};
-static void (*bad_interrupt[NR_IRQS])(void) = {
- NULL, NULL,
- NULL, bad_IRQ3_interrupt,
- bad_IRQ4_interrupt, bad_IRQ5_interrupt,
- bad_IRQ6_interrupt, bad_IRQ7_interrupt,
- bad_IRQ8_interrupt, bad_IRQ9_interrupt,
- bad_IRQ10_interrupt, bad_IRQ11_interrupt,
- bad_IRQ12_interrupt, bad_IRQ13_interrupt,
- NULL, NULL,
- bad_IRQ16_interrupt, bad_IRQ17_interrupt,
- bad_IRQ18_interrupt, bad_IRQ19_interrupt,
- bad_IRQ20_interrupt, bad_IRQ21_interrupt,
- bad_IRQ22_interrupt, bad_IRQ23_interrupt,
- bad_IRQ24_interrupt, bad_IRQ25_interrupt,
- NULL, NULL, NULL, NULL, NULL,
- bad_IRQ31_interrupt
-};
+static void enable_crisv10_irq(unsigned int irq);
+
+static unsigned int startup_crisv10_irq(unsigned int irq)
+{
+ enable_crisv10_irq(irq);
+ return 0;
+}
+
+#define shutdown_crisv10_irq disable_crisv10_irq
-void arch_setup_irq(int irq)
+static void enable_crisv10_irq(unsigned int irq)
{
- set_int_vector(irq, interrupt[irq]);
+ unmask_irq(irq);
}
-void arch_free_irq(int irq)
+static void disable_crisv10_irq(unsigned int irq)
{
- set_int_vector(irq, bad_interrupt[irq]);
+ mask_irq(irq);
}
+static void ack_crisv10_irq(unsigned int irq)
+{
+}
+
+static void end_crisv10_irq(unsigned int irq)
+{
+}
+
+static struct hw_interrupt_type crisv10_irq_type = {
+ .typename = "CRISv10",
+ .startup = startup_crisv10_irq,
+ .shutdown = shutdown_crisv10_irq,
+ .enable = enable_crisv10_irq,
+ .disable = disable_crisv10_irq,
+ .ack = ack_crisv10_irq,
+ .end = end_crisv10_irq,
+ .set_affinity = NULL
+};
+
void weird_irq(void);
void system_call(void); /* from entry.S */
void do_sigtrap(void); /* from entry.S */
void gdb_handle_breakpoint(void); /* from entry.S */
/* init_IRQ() is called by start_kernel and is responsible for fixing IRQ masks and
- setting the irq vector table to point to bad_interrupt ptrs.
+ setting the irq vector table.
*/
void __init
@@ -154,14 +167,15 @@ init_IRQ(void)
*R_VECT_MASK_CLR = 0xffffffff;
- /* clear the shortcut entry points */
-
- for(i = 0; i < NR_IRQS; i++)
- irq_shortcuts[i] = NULL;
-
for (i = 0; i < 256; i++)
etrax_irv->v[i] = weird_irq;
+ /* Initialize IRQ handler descriptiors. */
+ for(i = 2; i < NR_IRQS; i++) {
+ irq_desc[i].handler = &crisv10_irq_type;
+ set_int_vector(i, interrupt[i]);
+ }
+
/* the entries in the break vector contain actual code to be
executed by the associated break handler, rather than just a jump
address. therefore we need to setup a default breakpoint handler
@@ -170,10 +184,6 @@ init_IRQ(void)
for (i = 0; i < 16; i++)
set_break_vector(i, do_sigtrap);
- /* set all etrax irq's to the bad handlers */
- for (i = 2; i < NR_IRQS; i++)
- set_int_vector(i, bad_interrupt[i]);
-
/* except IRQ 15 which is the multiple-IRQ handler on Etrax100 */
set_int_vector(15, multiple_interrupt);