1 #include <linux/module.h>
2 #include <linux/init.h>
4 #include <asm/mach/irq.h>
5 #include <asm/hardware.h>
8 #include <asm/system.h>
9 #include <asm/arch/cpe/cpe.h>
10 #include <asm/arch/ftpci.h>
12 static spinlock_t cpe_int_lock;
14 #if 1 // add by Victor Yu. 05-17-2005
15 #include <asm/arch/irq.h>
16 struct irqchip cpe_irq_chip = {
17 .ack = cpe_mask_ack_irq,
19 .unmask = cpe_unmask_irq,
23 inline void cpe_irq_set_mode(unsigned int base_p,unsigned int irq,unsigned int edge)
26 *(volatile unsigned int *)(base_p+IRQ_MODE_REG)|=(1<<irq);
28 *(volatile unsigned int *)(base_p+IRQ_MODE_REG)&=~(1<<irq);
31 inline void cpe_irq_set_level(unsigned int base_p,unsigned int irq,unsigned int low)
34 *(volatile unsigned int *)(base_p+IRQ_LEVEL_REG)|=(1<<irq);
36 *(volatile unsigned int *)(base_p+IRQ_LEVEL_REG)&=~(1<<irq);
40 inline void cpe_fiq_set_mode(unsigned int base_p,unsigned int fiq,unsigned int edge)
43 *(volatile unsigned int *)(base_p+FIQ_MODE_REG)|=(1<<fiq);
45 *(volatile unsigned int *)(base_p+FIQ_MODE_REG)&=~(1<<fiq);
49 inline void cpe_fiq_set_level(unsigned int base_p,unsigned int fiq,unsigned int low)
52 *(volatile unsigned int *)(base_p+FIQ_LEVEL_REG)|=(1<<fiq);
54 *(volatile unsigned int *)(base_p+FIQ_LEVEL_REG)&=~(1<<fiq);
58 void cpe_int_set_irq(unsigned int irq,int mode,int level)
62 spin_lock_irqsave(&cpe_int_lock, flags);
63 if ( irq < 32 ) { //irq
64 #ifdef CONFIG_PCI // add by Victor Yu. 05-23-2006
66 goto cpe_int_set_irq_exit;
68 cpe_irq_set_mode(CPE_IC_VA_BASE,irq ,mode);
69 cpe_irq_set_level(CPE_IC_VA_BASE,irq,level);
70 goto cpe_int_set_irq_exit;
72 if ( irq < 64 ) { //fiq
74 #ifdef CONFIG_PCI // add by Victor Yu. 05-23-2006
76 goto cpe_int_set_irq_exit;
78 cpe_fiq_set_mode(CPE_IC_VA_BASE,irq,mode);
79 cpe_fiq_set_level(CPE_IC_VA_BASE,irq,level);
80 goto cpe_int_set_irq_exit;
83 #ifdef CONFIG_ARCH_CPE
84 if ( irq < 96 ) { //a321 irq
86 cpe_irq_set_mode(CPE_A321_IC_VA_BASE,irq,mode);
87 cpe_irq_set_level(CPE_A321_IC_VA_BASE,irq,level);
88 cpe_irq_set_mode(CPE_IC_VA_BASE,IRQ_EXT_A321,LEVEL);
89 cpe_irq_set_level(CPE_IC_VA_BASE,IRQ_EXT_A321,H_ACTIVE);
90 goto cpe_int_set_irq_exit;
92 if ( irq < 150 ) { //a321 fiq
94 cpe_fiq_set_mode(CPE_A321_IC_VA_BASE,irq,mode);
95 cpe_fiq_set_level(CPE_A321_IC_VA_BASE,irq,level);
96 cpe_fiq_set_mode(CPE_IC_VA_BASE,IRQ_EXT_A321,LEVEL);
97 cpe_fiq_set_level(CPE_IC_VA_BASE,IRQ_EXT_A321,H_ACTIVE);
98 goto cpe_int_set_irq_exit;
103 if ( (irq==VIRQ_PCI_A)||(irq==VIRQ_PCI_B)||(irq==VIRQ_PCI_C)||(irq==VIRQ_PCI_D) ) {
105 goto cpe_int_set_irq_exit;
106 cpe_irq_set_mode(CPE_A321_IC_VA_BASE,IRQ_A321_PCI,mode);
107 cpe_irq_set_level(CPE_A321_IC_VA_BASE,IRQ_A321_PCI,level);
108 cpe_irq_set_mode(CPE_IC_VA_BASE,IRQ_EXT_A321,LEVEL);
109 cpe_irq_set_level(CPE_IC_VA_BASE,IRQ_EXT_A321,H_ACTIVE);
110 #if 1 // add by Victor Yu. 10-20-2005
111 goto cpe_int_set_irq_exit;
115 #endif // CONFIG_ARCH_CPE
117 #ifdef CONFIG_ARCH_MOXACPU
120 if ( (irq==VIRQ_PCI_A)||(irq==VIRQ_PCI_B)||(irq==VIRQ_PCI_C)||(irq==VIRQ_PCI_D) ) {
122 goto cpe_int_set_irq_exit;
123 cpe_irq_set_mode(CPE_IC_VA_BASE,IRQ_PCI,LEVEL);
124 cpe_irq_set_level(CPE_IC_VA_BASE,IRQ_PCI,H_ACTIVE);
125 //goto cpe_int_set_irq_exit;
128 #endif // CONFIG_ARCH_MOXACPU
130 //printk("Not support irq %d\n",irq);
132 cpe_int_set_irq_exit:
133 spin_unlock_irqrestore(&cpe_int_lock, flags);
136 void cpe_int_clear_irq(unsigned int base,unsigned int irq)
138 *(volatile unsigned int *)(base+IRQ_CLEAR_REG)=1<<irq;
141 void cpe_int_clear_fiq(unsigned int base,unsigned int irq)
143 *(volatile unsigned int *)(base+FIQ_CLEAR_REG)=1<<irq;
146 inline void cpe_int_disable_irq(unsigned int base,unsigned int irq)
148 *(volatile unsigned int *)(base+IRQ_MASK_REG)&=~(1<<irq);
151 inline void cpe_int_disable_fiq(unsigned int base,unsigned int irq)
153 *(volatile unsigned int *)(base+FIQ_MASK_REG)&=~(1<<irq);
157 /* Turn the interrupt source on. */
158 inline void cpe_int_enable_irq(unsigned int base,unsigned int irq)
160 *(volatile unsigned int *)(base+IRQ_MASK_REG)|=(1<<irq);
163 inline void cpe_int_enable_fiq(unsigned int base,unsigned int irq)
165 *(volatile unsigned int *)(base+FIQ_MASK_REG)|=(1<<irq);
168 void cpe_unmask_irq(unsigned int irq)
172 spin_lock_irqsave(&cpe_int_lock, flags);
173 if ( irq < 32 ) { //irq
174 #ifdef CONFIG_PCI // add by Victor Yu. 05-23-2006
175 if ( irq == IRQ_PCI )
176 goto cpe_unmask_irq_exit;
178 cpe_int_clear_irq(CPE_IC_VA_BASE,irq);
179 cpe_int_enable_irq(CPE_IC_VA_BASE,irq);
180 goto cpe_unmask_irq_exit;
182 if ( irq < 64 ) { //fiq
184 #ifdef CONFIG_PCI // add by Victor Yu. 05-23-2006
185 if ( irq == IRQ_PCI )
186 goto cpe_unmask_irq_exit;
188 cpe_int_clear_fiq(CPE_IC_VA_BASE,irq);
189 cpe_int_enable_fiq(CPE_IC_VA_BASE,irq);
190 goto cpe_unmask_irq_exit;
193 #ifdef CONFIG_ARCH_CPE
194 if ( irq < 96 ) { //a321 irq
196 cpe_int_clear_irq(CPE_A321_IC_VA_BASE,irq);
197 cpe_int_clear_irq(CPE_IC_VA_BASE,IRQ_EXT_A321);
198 cpe_int_enable_irq(CPE_A321_IC_VA_BASE,irq);
199 cpe_int_enable_irq(CPE_IC_VA_BASE,IRQ_EXT_A321);
200 goto cpe_unmask_irq_exit;
202 if ( irq < 150 ) { //a321 fiq
204 cpe_int_clear_fiq(CPE_A321_IC_VA_BASE,irq);
205 cpe_int_clear_fiq(CPE_IC_VA_BASE,IRQ_EXT_A321);
206 cpe_int_enable_fiq(CPE_A321_IC_VA_BASE,irq);
207 cpe_int_enable_fiq(CPE_IC_VA_BASE,IRQ_EXT_A321);
208 goto cpe_unmask_irq_exit;
213 if( (irq==VIRQ_PCI_A)||(irq==VIRQ_PCI_B)||(irq==VIRQ_PCI_C)||(irq==VIRQ_PCI_D) ) {
215 goto cpe_unmask_irq_exit;
216 ftpci_clear_irq(irq-150);
217 cpe_int_clear_irq(CPE_A321_IC_VA_BASE,IRQ_A321_PCI);
218 cpe_int_enable_irq(CPE_A321_IC_VA_BASE,IRQ_A321_PCI); //always enabled
219 cpe_int_clear_irq(CPE_IC_VA_BASE,IRQ_EXT_A321);
220 cpe_int_enable_irq(CPE_IC_VA_BASE,IRQ_EXT_A321); //always enabled
221 goto cpe_unmask_irq_exit;
224 #endif // CONFIG_ARCH_CPE
226 #ifdef CONFIG_ARCH_MOXACPU
229 if( (irq==VIRQ_PCI_A)||(irq==VIRQ_PCI_B)||(irq==VIRQ_PCI_C)||(irq==VIRQ_PCI_D) ) {
231 goto cpe_unmask_irq_exit;
232 ftpci_clear_irq(irq-CPE_VIRQ_START);
233 cpe_int_clear_irq(CPE_IC_VA_BASE,IRQ_PCI);
234 cpe_int_enable_irq(CPE_IC_VA_BASE,IRQ_PCI); //always enabled
235 //goto cpe_unmask_irq_exit;
238 #endif // CONFIG_ARCH_MOXACPU
241 spin_unlock_irqrestore(&cpe_int_lock, flags);
244 void cpe_mask_ack_irq(unsigned int irq)
248 spin_lock_irqsave(&cpe_int_lock, flags);
249 if ( irq < 32 ) { //irq
250 #ifdef CONFIG_PCI // add by Victor Yu. 05-23-2006
251 if ( irq == IRQ_PCI )
252 goto cpe_mask_ack_irq_exit;
254 cpe_int_disable_irq(CPE_IC_VA_BASE,irq);
255 goto cpe_mask_ack_irq_exit;
258 if ( irq < 64 ) { //fiq
260 #ifdef CONFIG_PCI // add by Victor Yu. 05-23-2006
261 if ( irq == IRQ_PCI )
262 goto cpe_mask_ack_irq_exit;
264 cpe_int_disable_fiq(CPE_IC_VA_BASE,irq);
265 goto cpe_mask_ack_irq_exit;
268 #ifdef CONFIG_ARCH_CPE
269 if ( irq < 96 ) { //a321 irq
271 cpe_int_disable_irq(CPE_A321_IC_VA_BASE,irq);
272 goto cpe_mask_ack_irq_exit;
274 if ( irq < 150 ) { //a321 fiq
276 cpe_int_disable_fiq(CPE_A321_IC_VA_BASE,irq);
277 goto cpe_mask_ack_irq_exit;
281 if( (irq==VIRQ_PCI_A)||(irq==VIRQ_PCI_B)||(irq==VIRQ_PCI_C)||(irq==VIRQ_PCI_D) ) {
283 goto cpe_mask_ack_irq_exit;
284 cpe_int_disable_irq(CPE_A321_IC_VA_BASE,IRQ_A321_PCI); //always enabled
285 goto cpe_mask_ack_irq_exit;
288 #endif // CONFIG_ARCH_CPE
290 #ifdef CONFIG_ARCH_MOXACPU
293 if( (irq==VIRQ_PCI_A)||(irq==VIRQ_PCI_B)||(irq==VIRQ_PCI_C)||(irq==VIRQ_PCI_D) ) {
295 goto cpe_mask_ack_irq_exit;
296 cpe_int_disable_irq(CPE_IC_VA_BASE,IRQ_PCI);
297 //goto cpe_mask_ack_irq_exit;
300 #endif // CONFIG_ARCH_MOXACPU
302 cpe_mask_ack_irq_exit:
303 spin_unlock_irqrestore(&cpe_int_lock, flags);
306 void cpe_mask_irq(unsigned int irq)
308 cpe_mask_ack_irq(irq);
311 void cpe_int_init(void)
313 spin_lock_init(&cpe_int_lock);
314 //init interrupt controller
315 outl(0, CPE_IC_VA_BASE+IRQ_MASK_REG);
316 outl(0, CPE_IC_VA_BASE+FIQ_MASK_REG);
317 outl(0xffffffff, CPE_IC_VA_BASE+IRQ_CLEAR_REG);
318 outl(0xffffffff, CPE_IC_VA_BASE+FIQ_CLEAR_REG);
319 #ifdef CONFIG_ARCH_MOXACPU
321 cpe_int_set_irq(IRQ_PCI, LEVEL, H_ACTIVE);
322 #if 0 // mask by Victor Yu. 05-23-2006
323 cpe_int_enable_irq(CPE_IC_VA_BASE,IRQ_PCI); //always enabled
328 #ifdef CONFIG_ARCH_CPE
329 //init a321 interrupt controller
330 outl(0, CPE_A321_IC_VA_BASE+IRQ_MASK_REG);
331 outl(0, CPE_A321_IC_VA_BASE+FIQ_MASK_REG);
332 outl(0xffffffff, CPE_A321_IC_VA_BASE+IRQ_CLEAR_REG);
333 outl(0xffffffff, CPE_A321_IC_VA_BASE+FIQ_CLEAR_REG);
334 cpe_int_set_irq(IRQ_EXT_A321, LEVEL, H_ACTIVE);
335 cpe_int_enable_irq(CPE_IC_VA_BASE,IRQ_EXT_A321);
336 #endif // CONFIG_ARCH_CPE
339 EXPORT_SYMBOL(cpe_int_set_irq);
340 EXPORT_SYMBOL(cpe_int_clear_irq);