aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sh/kernel/cpu/irq/imask.c
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2006-01-17 01:14:14 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-01-17 02:15:28 -0500
commitbf3a00f88c926635932c91afd90b4a0907dfbe78 (patch)
tree179a56c061461a0f3d25cd0171ba8ce90e5e7ed5 /arch/sh/kernel/cpu/irq/imask.c
parent9d44190eae97ad4c9ce30f1084e1b0dabd646df5 (diff)
[PATCH] sh: IRQ handler updates
This moves the various IRQ controller drivers into a new subdirectory, and also extends the INTC2 IRQ handler to also deal with SH7760 and SH7780 interrupts, rather than just ST-40. The old CONFIG_SH_GENERIC has also been removed from the IRQ definitions, as new ports are expected to be based off of CONFIG_SH_UNKNOWN. Since there are plenty of incompatible machvecs, CONFIG_SH_GENERIC doesn't make sense anymore. Signed-off-by: Paul Mundt <lethal@linux-sh.org> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/sh/kernel/cpu/irq/imask.c')
-rw-r--r--arch/sh/kernel/cpu/irq/imask.c110
1 files changed, 110 insertions, 0 deletions
diff --git a/arch/sh/kernel/cpu/irq/imask.c b/arch/sh/kernel/cpu/irq/imask.c
new file mode 100644
index 000000000000..baed9a550d39
--- /dev/null
+++ b/arch/sh/kernel/cpu/irq/imask.c
@@ -0,0 +1,110 @@
1/*
2 * arch/sh/kernel/cpu/irq/imask.c
3 *
4 * Copyright (C) 1999, 2000 Niibe Yutaka
5 *
6 * Simple interrupt handling using IMASK of SR register.
7 *
8 */
9/* NOTE: Will not work on level 15 */
10#include <linux/ptrace.h>
11#include <linux/errno.h>
12#include <linux/kernel_stat.h>
13#include <linux/signal.h>
14#include <linux/sched.h>
15#include <linux/interrupt.h>
16#include <linux/init.h>
17#include <linux/bitops.h>
18#include <linux/spinlock.h>
19#include <linux/cache.h>
20#include <linux/irq.h>
21#include <asm/system.h>
22#include <asm/irq.h>
23
24/* Bitmap of IRQ masked */
25static unsigned long imask_mask = 0x7fff;
26static int interrupt_priority = 0;
27
28static void enable_imask_irq(unsigned int irq);
29static void disable_imask_irq(unsigned int irq);
30static void shutdown_imask_irq(unsigned int irq);
31static void mask_and_ack_imask(unsigned int);
32static void end_imask_irq(unsigned int irq);
33
34#define IMASK_PRIORITY 15
35
36static unsigned int startup_imask_irq(unsigned int irq)
37{
38 /* Nothing to do */
39 return 0; /* never anything pending */
40}
41
42static struct hw_interrupt_type imask_irq_type = {
43 .typename = "SR.IMASK",
44 .startup = startup_imask_irq,
45 .shutdown = shutdown_imask_irq,
46 .enable = enable_imask_irq,
47 .disable = disable_imask_irq,
48 .ack = mask_and_ack_imask,
49 .end = end_imask_irq
50};
51
52void static inline set_interrupt_registers(int ip)
53{
54 unsigned long __dummy;
55
56 asm volatile("ldc %2, r6_bank\n\t"
57 "stc sr, %0\n\t"
58 "and #0xf0, %0\n\t"
59 "shlr2 %0\n\t"
60 "cmp/eq #0x3c, %0\n\t"
61 "bt/s 1f ! CLI-ed\n\t"
62 " stc sr, %0\n\t"
63 "and %1, %0\n\t"
64 "or %2, %0\n\t"
65 "ldc %0, sr\n"
66 "1:"
67 : "=&z" (__dummy)
68 : "r" (~0xf0), "r" (ip << 4)
69 : "t");
70}
71
72static void disable_imask_irq(unsigned int irq)
73{
74 clear_bit(irq, &imask_mask);
75 if (interrupt_priority < IMASK_PRIORITY - irq)
76 interrupt_priority = IMASK_PRIORITY - irq;
77
78 set_interrupt_registers(interrupt_priority);
79}
80
81static void enable_imask_irq(unsigned int irq)
82{
83 set_bit(irq, &imask_mask);
84 interrupt_priority = IMASK_PRIORITY - ffz(imask_mask);
85
86 set_interrupt_registers(interrupt_priority);
87}
88
89static void mask_and_ack_imask(unsigned int irq)
90{
91 disable_imask_irq(irq);
92}
93
94static void end_imask_irq(unsigned int irq)
95{
96 if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
97 enable_imask_irq(irq);
98}
99
100static void shutdown_imask_irq(unsigned int irq)
101{
102 /* Nothing to do */
103}
104
105void make_imask_irq(unsigned int irq)
106{
107 disable_irq_nosync(irq);
108 irq_desc[irq].handler = &imask_irq_type;
109 enable_irq(irq);
110}