MOXA linux-2.6.x / linux-2.6.9-uc0 from sdlinux-moxaart.tgz
[linux-2.6.9-moxart.git] / arch / arm / mach-moxacpu / cpe_int.c
blobc2bcfa2ca354eba3e15b8eed3ca50999fc766caa
1 #include <linux/module.h>
2 #include <linux/init.h>
3 #include <linux/ioport.h>
5 #include <asm/mach/irq.h>
6 #include <asm/hardware.h>
7 #include <asm/io.h>
8 #include <asm/irq.h>
9 #include <asm/system.h>
10 #include <asm/arch/cpe/cpe.h>
11 #include <asm/arch/ftpci.h>
13 //#define VICTOR_LOCK_IRQ // add by Victor Yu. 07-25-2007
15 static spinlock_t cpe_int_lock;
17 #if 0 // mask by Victor Yu. 07-25-2007
18 inline void cpe_irq_set_mode(unsigned int base_p,unsigned int irq,unsigned int edge)
19 #else
20 static void cpe_irq_set_mode(unsigned int base_p,unsigned int irq,unsigned int edge)
21 #endif
23 if ( edge )
24 *(volatile unsigned int *)(base_p+IRQ_MODE_REG)|=(1<<irq);
25 else
26 *(volatile unsigned int *)(base_p+IRQ_MODE_REG)&=~(1<<irq);
29 #if 0 // mask by Victor Yu. 07-25-2007
30 inline void cpe_irq_set_level(unsigned int base_p,unsigned int irq,unsigned int low)
31 #else
32 static void cpe_irq_set_level(unsigned int base_p,unsigned int irq,unsigned int low)
33 #endif
35 if ( low )
36 *(volatile unsigned int *)(base_p+IRQ_LEVEL_REG)|=(1<<irq);
37 else
38 *(volatile unsigned int *)(base_p+IRQ_LEVEL_REG)&=~(1<<irq);
41 #if 0 // mask by Victor Yu. 07-25-2007
42 inline void cpe_fiq_set_mode(unsigned int base_p,unsigned int fiq,unsigned int edge)
43 #else
44 static void cpe_fiq_set_mode(unsigned int base_p,unsigned int fiq,unsigned int edge)
45 #endif
47 if ( edge )
48 *(volatile unsigned int *)(base_p+FIQ_MODE_REG)|=(1<<fiq);
49 else
50 *(volatile unsigned int *)(base_p+FIQ_MODE_REG)&=~(1<<fiq);
53 #if 0 // mask by Victor Yu. 07-25-2007
54 inline void cpe_fiq_set_level(unsigned int base_p,unsigned int fiq,unsigned int low)
55 #else
56 static void cpe_fiq_set_level(unsigned int base_p,unsigned int fiq,unsigned int low)
57 #endif
59 if ( low )
60 *(volatile unsigned int *)(base_p+FIQ_LEVEL_REG)|=(1<<fiq);
61 else
62 *(volatile unsigned int *)(base_p+FIQ_LEVEL_REG)&=~(1<<fiq);
66 void cpe_int_set_irq(unsigned int irq,int mode,int level)
68 unsigned long flags;
70 spin_lock_irqsave(&cpe_int_lock, flags);
71 if ( irq < 32 ) { //irq
72 #ifdef CONFIG_PCI // add by Victor Yu. 05-23-2006
73 if ( irq == IRQ_PCI )
74 goto cpe_int_set_irq_exit;
75 #endif
76 cpe_irq_set_mode(CPE_IC_VA_BASE,irq ,mode);
77 cpe_irq_set_level(CPE_IC_VA_BASE,irq,level);
78 goto cpe_int_set_irq_exit;
80 if ( irq < 64 ) { //fiq
81 irq-=32;
82 #ifdef CONFIG_PCI // add by Victor Yu. 05-23-2006
83 if ( irq == IRQ_PCI )
84 goto cpe_int_set_irq_exit;
85 #endif
86 cpe_fiq_set_mode(CPE_IC_VA_BASE,irq,mode);
87 cpe_fiq_set_level(CPE_IC_VA_BASE,irq,level);
88 goto cpe_int_set_irq_exit;
91 #ifdef CONFIG_ARCH_CPE
92 if ( irq < 96 ) { //a321 irq
93 irq-=64;
94 cpe_irq_set_mode(CPE_A321_IC_VA_BASE,irq,mode);
95 cpe_irq_set_level(CPE_A321_IC_VA_BASE,irq,level);
96 cpe_irq_set_mode(CPE_IC_VA_BASE,IRQ_EXT_A321,LEVEL);
97 cpe_irq_set_level(CPE_IC_VA_BASE,IRQ_EXT_A321,H_ACTIVE);
98 goto cpe_int_set_irq_exit;
100 if ( irq < 150 ) { //a321 fiq
101 irq-=96;
102 cpe_fiq_set_mode(CPE_A321_IC_VA_BASE,irq,mode);
103 cpe_fiq_set_level(CPE_A321_IC_VA_BASE,irq,level);
104 cpe_fiq_set_mode(CPE_IC_VA_BASE,IRQ_EXT_A321,LEVEL);
105 cpe_fiq_set_level(CPE_IC_VA_BASE,IRQ_EXT_A321,H_ACTIVE);
106 goto cpe_int_set_irq_exit;
109 #ifdef CONFIG_PCI
110 //pci virtual irq
111 if ( (irq==VIRQ_PCI_A)||(irq==VIRQ_PCI_B)||(irq==VIRQ_PCI_C)||(irq==VIRQ_PCI_D) ) {
112 if( !ftpci_probed )
113 goto cpe_int_set_irq_exit;
114 cpe_irq_set_mode(CPE_A321_IC_VA_BASE,IRQ_A321_PCI,mode);
115 cpe_irq_set_level(CPE_A321_IC_VA_BASE,IRQ_A321_PCI,level);
116 cpe_irq_set_mode(CPE_IC_VA_BASE,IRQ_EXT_A321,LEVEL);
117 cpe_irq_set_level(CPE_IC_VA_BASE,IRQ_EXT_A321,H_ACTIVE);
118 #if 1 // add by Victor Yu. 10-20-2005
119 goto cpe_int_set_irq_exit;
120 #endif // 10-20-2005
122 #endif // CONFIG_PCI
123 #endif // CONFIG_ARCH_CPE
125 #ifdef CONFIG_ARCH_MOXACPU
126 #ifdef CONFIG_PCI
127 //pci virtual irq
128 if ( (irq==VIRQ_PCI_A)||(irq==VIRQ_PCI_B)||(irq==VIRQ_PCI_C)||(irq==VIRQ_PCI_D) ) {
129 if( !ftpci_probed )
130 goto cpe_int_set_irq_exit;
131 cpe_irq_set_mode(CPE_IC_VA_BASE,IRQ_PCI,LEVEL);
132 cpe_irq_set_level(CPE_IC_VA_BASE,IRQ_PCI,H_ACTIVE);
133 //goto cpe_int_set_irq_exit;
135 #endif // CONFIG_PCI
136 #endif // CONFIG_ARCH_MOXACPU
138 //printk("Not support irq %d\n",irq);
140 cpe_int_set_irq_exit:
141 spin_unlock_irqrestore(&cpe_int_lock, flags);
144 static void cpe_int_clear_irq(unsigned int base,unsigned int irq)
146 *(volatile unsigned int *)(base+IRQ_CLEAR_REG)=1<<irq;
149 static void cpe_int_clear_fiq(unsigned int base,unsigned int irq)
151 *(volatile unsigned int *)(base+FIQ_CLEAR_REG)=1<<irq;
154 #if 0 // mask by Victor Yu. 07-25-2007
155 inline void cpe_int_disable_irq(unsigned int base,unsigned int irq)
156 #else
157 static void cpe_int_disable_irq(unsigned int base,unsigned int irq)
158 #endif
160 *(volatile unsigned int *)(base+IRQ_MASK_REG)&=~(1<<irq);
163 #if 0 // mask by Victor Yu. 07-25-2007
164 inline void cpe_int_disable_fiq(unsigned int base,unsigned int irq)
165 #else
166 static void cpe_int_disable_fiq(unsigned int base,unsigned int irq)
167 #endif
169 *(volatile unsigned int *)(base+FIQ_MASK_REG)&=~(1<<irq);
172 /* Turn the interrupt source on. */
173 #if 0 // mask by Victor Yu. 07-25-2007
174 inline void cpe_int_enable_irq(unsigned int base,unsigned int irq)
175 #else
176 static void cpe_int_enable_irq(unsigned int base,unsigned int irq)
177 #endif
179 *(volatile unsigned int *)(base+IRQ_MASK_REG)|=(1<<irq);
182 #if 0 // mask by Victor Yu. 07-25-2007
183 inline void cpe_int_enable_fiq(unsigned int base,unsigned int irq)
184 #else
185 static void cpe_int_enable_fiq(unsigned int base,unsigned int irq)
186 #endif
188 *(volatile unsigned int *)(base+FIQ_MASK_REG)|=(1<<irq);
191 static void cpe_unmask_irq(unsigned int irq)
193 #ifdef VICTOR_LOCK_IRQ // add by Victor Yu. 07-25-2007
194 unsigned long flags;
195 #endif
197 #ifdef VICTOR_LOCK_IRQ // add by Victor Yu. 07-25-2007
198 spin_lock_irqsave(&cpe_int_lock, flags);
199 #else
200 spin_lock(&cpe_int_lock);
201 #endif
202 if ( irq < 32 ) { //irq
203 #ifdef CONFIG_PCI // add by Victor Yu. 05-23-2006
204 if ( irq == IRQ_PCI )
205 goto cpe_unmask_irq_exit;
206 #endif
207 cpe_int_clear_irq(CPE_IC_VA_BASE,irq);
208 cpe_int_enable_irq(CPE_IC_VA_BASE,irq);
209 goto cpe_unmask_irq_exit;
211 if ( irq < 64 ) { //fiq
212 irq-=32;
213 #ifdef CONFIG_PCI // add by Victor Yu. 05-23-2006
214 if ( irq == IRQ_PCI )
215 goto cpe_unmask_irq_exit;
216 #endif
217 cpe_int_clear_fiq(CPE_IC_VA_BASE,irq);
218 cpe_int_enable_fiq(CPE_IC_VA_BASE,irq);
219 goto cpe_unmask_irq_exit;
222 #ifdef CONFIG_ARCH_CPE
223 if ( irq < 96 ) { //a321 irq
224 irq-=64;
225 cpe_int_clear_irq(CPE_A321_IC_VA_BASE,irq);
226 cpe_int_clear_irq(CPE_IC_VA_BASE,IRQ_EXT_A321);
227 cpe_int_enable_irq(CPE_A321_IC_VA_BASE,irq);
228 cpe_int_enable_irq(CPE_IC_VA_BASE,IRQ_EXT_A321);
229 goto cpe_unmask_irq_exit;
231 if ( irq < 150 ) { //a321 fiq
232 irq-=96;
233 cpe_int_clear_fiq(CPE_A321_IC_VA_BASE,irq);
234 cpe_int_clear_fiq(CPE_IC_VA_BASE,IRQ_EXT_A321);
235 cpe_int_enable_fiq(CPE_A321_IC_VA_BASE,irq);
236 cpe_int_enable_fiq(CPE_IC_VA_BASE,IRQ_EXT_A321);
237 goto cpe_unmask_irq_exit;
240 #ifdef CONFIG_PCI
241 //pci virtual irq
242 if( (irq==VIRQ_PCI_A)||(irq==VIRQ_PCI_B)||(irq==VIRQ_PCI_C)||(irq==VIRQ_PCI_D) ) {
243 if( !ftpci_probed )
244 goto cpe_unmask_irq_exit;
245 ftpci_clear_irq(irq-150);
246 cpe_int_clear_irq(CPE_A321_IC_VA_BASE,IRQ_A321_PCI);
247 cpe_int_enable_irq(CPE_A321_IC_VA_BASE,IRQ_A321_PCI); //always enabled
248 cpe_int_clear_irq(CPE_IC_VA_BASE,IRQ_EXT_A321);
249 cpe_int_enable_irq(CPE_IC_VA_BASE,IRQ_EXT_A321); //always enabled
250 goto cpe_unmask_irq_exit;
252 #endif // CONFIG_PCI
253 #endif // CONFIG_ARCH_CPE
255 #ifdef CONFIG_ARCH_MOXACPU
256 #ifdef CONFIG_PCI
257 //pci virtual irq
258 if( (irq==VIRQ_PCI_A)||(irq==VIRQ_PCI_B)||(irq==VIRQ_PCI_C)||(irq==VIRQ_PCI_D) ) {
259 if( !ftpci_probed )
260 goto cpe_unmask_irq_exit;
261 ftpci_clear_irq(irq-CPE_VIRQ_START);
262 cpe_int_clear_irq(CPE_IC_VA_BASE,IRQ_PCI);
263 cpe_int_enable_irq(CPE_IC_VA_BASE,IRQ_PCI); //always enabled
264 //goto cpe_unmask_irq_exit;
266 #endif // CONFIG_PCI
267 #endif // CONFIG_ARCH_MOXACPU
269 cpe_unmask_irq_exit:
270 #ifdef VICTOR_LOCK_IRQ // add by Victor Yu. 07-25-2007
271 spin_unlock_irqrestore(&cpe_int_lock, flags);
272 #else
273 spin_unlock(&cpe_int_lock);
274 #endif
275 return;
278 static void cpe_mask_ack_irq(unsigned int irq)
280 #ifdef VICTOR_LOCK_IRQ // add by Victor Yu. 07-25-2007
281 unsigned long flags;
282 #endif
284 #ifdef VICTOR_LOCK_IRQ // add by Victor Yu. 07-25-2007
285 spin_lock_irqsave(&cpe_int_lock, flags);
286 #else
287 spin_lock(&cpe_int_lock);
288 #endif
289 if ( irq < 32 ) { //irq
290 #ifdef CONFIG_PCI // add by Victor Yu. 05-23-2006
291 if ( irq == IRQ_PCI )
292 goto cpe_mask_ack_irq_exit;
293 #endif
294 cpe_int_disable_irq(CPE_IC_VA_BASE,irq);
295 goto cpe_mask_ack_irq_exit;
298 if ( irq < 64 ) { //fiq
299 irq-=32;
300 #ifdef CONFIG_PCI // add by Victor Yu. 05-23-2006
301 if ( irq == IRQ_PCI )
302 goto cpe_mask_ack_irq_exit;
303 #endif
304 cpe_int_disable_fiq(CPE_IC_VA_BASE,irq);
305 goto cpe_mask_ack_irq_exit;
308 #ifdef CONFIG_ARCH_CPE
309 if ( irq < 96 ) { //a321 irq
310 irq-=64;
311 cpe_int_disable_irq(CPE_A321_IC_VA_BASE,irq);
312 goto cpe_mask_ack_irq_exit;
314 if ( irq < 150 ) { //a321 fiq
315 irq-=96;
316 cpe_int_disable_fiq(CPE_A321_IC_VA_BASE,irq);
317 goto cpe_mask_ack_irq_exit;
319 #ifdef CONFIG_PCI
320 //pci virtual irq
321 if( (irq==VIRQ_PCI_A)||(irq==VIRQ_PCI_B)||(irq==VIRQ_PCI_C)||(irq==VIRQ_PCI_D) ) {
322 if( !ftpci_probed )
323 goto cpe_mask_ack_irq_exit;
324 cpe_int_disable_irq(CPE_A321_IC_VA_BASE,IRQ_A321_PCI); //always enabled
325 goto cpe_mask_ack_irq_exit;
327 #endif // CONFIG_PCI
328 #endif // CONFIG_ARCH_CPE
330 #ifdef CONFIG_ARCH_MOXACPU
331 #ifdef CONFIG_PCI
332 //pci virtual irq
333 if( (irq==VIRQ_PCI_A)||(irq==VIRQ_PCI_B)||(irq==VIRQ_PCI_C)||(irq==VIRQ_PCI_D) ) {
334 if( !ftpci_probed )
335 goto cpe_mask_ack_irq_exit;
336 cpe_int_disable_irq(CPE_IC_VA_BASE,IRQ_PCI);
337 //goto cpe_mask_ack_irq_exit;
339 #endif // CONFIG_PCI
340 #endif // CONFIG_ARCH_MOXACPU
342 cpe_mask_ack_irq_exit:
343 #ifdef VICTOR_LOCK_IRQ // add by Victor Yu. 07-25-2007
344 spin_unlock_irqrestore(&cpe_int_lock, flags);
345 #else
346 spin_unlock(&cpe_int_lock);
347 #endif
348 return;
351 #if 0 // mask by Victor Yu. 07-25-2007
352 static void cpe_mask_irq(unsigned int irq)
354 cpe_mask_ack_irq(irq);
356 #endif
358 void cpe_int_init(void)
360 #if 1 // add by Victor Yu. 07-26-2007
361 unsigned long flags;
362 #endif
364 spin_lock_init(&cpe_int_lock);
365 //init interrupt controller
366 #if 1 // add by Victor Yu. 07-26-2007
367 spin_lock_irqsave(&cpe_int_lock, flags);
368 #endif
369 outl(0, CPE_IC_VA_BASE+IRQ_MASK_REG);
370 outl(0, CPE_IC_VA_BASE+FIQ_MASK_REG);
371 outl(0xffffffff, CPE_IC_VA_BASE+IRQ_CLEAR_REG);
372 outl(0xffffffff, CPE_IC_VA_BASE+FIQ_CLEAR_REG);
373 #if 1 // add by Victor Yu. 07-26-2007
374 spin_unlock_irqrestore(&cpe_int_lock, flags);
375 #endif
376 #ifdef CONFIG_ARCH_MOXACPU
377 #ifdef CONFIG_PCI
378 cpe_int_set_irq(IRQ_PCI, LEVEL, H_ACTIVE);
379 #if 0 // mask by Victor Yu. 05-23-2006
380 cpe_int_enable_irq(CPE_IC_VA_BASE,IRQ_PCI); //always enabled
381 #endif
382 #endif
383 #endif
385 #ifdef CONFIG_ARCH_CPE
386 //init a321 interrupt controller
387 outl(0, CPE_A321_IC_VA_BASE+IRQ_MASK_REG);
388 outl(0, CPE_A321_IC_VA_BASE+FIQ_MASK_REG);
389 outl(0xffffffff, CPE_A321_IC_VA_BASE+IRQ_CLEAR_REG);
390 outl(0xffffffff, CPE_A321_IC_VA_BASE+FIQ_CLEAR_REG);
391 cpe_int_set_irq(IRQ_EXT_A321, LEVEL, H_ACTIVE);
392 cpe_int_enable_irq(CPE_IC_VA_BASE,IRQ_EXT_A321);
393 #endif // CONFIG_ARCH_CPE
396 #if 1 // add by Victor Yu. 05-17-2005
397 #include <asm/arch/irq.h>
398 struct irqchip cpe_irq_chip = {
399 .ack = cpe_mask_ack_irq,
400 #if 0 // mask by Victor Yu. 07-25-2007
401 .mask = cpe_mask_irq,
402 #else
403 .mask = cpe_mask_ack_irq,
404 #endif
405 .unmask = cpe_unmask_irq,
407 #endif
409 EXPORT_SYMBOL(cpe_int_set_irq);
410 EXPORT_SYMBOL(cpe_int_clear_irq);