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>
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
)
20 static void cpe_irq_set_mode(unsigned int base_p
,unsigned int irq
,unsigned int edge
)
24 *(volatile unsigned int *)(base_p
+IRQ_MODE_REG
)|=(1<<irq
);
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
)
32 static void cpe_irq_set_level(unsigned int base_p
,unsigned int irq
,unsigned int low
)
36 *(volatile unsigned int *)(base_p
+IRQ_LEVEL_REG
)|=(1<<irq
);
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
)
44 static void cpe_fiq_set_mode(unsigned int base_p
,unsigned int fiq
,unsigned int edge
)
48 *(volatile unsigned int *)(base_p
+FIQ_MODE_REG
)|=(1<<fiq
);
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
)
56 static void cpe_fiq_set_level(unsigned int base_p
,unsigned int fiq
,unsigned int low
)
60 *(volatile unsigned int *)(base_p
+FIQ_LEVEL_REG
)|=(1<<fiq
);
62 *(volatile unsigned int *)(base_p
+FIQ_LEVEL_REG
)&=~(1<<fiq
);
66 void cpe_int_set_irq(unsigned int irq
,int mode
,int level
)
70 spin_lock_irqsave(&cpe_int_lock
, flags
);
71 if ( irq
< 32 ) { //irq
72 #ifdef CONFIG_PCI // add by Victor Yu. 05-23-2006
74 goto cpe_int_set_irq_exit
;
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
82 #ifdef CONFIG_PCI // add by Victor Yu. 05-23-2006
84 goto cpe_int_set_irq_exit
;
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
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
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
;
111 if ( (irq
==VIRQ_PCI_A
)||(irq
==VIRQ_PCI_B
)||(irq
==VIRQ_PCI_C
)||(irq
==VIRQ_PCI_D
) ) {
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
;
123 #endif // CONFIG_ARCH_CPE
125 #ifdef CONFIG_ARCH_MOXACPU
128 if ( (irq
==VIRQ_PCI_A
)||(irq
==VIRQ_PCI_B
)||(irq
==VIRQ_PCI_C
)||(irq
==VIRQ_PCI_D
) ) {
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;
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
)
157 static void cpe_int_disable_irq(unsigned int base
,unsigned int irq
)
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
)
166 static void cpe_int_disable_fiq(unsigned int base
,unsigned int irq
)
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
)
176 static void cpe_int_enable_irq(unsigned int base
,unsigned int irq
)
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
)
185 static void cpe_int_enable_fiq(unsigned int base
,unsigned int irq
)
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
197 #ifdef VICTOR_LOCK_IRQ // add by Victor Yu. 07-25-2007
198 spin_lock_irqsave(&cpe_int_lock
, flags
);
200 spin_lock(&cpe_int_lock
);
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
;
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
213 #ifdef CONFIG_PCI // add by Victor Yu. 05-23-2006
214 if ( irq
== IRQ_PCI
)
215 goto cpe_unmask_irq_exit
;
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
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
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
;
242 if( (irq
==VIRQ_PCI_A
)||(irq
==VIRQ_PCI_B
)||(irq
==VIRQ_PCI_C
)||(irq
==VIRQ_PCI_D
) ) {
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
;
253 #endif // CONFIG_ARCH_CPE
255 #ifdef CONFIG_ARCH_MOXACPU
258 if( (irq
==VIRQ_PCI_A
)||(irq
==VIRQ_PCI_B
)||(irq
==VIRQ_PCI_C
)||(irq
==VIRQ_PCI_D
) ) {
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;
267 #endif // CONFIG_ARCH_MOXACPU
270 #ifdef VICTOR_LOCK_IRQ // add by Victor Yu. 07-25-2007
271 spin_unlock_irqrestore(&cpe_int_lock
, flags
);
273 spin_unlock(&cpe_int_lock
);
278 static void cpe_mask_ack_irq(unsigned int irq
)
280 #ifdef VICTOR_LOCK_IRQ // add by Victor Yu. 07-25-2007
284 #ifdef VICTOR_LOCK_IRQ // add by Victor Yu. 07-25-2007
285 spin_lock_irqsave(&cpe_int_lock
, flags
);
287 spin_lock(&cpe_int_lock
);
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
;
294 cpe_int_disable_irq(CPE_IC_VA_BASE
,irq
);
295 goto cpe_mask_ack_irq_exit
;
298 if ( irq
< 64 ) { //fiq
300 #ifdef CONFIG_PCI // add by Victor Yu. 05-23-2006
301 if ( irq
== IRQ_PCI
)
302 goto cpe_mask_ack_irq_exit
;
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
311 cpe_int_disable_irq(CPE_A321_IC_VA_BASE
,irq
);
312 goto cpe_mask_ack_irq_exit
;
314 if ( irq
< 150 ) { //a321 fiq
316 cpe_int_disable_fiq(CPE_A321_IC_VA_BASE
,irq
);
317 goto cpe_mask_ack_irq_exit
;
321 if( (irq
==VIRQ_PCI_A
)||(irq
==VIRQ_PCI_B
)||(irq
==VIRQ_PCI_C
)||(irq
==VIRQ_PCI_D
) ) {
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
;
328 #endif // CONFIG_ARCH_CPE
330 #ifdef CONFIG_ARCH_MOXACPU
333 if( (irq
==VIRQ_PCI_A
)||(irq
==VIRQ_PCI_B
)||(irq
==VIRQ_PCI_C
)||(irq
==VIRQ_PCI_D
) ) {
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;
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
);
346 spin_unlock(&cpe_int_lock
);
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
);
358 void cpe_int_init(void)
360 #if 1 // add by Victor Yu. 07-26-2007
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
);
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
);
376 #ifdef CONFIG_ARCH_MOXACPU
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
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
,
403 .mask
= cpe_mask_ack_irq
,
405 .unmask
= cpe_unmask_irq
,
409 EXPORT_SYMBOL(cpe_int_set_irq
);
410 EXPORT_SYMBOL(cpe_int_clear_irq
);