MOXA linux-2.6.x / linux-2.6.19-uc1 from UC-7110-LX-BOOTLOADER-1.9_VERSION-4.2.tgz
[linux-2.6.19-moxart.git] / arch / arm / mach-moxart / irq.c
blobf4fcd105c52b2ca6ac392693c63e99c6adef41f8
2 //#include <linux/config.h>
3 #include <asm/arch/moxa.h>
4 #include <linux/module.h>
5 #include <linux/init.h>
7 //#include <asm/mach/irq.h>
8 #include <asm/hardware.h>
9 #include <asm/io.h>
10 #include <asm/irq.h>
11 #include <asm/system.h>
12 #ifdef CONFIG_PCI
13 #include <asm/arch/ftpci.h>
14 #endif // CONFIG_PCI
16 //#define VICTOR_USE_IRQ_LOCK // add by Victor Yu. 07-31-2007
18 #if 0 // mask by Victtor Yu. 03-15-2007
19 static spinlock_t cpe_int_lock;
20 #else
21 static spinlock_t cpe_int_lock=SPIN_LOCK_UNLOCKED;
22 #endif
24 #if 0 // add by Victor Yu. 05-17-2005
25 #include <asm/arch/irq.h>
26 #if 0 // mask by Victor Yu, 03-15-2007
27 struct irqchip cpe_irq_chip = {
28 .ack = cpe_mask_ack_irq,
29 .mask = cpe_mask_irq,
30 .unmask = cpe_unmask_irq,
32 #endif
33 #endif
35 inline void cpe_irq_set_mode(unsigned int base_p,unsigned int irq,unsigned int edge)
37 if ( edge )
38 *(volatile unsigned int *)(base_p+IRQ_MODE_REG)|=(1<<irq);
39 else
40 *(volatile unsigned int *)(base_p+IRQ_MODE_REG)&=~(1<<irq);
43 inline void cpe_irq_set_level(unsigned int base_p,unsigned int irq,unsigned int low)
45 if ( low )
46 *(volatile unsigned int *)(base_p+IRQ_LEVEL_REG)|=(1<<irq);
47 else
48 *(volatile unsigned int *)(base_p+IRQ_LEVEL_REG)&=~(1<<irq);
52 inline void cpe_fiq_set_mode(unsigned int base_p,unsigned int fiq,unsigned int edge)
54 if ( edge )
55 *(volatile unsigned int *)(base_p+FIQ_MODE_REG)|=(1<<fiq);
56 else
57 *(volatile unsigned int *)(base_p+FIQ_MODE_REG)&=~(1<<fiq);
61 inline void cpe_fiq_set_level(unsigned int base_p,unsigned int fiq,unsigned int low)
63 if ( low )
64 *(volatile unsigned int *)(base_p+FIQ_LEVEL_REG)|=(1<<fiq);
65 else
66 *(volatile unsigned int *)(base_p+FIQ_LEVEL_REG)&=~(1<<fiq);
70 void cpe_int_set_irq(unsigned int irq,int mode,int level)
72 unsigned long flags;
74 spin_lock_irqsave(&cpe_int_lock, flags);
75 if ( irq < 32 ) { //irq
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 cpe_fiq_set_mode(CPE_IC_VA_BASE,irq,mode);
83 cpe_fiq_set_level(CPE_IC_VA_BASE,irq,level);
84 goto cpe_int_set_irq_exit;
87 #ifdef CONFIG_ARCH_CPE
88 if ( irq < 96 ) { //a321 irq
89 irq-=64;
90 cpe_irq_set_mode(CPE_A321_IC_VA_BASE,irq,mode);
91 cpe_irq_set_level(CPE_A321_IC_VA_BASE,irq,level);
92 cpe_irq_set_mode(CPE_IC_VA_BASE,IRQ_EXT_A321,LEVEL);
93 cpe_irq_set_level(CPE_IC_VA_BASE,IRQ_EXT_A321,H_ACTIVE);
94 goto cpe_int_set_irq_exit;
96 if ( irq < 150 ) { //a321 fiq
97 irq-=96;
98 cpe_fiq_set_mode(CPE_A321_IC_VA_BASE,irq,mode);
99 cpe_fiq_set_level(CPE_A321_IC_VA_BASE,irq,level);
100 cpe_fiq_set_mode(CPE_IC_VA_BASE,IRQ_EXT_A321,LEVEL);
101 cpe_fiq_set_level(CPE_IC_VA_BASE,IRQ_EXT_A321,H_ACTIVE);
102 goto cpe_int_set_irq_exit;
105 #ifdef CONFIG_PCI
106 //pci virtual irq
107 if ( (irq==VIRQ_PCI_A)||(irq==VIRQ_PCI_B)||(irq==VIRQ_PCI_C)||(irq==VIRQ_PCI_D) ) {
108 if( !ftpci_probed )
109 goto cpe_int_set_irq_exit;
110 cpe_irq_set_mode(CPE_A321_IC_VA_BASE,IRQ_A321_PCI,mode);
111 cpe_irq_set_level(CPE_A321_IC_VA_BASE,IRQ_A321_PCI,level);
112 cpe_irq_set_mode(CPE_IC_VA_BASE,IRQ_EXT_A321,LEVEL);
113 cpe_irq_set_level(CPE_IC_VA_BASE,IRQ_EXT_A321,H_ACTIVE);
114 #if 1 // add by Victor Yu. 10-20-2005
115 goto cpe_int_set_irq_exit;
116 #endif // 10-20-2005
118 #endif // CONFIG_PCI
119 #endif // CONFIG_ARCH_CPE
121 #ifdef CONFIG_ARCH_IA240
122 #ifdef CONFIG_PCI
123 //pci virtual irq
124 if ( (irq==VIRQ_PCI_A)||(irq==VIRQ_PCI_B)||(irq==VIRQ_PCI_C)||(irq==VIRQ_PCI_D) ) {
125 if( !ftpci_probed )
126 goto cpe_int_set_irq_exit;
127 cpe_irq_set_mode(CPE_IC_VA_BASE,IRQ_PCI,LEVEL);
128 cpe_irq_set_level(CPE_IC_VA_BASE,IRQ_PCI,H_ACTIVE);
129 goto cpe_int_set_irq_exit;
131 #endif // CONFIG_PCI
132 #endif // CONFIG_ARCH_IA240
134 //printk("Not support irq %d\n",irq);
136 cpe_int_set_irq_exit:
137 spin_unlock_irqrestore(&cpe_int_lock, flags);
140 void cpe_int_clear_irq(unsigned int base,unsigned int irq)
142 *(volatile unsigned int *)(base+IRQ_CLEAR_REG)=1<<irq;
145 void cpe_int_clear_fiq(unsigned int base,unsigned int irq)
147 *(volatile unsigned int *)(base+FIQ_CLEAR_REG)=1<<irq;
150 inline void cpe_int_disable_irq(unsigned int base,unsigned int irq)
152 *(volatile unsigned int *)(base+IRQ_MASK_REG)&=~(1<<irq);
155 inline void cpe_int_disable_fiq(unsigned int base,unsigned int irq)
157 *(volatile unsigned int *)(base+FIQ_MASK_REG)&=~(1<<irq);
160 /* Turn the interrupt source on. */
161 inline void cpe_int_enable_irq(unsigned int base,unsigned int irq)
163 *(volatile unsigned int *)(base+IRQ_MASK_REG)|=(1<<irq);
166 inline void cpe_int_enable_fiq(unsigned int base,unsigned int irq)
168 *(volatile unsigned int *)(base+FIQ_MASK_REG)|=(1<<irq);
171 void cpe_unmask_irq(unsigned int irq)
173 #ifdef VICTOR_USE_IRQ_LOCK // add by Victor Yu. 07-31-2007
174 unsigned long flags;
176 spin_lock_irqsave(&cpe_int_lock, flags);
177 #else
178 spin_lock(&cpe_int_lock);
179 #endif
180 if ( irq < 32 ) { //irq
181 cpe_int_clear_irq(CPE_IC_VA_BASE,irq);
182 cpe_int_enable_irq(CPE_IC_VA_BASE,irq);
183 goto cpe_unmask_irq_exit;
185 if ( irq < 64 ) { //fiq
186 irq-=32;
187 cpe_int_clear_fiq(CPE_IC_VA_BASE,irq);
188 cpe_int_enable_fiq(CPE_IC_VA_BASE,irq);
189 goto cpe_unmask_irq_exit;
192 #ifdef CONFIG_ARCH_CPE
193 if ( irq < 96 ) { //a321 irq
194 irq-=64;
195 cpe_int_clear_irq(CPE_A321_IC_VA_BASE,irq);
196 cpe_int_clear_irq(CPE_IC_VA_BASE,IRQ_EXT_A321);
197 cpe_int_enable_irq(CPE_A321_IC_VA_BASE,irq);
198 cpe_int_enable_irq(CPE_IC_VA_BASE,IRQ_EXT_A321);
199 goto cpe_unmask_irq_exit;
201 if ( irq < 150 ) { //a321 fiq
202 irq-=96;
203 cpe_int_clear_fiq(CPE_A321_IC_VA_BASE,irq);
204 cpe_int_clear_fiq(CPE_IC_VA_BASE,IRQ_EXT_A321);
205 cpe_int_enable_fiq(CPE_A321_IC_VA_BASE,irq);
206 cpe_int_enable_fiq(CPE_IC_VA_BASE,IRQ_EXT_A321);
207 goto cpe_unmask_irq_exit;
210 #ifdef CONFIG_PCI
211 //pci virtual irq
212 if( (irq==VIRQ_PCI_A)||(irq==VIRQ_PCI_B)||(irq==VIRQ_PCI_C)||(irq==VIRQ_PCI_D) ) {
213 if( !ftpci_probed )
214 goto cpe_unmask_irq_exit;
215 ftpci_clear_irq(irq-150);
216 cpe_int_clear_irq(CPE_A321_IC_VA_BASE,IRQ_A321_PCI);
217 cpe_int_enable_irq(CPE_A321_IC_VA_BASE,IRQ_A321_PCI); //always enabled
218 cpe_int_clear_irq(CPE_IC_VA_BASE,IRQ_EXT_A321);
219 cpe_int_enable_irq(CPE_IC_VA_BASE,IRQ_EXT_A321); //always enabled
220 goto cpe_unmask_irq_exit;
222 #endif // CONFIG_PCI
223 #endif // CONFIG_ARCH_CPE
225 #ifdef CONFIG_ARCH_IA240
226 #ifdef CONFIG_PCI
227 //pci virtual irq
228 if( (irq==VIRQ_PCI_A)||(irq==VIRQ_PCI_B)||(irq==VIRQ_PCI_C)||(irq==VIRQ_PCI_D) ) {
229 if( !ftpci_probed )
230 goto cpe_unmask_irq_exit;
231 ftpci_clear_irq(irq-64);
232 cpe_int_clear_irq(CPE_IC_VA_BASE,IRQ_PCI);
233 cpe_int_enable_irq(CPE_IC_VA_BASE,IRQ_PCI); //always enabled
234 goto cpe_unmask_irq_exit;
236 #endif // CONFIG_PCI
237 #endif // CONFIG_ARCH_IA240
239 cpe_unmask_irq_exit:
240 #ifdef VICTOR_USE_IRQ_LOCK // add by Victor Yu. 07-31-2007
241 spin_unlock_irqrestore(&cpe_int_lock, flags);
242 #else
243 spin_unlock(&cpe_int_lock);
244 #endif
247 void cpe_mask_ack_irq(unsigned int irq)
249 #ifdef VICTOR_USE_IRQ_LOCK // add by Victor Yu. 07-31-2007
250 unsigned long flags;
252 spin_lock_irqsave(&cpe_int_lock, flags);
253 #else
254 spin_lock(&cpe_int_lock);
255 #endif
256 if ( irq < 32 ) { //irq
257 cpe_int_disable_irq(CPE_IC_VA_BASE,irq);
258 goto cpe_mask_ack_irq_exit;
261 if ( irq < 64 ) { //fiq
262 irq-=32;
263 cpe_int_disable_fiq(CPE_IC_VA_BASE,irq);
264 goto cpe_mask_ack_irq_exit;
267 #ifdef CONFIG_ARCH_CPE
268 if ( irq < 96 ) { //a321 irq
269 irq-=64;
270 cpe_int_disable_irq(CPE_A321_IC_VA_BASE,irq);
271 goto cpe_mask_ack_irq_exit;
273 if ( irq < 150 ) { //a321 fiq
274 irq-=96;
275 cpe_int_disable_fiq(CPE_A321_IC_VA_BASE,irq);
276 goto cpe_mask_ack_irq_exit;
278 #ifdef CONFIG_PCI
279 //pci virtual irq
280 if( (irq==VIRQ_PCI_A)||(irq==VIRQ_PCI_B)||(irq==VIRQ_PCI_C)||(irq==VIRQ_PCI_D) ) {
281 if( !ftpci_probed )
282 goto cpe_mask_ack_irq_exit;
283 cpe_int_disable_irq(CPE_A321_IC_VA_BASE,IRQ_A321_PCI); //always enabled
284 goto cpe_mask_ack_irq_exit;
286 #endif // CONFIG_PCI
287 #endif // CONFIG_ARCH_CPE
289 #ifdef CONFIG_ARCH_IA240
290 #ifdef CONFIG_PCI
291 //pci virtual irq
292 if( (irq==VIRQ_PCI_A)||(irq==VIRQ_PCI_B)||(irq==VIRQ_PCI_C)||(irq==VIRQ_PCI_D) ) {
293 if( !ftpci_probed )
294 goto cpe_mask_ack_irq_exit;
295 cpe_int_disable_irq(CPE_IC_VA_BASE,IRQ_PCI);
296 goto cpe_mask_ack_irq_exit;
298 #endif // CONFIG_PCI
299 #endif // CONFIG_ARCH_IA240
301 cpe_mask_ack_irq_exit:
302 #ifdef VICTOR_USE_IRQ_LOCK // add by Victor Yu. 07-31-2007
303 spin_unlock_irqrestore(&cpe_int_lock, flags);
304 #else
305 spin_unlock(&cpe_int_lock);
306 #endif
309 void cpe_mask_irq(unsigned int irq)
311 cpe_mask_ack_irq(irq);
314 void cpe_int_init(void)
316 spin_lock_init(&cpe_int_lock);
317 //init interrupt controller
318 outl(0, CPE_IC_VA_BASE+IRQ_MASK_REG);
319 outl(0, CPE_IC_VA_BASE+FIQ_MASK_REG);
320 outl(0xffffffff, CPE_IC_VA_BASE+IRQ_CLEAR_REG);
321 outl(0xffffffff, CPE_IC_VA_BASE+FIQ_CLEAR_REG);
323 #ifdef CONFIG_ARCH_CPE
324 //init a321 interrupt controller
325 outl(0, CPE_A321_IC_VA_BASE+IRQ_MASK_REG);
326 outl(0, CPE_A321_IC_VA_BASE+FIQ_MASK_REG);
327 outl(0xffffffff, CPE_A321_IC_VA_BASE+IRQ_CLEAR_REG);
328 outl(0xffffffff, CPE_A321_IC_VA_BASE+FIQ_CLEAR_REG);
329 cpe_int_set_irq(IRQ_EXT_A321, LEVEL, H_ACTIVE);
330 cpe_int_enable_irq(CPE_IC_VA_BASE,IRQ_EXT_A321);
331 #endif // CONFIG_ARCH_CPE
334 EXPORT_SYMBOL(cpe_int_set_irq);
335 EXPORT_SYMBOL(cpe_int_clear_irq);