diff options
author | Paul Mundt <lethal@linux-sh.org> | 2006-01-17 01:14:14 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-01-17 02:15:28 -0500 |
commit | bf3a00f88c926635932c91afd90b4a0907dfbe78 (patch) | |
tree | 179a56c061461a0f3d25cd0171ba8ce90e5e7ed5 /arch/sh/kernel/cpu/sh4 | |
parent | 9d44190eae97ad4c9ce30f1084e1b0dabd646df5 (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/sh4')
-rw-r--r-- | arch/sh/kernel/cpu/sh4/irq_intc2.c | 222 |
1 files changed, 0 insertions, 222 deletions
diff --git a/arch/sh/kernel/cpu/sh4/irq_intc2.c b/arch/sh/kernel/cpu/sh4/irq_intc2.c deleted file mode 100644 index f6b16ba01932..000000000000 --- a/arch/sh/kernel/cpu/sh4/irq_intc2.c +++ /dev/null | |||
@@ -1,222 +0,0 @@ | |||
1 | /* | ||
2 | * linux/arch/sh/kernel/irq_intc2.c | ||
3 | * | ||
4 | * Copyright (C) 2001 David J. Mckay (david.mckay@st.com) | ||
5 | * | ||
6 | * May be copied or modified under the terms of the GNU General Public | ||
7 | * License. See linux/COPYING for more information. | ||
8 | * | ||
9 | * Interrupt handling for INTC2-based IRQ. | ||
10 | * | ||
11 | * These are the "new Hitachi style" interrupts, as present on the | ||
12 | * Hitachi 7751 and the STM ST40 STB1. | ||
13 | */ | ||
14 | |||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/init.h> | ||
17 | #include <linux/irq.h> | ||
18 | |||
19 | #include <asm/system.h> | ||
20 | #include <asm/io.h> | ||
21 | #include <asm/machvec.h> | ||
22 | |||
23 | |||
24 | struct intc2_data { | ||
25 | unsigned char msk_offset; | ||
26 | unsigned char msk_shift; | ||
27 | #ifdef CONFIG_CPU_SUBTYPE_ST40 | ||
28 | int (*clear_irq) (int); | ||
29 | #endif | ||
30 | }; | ||
31 | |||
32 | |||
33 | static struct intc2_data intc2_data[NR_INTC2_IRQS]; | ||
34 | |||
35 | static void enable_intc2_irq(unsigned int irq); | ||
36 | static void disable_intc2_irq(unsigned int irq); | ||
37 | |||
38 | /* shutdown is same as "disable" */ | ||
39 | #define shutdown_intc2_irq disable_intc2_irq | ||
40 | |||
41 | static void mask_and_ack_intc2(unsigned int); | ||
42 | static void end_intc2_irq(unsigned int irq); | ||
43 | |||
44 | static unsigned int startup_intc2_irq(unsigned int irq) | ||
45 | { | ||
46 | enable_intc2_irq(irq); | ||
47 | return 0; /* never anything pending */ | ||
48 | } | ||
49 | |||
50 | static struct hw_interrupt_type intc2_irq_type = { | ||
51 | .typename = "INTC2-IRQ", | ||
52 | .startup = startup_intc2_irq, | ||
53 | .shutdown = shutdown_intc2_irq, | ||
54 | .enable = enable_intc2_irq, | ||
55 | .disable = disable_intc2_irq, | ||
56 | .ack = mask_and_ack_intc2, | ||
57 | .end = end_intc2_irq | ||
58 | }; | ||
59 | |||
60 | static void disable_intc2_irq(unsigned int irq) | ||
61 | { | ||
62 | int irq_offset = irq - INTC2_FIRST_IRQ; | ||
63 | int msk_shift, msk_offset; | ||
64 | |||
65 | // Sanity check | ||
66 | if((irq_offset<0) || (irq_offset>=NR_INTC2_IRQS)) | ||
67 | return; | ||
68 | |||
69 | msk_shift = intc2_data[irq_offset].msk_shift; | ||
70 | msk_offset = intc2_data[irq_offset].msk_offset; | ||
71 | |||
72 | ctrl_outl(1<<msk_shift, | ||
73 | INTC2_BASE+INTC2_INTMSK_OFFSET+msk_offset); | ||
74 | } | ||
75 | |||
76 | static void enable_intc2_irq(unsigned int irq) | ||
77 | { | ||
78 | int irq_offset = irq - INTC2_FIRST_IRQ; | ||
79 | int msk_shift, msk_offset; | ||
80 | |||
81 | /* Sanity check */ | ||
82 | if((irq_offset<0) || (irq_offset>=NR_INTC2_IRQS)) | ||
83 | return; | ||
84 | |||
85 | msk_shift = intc2_data[irq_offset].msk_shift; | ||
86 | msk_offset = intc2_data[irq_offset].msk_offset; | ||
87 | |||
88 | ctrl_outl(1<<msk_shift, | ||
89 | INTC2_BASE+INTC2_INTMSKCLR_OFFSET+msk_offset); | ||
90 | } | ||
91 | |||
92 | static void mask_and_ack_intc2(unsigned int irq) | ||
93 | { | ||
94 | disable_intc2_irq(irq); | ||
95 | } | ||
96 | |||
97 | static void end_intc2_irq(unsigned int irq) | ||
98 | { | ||
99 | if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) | ||
100 | enable_intc2_irq(irq); | ||
101 | |||
102 | #ifdef CONFIG_CPU_SUBTYPE_ST40 | ||
103 | if (intc2_data[irq - INTC2_FIRST_IRQ].clear_irq) | ||
104 | intc2_data[irq - INTC2_FIRST_IRQ].clear_irq (irq); | ||
105 | #endif | ||
106 | } | ||
107 | |||
108 | /* | ||
109 | * Setup an INTC2 style interrupt. | ||
110 | * NOTE: Unlike IPR interrupts, parameters are not shifted by this code, | ||
111 | * allowing the use of the numbers straight out of the datasheet. | ||
112 | * For example: | ||
113 | * PIO1 which is INTPRI00[19,16] and INTMSK00[13] | ||
114 | * would be: ^ ^ ^ ^ | ||
115 | * | | | | | ||
116 | * make_intc2_irq(84, 0, 16, 0, 13); | ||
117 | */ | ||
118 | void make_intc2_irq(unsigned int irq, | ||
119 | unsigned int ipr_offset, unsigned int ipr_shift, | ||
120 | unsigned int msk_offset, unsigned int msk_shift, | ||
121 | unsigned int priority) | ||
122 | { | ||
123 | int irq_offset = irq - INTC2_FIRST_IRQ; | ||
124 | unsigned int flags; | ||
125 | unsigned long ipr; | ||
126 | |||
127 | if((irq_offset<0) || (irq_offset>=NR_INTC2_IRQS)) | ||
128 | return; | ||
129 | |||
130 | disable_irq_nosync(irq); | ||
131 | |||
132 | /* Fill the data we need */ | ||
133 | intc2_data[irq_offset].msk_offset = msk_offset; | ||
134 | intc2_data[irq_offset].msk_shift = msk_shift; | ||
135 | #ifdef CONFIG_CPU_SUBTYPE_ST40 | ||
136 | intc2_data[irq_offset].clear_irq = NULL; | ||
137 | #endif | ||
138 | |||
139 | /* Set the priority level */ | ||
140 | local_irq_save(flags); | ||
141 | |||
142 | ipr=ctrl_inl(INTC2_BASE+INTC2_INTPRI_OFFSET+ipr_offset); | ||
143 | ipr&=~(0xf<<ipr_shift); | ||
144 | ipr|=(priority)<<ipr_shift; | ||
145 | ctrl_outl(ipr, INTC2_BASE+INTC2_INTPRI_OFFSET+ipr_offset); | ||
146 | |||
147 | local_irq_restore(flags); | ||
148 | |||
149 | irq_desc[irq].handler=&intc2_irq_type; | ||
150 | |||
151 | disable_intc2_irq(irq); | ||
152 | } | ||
153 | |||
154 | #ifdef CONFIG_CPU_SUBTYPE_ST40 | ||
155 | |||
156 | struct intc2_init { | ||
157 | unsigned short irq; | ||
158 | unsigned char ipr_offset, ipr_shift; | ||
159 | unsigned char msk_offset, msk_shift; | ||
160 | }; | ||
161 | |||
162 | static struct intc2_init intc2_init_data[] __initdata = { | ||
163 | {64, 0, 0, 0, 0}, /* PCI serr */ | ||
164 | {65, 0, 4, 0, 1}, /* PCI err */ | ||
165 | {66, 0, 4, 0, 2}, /* PCI ad */ | ||
166 | {67, 0, 4, 0, 3}, /* PCI pwd down */ | ||
167 | {72, 0, 8, 0, 5}, /* DMAC INT0 */ | ||
168 | {73, 0, 8, 0, 6}, /* DMAC INT1 */ | ||
169 | {74, 0, 8, 0, 7}, /* DMAC INT2 */ | ||
170 | {75, 0, 8, 0, 8}, /* DMAC INT3 */ | ||
171 | {76, 0, 8, 0, 9}, /* DMAC INT4 */ | ||
172 | {78, 0, 8, 0, 11}, /* DMAC ERR */ | ||
173 | {80, 0, 12, 0, 12}, /* PIO0 */ | ||
174 | {84, 0, 16, 0, 13}, /* PIO1 */ | ||
175 | {88, 0, 20, 0, 14}, /* PIO2 */ | ||
176 | {112, 4, 0, 4, 0}, /* Mailbox */ | ||
177 | #ifdef CONFIG_CPU_SUBTYPE_ST40GX1 | ||
178 | {116, 4, 4, 4, 4}, /* SSC0 */ | ||
179 | {120, 4, 8, 4, 8}, /* IR Blaster */ | ||
180 | {124, 4, 12, 4, 12}, /* USB host */ | ||
181 | {128, 4, 16, 4, 16}, /* Video processor BLITTER */ | ||
182 | {132, 4, 20, 4, 20}, /* UART0 */ | ||
183 | {134, 4, 20, 4, 22}, /* UART2 */ | ||
184 | {136, 4, 24, 4, 24}, /* IO_PIO0 */ | ||
185 | {140, 4, 28, 4, 28}, /* EMPI */ | ||
186 | {144, 8, 0, 8, 0}, /* MAFE */ | ||
187 | {148, 8, 4, 8, 4}, /* PWM */ | ||
188 | {152, 8, 8, 8, 8}, /* SSC1 */ | ||
189 | {156, 8, 12, 8, 12}, /* IO_PIO1 */ | ||
190 | {160, 8, 16, 8, 16}, /* USB target */ | ||
191 | {164, 8, 20, 8, 20}, /* UART1 */ | ||
192 | {168, 8, 24, 8, 24}, /* Teletext */ | ||
193 | {172, 8, 28, 8, 28}, /* VideoSync VTG */ | ||
194 | {173, 8, 28, 8, 29}, /* VideoSync DVP0 */ | ||
195 | {174, 8, 28, 8, 30}, /* VideoSync DVP1 */ | ||
196 | #endif | ||
197 | }; | ||
198 | |||
199 | void __init init_IRQ_intc2(void) | ||
200 | { | ||
201 | struct intc2_init *p; | ||
202 | |||
203 | printk(KERN_ALERT "init_IRQ_intc2\n"); | ||
204 | |||
205 | for (p = intc2_init_data; | ||
206 | p<intc2_init_data+ARRAY_SIZE(intc2_init_data); | ||
207 | p++) { | ||
208 | make_intc2_irq(p->irq, p->ipr_offset, p->ipr_shift, | ||
209 | p-> msk_offset, p->msk_shift, 13); | ||
210 | } | ||
211 | } | ||
212 | |||
213 | /* Adds a termination callback to the interrupt */ | ||
214 | void intc2_add_clear_irq(int irq, int (*fn)(int)) | ||
215 | { | ||
216 | if (irq < INTC2_FIRST_IRQ) | ||
217 | return; | ||
218 | |||
219 | intc2_data[irq - INTC2_FIRST_IRQ].clear_irq = fn; | ||
220 | } | ||
221 | |||
222 | #endif /* CONFIG_CPU_SUBTYPE_ST40 */ | ||