diff options
Diffstat (limited to 'arch/mips/tx4938/common/irq.c')
-rw-r--r-- | arch/mips/tx4938/common/irq.c | 279 |
1 files changed, 9 insertions, 270 deletions
diff --git a/arch/mips/tx4938/common/irq.c b/arch/mips/tx4938/common/irq.c index 3a2dbfc25014..c059b899d120 100644 --- a/arch/mips/tx4938/common/irq.c +++ b/arch/mips/tx4938/common/irq.c | |||
@@ -11,284 +11,21 @@ | |||
11 | * | 11 | * |
12 | * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com) | 12 | * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com) |
13 | */ | 13 | */ |
14 | #include <linux/errno.h> | ||
15 | #include <linux/init.h> | 14 | #include <linux/init.h> |
16 | #include <linux/kernel_stat.h> | ||
17 | #include <linux/module.h> | ||
18 | #include <linux/signal.h> | ||
19 | #include <linux/sched.h> | ||
20 | #include <linux/types.h> | ||
21 | #include <linux/interrupt.h> | 15 | #include <linux/interrupt.h> |
22 | #include <linux/ioport.h> | 16 | #include <asm/irq_cpu.h> |
23 | #include <linux/timex.h> | ||
24 | #include <linux/slab.h> | ||
25 | #include <linux/random.h> | ||
26 | #include <linux/irq.h> | ||
27 | #include <asm/bitops.h> | ||
28 | #include <asm/bootinfo.h> | ||
29 | #include <asm/io.h> | ||
30 | #include <asm/irq.h> | ||
31 | #include <asm/mipsregs.h> | 17 | #include <asm/mipsregs.h> |
32 | #include <asm/system.h> | ||
33 | #include <asm/wbflush.h> | ||
34 | #include <asm/tx4938/rbtx4938.h> | 18 | #include <asm/tx4938/rbtx4938.h> |
35 | 19 | ||
36 | /**********************************************************************************/ | ||
37 | /* Forwad definitions for all pic's */ | ||
38 | /**********************************************************************************/ | ||
39 | |||
40 | static void tx4938_irq_cp0_enable(unsigned int irq); | ||
41 | static void tx4938_irq_cp0_disable(unsigned int irq); | ||
42 | |||
43 | static void tx4938_irq_pic_enable(unsigned int irq); | ||
44 | static void tx4938_irq_pic_disable(unsigned int irq); | ||
45 | |||
46 | /**********************************************************************************/ | ||
47 | /* Kernel structs for all pic's */ | ||
48 | /**********************************************************************************/ | ||
49 | |||
50 | #define TX4938_CP0_NAME "TX4938-CP0" | ||
51 | static struct irq_chip tx4938_irq_cp0_type = { | ||
52 | .name = TX4938_CP0_NAME, | ||
53 | .ack = tx4938_irq_cp0_disable, | ||
54 | .mask = tx4938_irq_cp0_disable, | ||
55 | .mask_ack = tx4938_irq_cp0_disable, | ||
56 | .unmask = tx4938_irq_cp0_enable, | ||
57 | }; | ||
58 | |||
59 | #define TX4938_PIC_NAME "TX4938-PIC" | ||
60 | static struct irq_chip tx4938_irq_pic_type = { | ||
61 | .name = TX4938_PIC_NAME, | ||
62 | .ack = tx4938_irq_pic_disable, | ||
63 | .mask = tx4938_irq_pic_disable, | ||
64 | .mask_ack = tx4938_irq_pic_disable, | ||
65 | .unmask = tx4938_irq_pic_enable, | ||
66 | }; | ||
67 | |||
68 | static struct irqaction tx4938_irq_pic_action = { | ||
69 | .handler = no_action, | ||
70 | .flags = 0, | ||
71 | .mask = CPU_MASK_NONE, | ||
72 | .name = TX4938_PIC_NAME | ||
73 | }; | ||
74 | |||
75 | /**********************************************************************************/ | ||
76 | /* Functions for cp0 */ | ||
77 | /**********************************************************************************/ | ||
78 | |||
79 | #define tx4938_irq_cp0_mask(irq) ( 1 << ( irq-TX4938_IRQ_CP0_BEG+8 ) ) | ||
80 | |||
81 | static void __init | ||
82 | tx4938_irq_cp0_init(void) | ||
83 | { | ||
84 | int i; | ||
85 | |||
86 | for (i = TX4938_IRQ_CP0_BEG; i <= TX4938_IRQ_CP0_END; i++) | ||
87 | set_irq_chip_and_handler(i, &tx4938_irq_cp0_type, | ||
88 | handle_level_irq); | ||
89 | } | ||
90 | |||
91 | static void | ||
92 | tx4938_irq_cp0_enable(unsigned int irq) | ||
93 | { | ||
94 | set_c0_status(tx4938_irq_cp0_mask(irq)); | ||
95 | } | ||
96 | |||
97 | static void | ||
98 | tx4938_irq_cp0_disable(unsigned int irq) | ||
99 | { | ||
100 | clear_c0_status(tx4938_irq_cp0_mask(irq)); | ||
101 | } | ||
102 | |||
103 | /**********************************************************************************/ | ||
104 | /* Functions for pic */ | ||
105 | /**********************************************************************************/ | ||
106 | |||
107 | u32 | ||
108 | tx4938_irq_pic_addr(int irq) | ||
109 | { | ||
110 | /* MVMCP -- need to formulize this */ | ||
111 | irq -= TX4938_IRQ_PIC_BEG; | ||
112 | |||
113 | switch (irq) { | ||
114 | case 17: | ||
115 | case 16: | ||
116 | case 1: | ||
117 | case 0:{ | ||
118 | return (TX4938_MKA(TX4938_IRC_IRLVL0)); | ||
119 | } | ||
120 | case 19: | ||
121 | case 18: | ||
122 | case 3: | ||
123 | case 2:{ | ||
124 | return (TX4938_MKA(TX4938_IRC_IRLVL1)); | ||
125 | } | ||
126 | case 21: | ||
127 | case 20: | ||
128 | case 5: | ||
129 | case 4:{ | ||
130 | return (TX4938_MKA(TX4938_IRC_IRLVL2)); | ||
131 | } | ||
132 | case 23: | ||
133 | case 22: | ||
134 | case 7: | ||
135 | case 6:{ | ||
136 | return (TX4938_MKA(TX4938_IRC_IRLVL3)); | ||
137 | } | ||
138 | case 25: | ||
139 | case 24: | ||
140 | case 9: | ||
141 | case 8:{ | ||
142 | return (TX4938_MKA(TX4938_IRC_IRLVL4)); | ||
143 | } | ||
144 | case 27: | ||
145 | case 26: | ||
146 | case 11: | ||
147 | case 10:{ | ||
148 | return (TX4938_MKA(TX4938_IRC_IRLVL5)); | ||
149 | } | ||
150 | case 29: | ||
151 | case 28: | ||
152 | case 13: | ||
153 | case 12:{ | ||
154 | return (TX4938_MKA(TX4938_IRC_IRLVL6)); | ||
155 | } | ||
156 | case 31: | ||
157 | case 30: | ||
158 | case 15: | ||
159 | case 14:{ | ||
160 | return (TX4938_MKA(TX4938_IRC_IRLVL7)); | ||
161 | } | ||
162 | } | ||
163 | |||
164 | return 0; | ||
165 | } | ||
166 | |||
167 | u32 | ||
168 | tx4938_irq_pic_mask(int irq) | ||
169 | { | ||
170 | /* MVMCP -- need to formulize this */ | ||
171 | irq -= TX4938_IRQ_PIC_BEG; | ||
172 | |||
173 | switch (irq) { | ||
174 | case 31: | ||
175 | case 29: | ||
176 | case 27: | ||
177 | case 25: | ||
178 | case 23: | ||
179 | case 21: | ||
180 | case 19: | ||
181 | case 17:{ | ||
182 | return (0x07000000); | ||
183 | } | ||
184 | case 30: | ||
185 | case 28: | ||
186 | case 26: | ||
187 | case 24: | ||
188 | case 22: | ||
189 | case 20: | ||
190 | case 18: | ||
191 | case 16:{ | ||
192 | return (0x00070000); | ||
193 | } | ||
194 | case 15: | ||
195 | case 13: | ||
196 | case 11: | ||
197 | case 9: | ||
198 | case 7: | ||
199 | case 5: | ||
200 | case 3: | ||
201 | case 1:{ | ||
202 | return (0x00000700); | ||
203 | } | ||
204 | case 14: | ||
205 | case 12: | ||
206 | case 10: | ||
207 | case 8: | ||
208 | case 6: | ||
209 | case 4: | ||
210 | case 2: | ||
211 | case 0:{ | ||
212 | return (0x00000007); | ||
213 | } | ||
214 | } | ||
215 | return 0x00000000; | ||
216 | } | ||
217 | |||
218 | static void | ||
219 | tx4938_irq_pic_modify(unsigned pic_reg, unsigned clr_bits, unsigned set_bits) | ||
220 | { | ||
221 | unsigned long val = 0; | ||
222 | |||
223 | val = TX4938_RD(pic_reg); | ||
224 | val &= (~clr_bits); | ||
225 | val |= (set_bits); | ||
226 | TX4938_WR(pic_reg, val); | ||
227 | mmiowb(); | ||
228 | TX4938_RD(pic_reg); | ||
229 | } | ||
230 | |||
231 | static void __init | ||
232 | tx4938_irq_pic_init(void) | ||
233 | { | ||
234 | int i; | ||
235 | |||
236 | for (i = TX4938_IRQ_PIC_BEG; i <= TX4938_IRQ_PIC_END; i++) | ||
237 | set_irq_chip_and_handler(i, &tx4938_irq_pic_type, | ||
238 | handle_level_irq); | ||
239 | |||
240 | setup_irq(TX4938_IRQ_NEST_PIC_ON_CP0, &tx4938_irq_pic_action); | ||
241 | |||
242 | TX4938_WR(0xff1ff640, 0x6); /* irq level mask -- only accept hightest */ | ||
243 | TX4938_WR(0xff1ff600, TX4938_RD(0xff1ff600) | 0x1); /* irq enable */ | ||
244 | } | ||
245 | |||
246 | static void | ||
247 | tx4938_irq_pic_enable(unsigned int irq) | ||
248 | { | ||
249 | tx4938_irq_pic_modify(tx4938_irq_pic_addr(irq), 0, | ||
250 | tx4938_irq_pic_mask(irq)); | ||
251 | } | ||
252 | |||
253 | static void | ||
254 | tx4938_irq_pic_disable(unsigned int irq) | ||
255 | { | ||
256 | tx4938_irq_pic_modify(tx4938_irq_pic_addr(irq), | ||
257 | tx4938_irq_pic_mask(irq), 0); | ||
258 | } | ||
259 | |||
260 | /**********************************************************************************/ | ||
261 | /* Main init functions */ | ||
262 | /**********************************************************************************/ | ||
263 | |||
264 | void __init | 20 | void __init |
265 | tx4938_irq_init(void) | 21 | tx4938_irq_init(void) |
266 | { | 22 | { |
267 | tx4938_irq_cp0_init(); | 23 | mips_cpu_irq_init(); |
268 | tx4938_irq_pic_init(); | 24 | txx9_irq_init(TX4938_IRC_REG); |
25 | set_irq_chained_handler(TX4938_IRQ_NEST_PIC_ON_CP0, handle_simple_irq); | ||
269 | } | 26 | } |
270 | 27 | ||
271 | int | 28 | int toshiba_rbtx4938_irq_nested(int irq); |
272 | tx4938_irq_nested(void) | ||
273 | { | ||
274 | int sw_irq = 0; | ||
275 | u32 level2; | ||
276 | |||
277 | level2 = TX4938_RD(0xff1ff6a0); | ||
278 | if ((level2 & 0x10000) == 0) { | ||
279 | level2 &= 0x1f; | ||
280 | sw_irq = TX4938_IRQ_PIC_BEG + level2; | ||
281 | if (sw_irq == 26) { | ||
282 | { | ||
283 | extern int toshiba_rbtx4938_irq_nested(int sw_irq); | ||
284 | sw_irq = toshiba_rbtx4938_irq_nested(sw_irq); | ||
285 | } | ||
286 | } | ||
287 | } | ||
288 | |||
289 | wbflush(); | ||
290 | return sw_irq; | ||
291 | } | ||
292 | 29 | ||
293 | asmlinkage void plat_irq_dispatch(void) | 30 | asmlinkage void plat_irq_dispatch(void) |
294 | { | 31 | { |
@@ -297,8 +34,10 @@ asmlinkage void plat_irq_dispatch(void) | |||
297 | if (pending & STATUSF_IP7) | 34 | if (pending & STATUSF_IP7) |
298 | do_IRQ(TX4938_IRQ_CPU_TIMER); | 35 | do_IRQ(TX4938_IRQ_CPU_TIMER); |
299 | else if (pending & STATUSF_IP2) { | 36 | else if (pending & STATUSF_IP2) { |
300 | int irq = tx4938_irq_nested(); | 37 | int irq = txx9_irq(); |
301 | if (irq) | 38 | if (irq == TX4938_IRQ_PIC_BEG + TX4938_IR_INT(0)) |
39 | irq = toshiba_rbtx4938_irq_nested(irq); | ||
40 | if (irq >= 0) | ||
302 | do_IRQ(irq); | 41 | do_IRQ(irq); |
303 | else | 42 | else |
304 | spurious_interrupt(); | 43 | spurious_interrupt(); |