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>
11 #include <asm/system.h>
13 #include <asm/arch/ftpci.h>
16 #if 0 // mask by Victtor Yu. 03-15-2007
17 static spinlock_t cpe_int_lock;
19 static spinlock_t cpe_int_lock=SPIN_LOCK_UNLOCKED;
22 #if 0 // add by Victor Yu. 05-17-2005
23 #include <asm/arch/irq.h>
24 #if 0 // mask by Victor Yu, 03-15-2007
25 struct irqchip cpe_irq_chip = {
26 .ack = cpe_mask_ack_irq,
28 .unmask = cpe_unmask_irq,
33 inline void cpe_irq_set_mode(unsigned int base_p,unsigned int irq,unsigned int edge)
36 *(volatile unsigned int *)(base_p+IRQ_MODE_REG)|=(1<<irq);
38 *(volatile unsigned int *)(base_p+IRQ_MODE_REG)&=~(1<<irq);
41 inline void cpe_irq_set_level(unsigned int base_p,unsigned int irq,unsigned int low)
44 *(volatile unsigned int *)(base_p+IRQ_LEVEL_REG)|=(1<<irq);
46 *(volatile unsigned int *)(base_p+IRQ_LEVEL_REG)&=~(1<<irq);
50 inline void cpe_fiq_set_mode(unsigned int base_p,unsigned int fiq,unsigned int edge)
53 *(volatile unsigned int *)(base_p+FIQ_MODE_REG)|=(1<<fiq);
55 *(volatile unsigned int *)(base_p+FIQ_MODE_REG)&=~(1<<fiq);
59 inline void cpe_fiq_set_level(unsigned int base_p,unsigned int fiq,unsigned int low)
62 *(volatile unsigned int *)(base_p+FIQ_LEVEL_REG)|=(1<<fiq);
64 *(volatile unsigned int *)(base_p+FIQ_LEVEL_REG)&=~(1<<fiq);
68 void cpe_int_set_irq(unsigned int irq,int mode,int level)
72 spin_lock_irqsave(&cpe_int_lock, flags);
73 if ( irq < 32 ) { //irq
74 cpe_irq_set_mode(CPE_IC_VA_BASE,irq ,mode);
75 cpe_irq_set_level(CPE_IC_VA_BASE,irq,level);
76 goto cpe_int_set_irq_exit;
78 if ( irq < 64 ) { //fiq
80 cpe_fiq_set_mode(CPE_IC_VA_BASE,irq,mode);
81 cpe_fiq_set_level(CPE_IC_VA_BASE,irq,level);
82 goto cpe_int_set_irq_exit;
85 #ifdef CONFIG_ARCH_CPE
86 if ( irq < 96 ) { //a321 irq
88 cpe_irq_set_mode(CPE_A321_IC_VA_BASE,irq,mode);
89 cpe_irq_set_level(CPE_A321_IC_VA_BASE,irq,level);
90 cpe_irq_set_mode(CPE_IC_VA_BASE,IRQ_EXT_A321,LEVEL);
91 cpe_irq_set_level(CPE_IC_VA_BASE,IRQ_EXT_A321,H_ACTIVE);
92 goto cpe_int_set_irq_exit;
94 if ( irq < 150 ) { //a321 fiq
96 cpe_fiq_set_mode(CPE_A321_IC_VA_BASE,irq,mode);
97 cpe_fiq_set_level(CPE_A321_IC_VA_BASE,irq,level);
98 cpe_fiq_set_mode(CPE_IC_VA_BASE,IRQ_EXT_A321,LEVEL);
99 cpe_fiq_set_level(CPE_IC_VA_BASE,IRQ_EXT_A321,H_ACTIVE);
100 goto cpe_int_set_irq_exit;
105 if ( (irq==VIRQ_PCI_A)||(irq==VIRQ_PCI_B)||(irq==VIRQ_PCI_C)||(irq==VIRQ_PCI_D) ) {
107 goto cpe_int_set_irq_exit;
108 cpe_irq_set_mode(CPE_A321_IC_VA_BASE,IRQ_A321_PCI,mode);
109 cpe_irq_set_level(CPE_A321_IC_VA_BASE,IRQ_A321_PCI,level);
110 cpe_irq_set_mode(CPE_IC_VA_BASE,IRQ_EXT_A321,LEVEL);
111 cpe_irq_set_level(CPE_IC_VA_BASE,IRQ_EXT_A321,H_ACTIVE);
112 #if 1 // add by Victor Yu. 10-20-2005
113 goto cpe_int_set_irq_exit;
117 #endif // CONFIG_ARCH_CPE
119 #ifdef CONFIG_ARCH_IA240
122 if ( (irq==VIRQ_PCI_A)||(irq==VIRQ_PCI_B)||(irq==VIRQ_PCI_C)||(irq==VIRQ_PCI_D) ) {
124 goto cpe_int_set_irq_exit;
125 cpe_irq_set_mode(CPE_IC_VA_BASE,IRQ_PCI,LEVEL);
126 cpe_irq_set_level(CPE_IC_VA_BASE,IRQ_PCI,H_ACTIVE);
127 goto cpe_int_set_irq_exit;
130 #endif // CONFIG_ARCH_IA240
132 //printk("Not support irq %d\n",irq);
134 cpe_int_set_irq_exit:
135 spin_unlock_irqrestore(&cpe_int_lock, flags);
138 void cpe_int_clear_irq(unsigned int base,unsigned int irq)
140 *(volatile unsigned int *)(base+IRQ_CLEAR_REG)=1<<irq;
143 void cpe_int_clear_fiq(unsigned int base,unsigned int irq)
145 *(volatile unsigned int *)(base+FIQ_CLEAR_REG)=1<<irq;
148 inline void cpe_int_disable_irq(unsigned int base,unsigned int irq)
150 *(volatile unsigned int *)(base+IRQ_MASK_REG)&=~(1<<irq);
153 inline void cpe_int_disable_fiq(unsigned int base,unsigned int irq)
155 *(volatile unsigned int *)(base+FIQ_MASK_REG)&=~(1<<irq);
158 /* Turn the interrupt source on. */
159 inline void cpe_int_enable_irq(unsigned int base,unsigned int irq)
161 *(volatile unsigned int *)(base+IRQ_MASK_REG)|=(1<<irq);
164 inline void cpe_int_enable_fiq(unsigned int base,unsigned int irq)
166 *(volatile unsigned int *)(base+FIQ_MASK_REG)|=(1<<irq);
169 void cpe_unmask_irq(unsigned int irq)
173 spin_lock_irqsave(&cpe_int_lock, flags);
174 if ( irq < 32 ) { //irq
175 cpe_int_clear_irq(CPE_IC_VA_BASE,irq);
176 cpe_int_enable_irq(CPE_IC_VA_BASE,irq);
177 goto cpe_unmask_irq_exit;
179 if ( irq < 64 ) { //fiq
181 cpe_int_clear_fiq(CPE_IC_VA_BASE,irq);
182 cpe_int_enable_fiq(CPE_IC_VA_BASE,irq);
183 goto cpe_unmask_irq_exit;
186 #ifdef CONFIG_ARCH_CPE
187 if ( irq < 96 ) { //a321 irq
189 cpe_int_clear_irq(CPE_A321_IC_VA_BASE,irq);
190 cpe_int_clear_irq(CPE_IC_VA_BASE,IRQ_EXT_A321);
191 cpe_int_enable_irq(CPE_A321_IC_VA_BASE,irq);
192 cpe_int_enable_irq(CPE_IC_VA_BASE,IRQ_EXT_A321);
193 goto cpe_unmask_irq_exit;
195 if ( irq < 150 ) { //a321 fiq
197 cpe_int_clear_fiq(CPE_A321_IC_VA_BASE,irq);
198 cpe_int_clear_fiq(CPE_IC_VA_BASE,IRQ_EXT_A321);
199 cpe_int_enable_fiq(CPE_A321_IC_VA_BASE,irq);
200 cpe_int_enable_fiq(CPE_IC_VA_BASE,IRQ_EXT_A321);
201 goto cpe_unmask_irq_exit;
206 if( (irq==VIRQ_PCI_A)||(irq==VIRQ_PCI_B)||(irq==VIRQ_PCI_C)||(irq==VIRQ_PCI_D) ) {
208 goto cpe_unmask_irq_exit;
209 ftpci_clear_irq(irq-150);
210 cpe_int_clear_irq(CPE_A321_IC_VA_BASE,IRQ_A321_PCI);
211 cpe_int_enable_irq(CPE_A321_IC_VA_BASE,IRQ_A321_PCI); //always enabled
212 cpe_int_clear_irq(CPE_IC_VA_BASE,IRQ_EXT_A321);
213 cpe_int_enable_irq(CPE_IC_VA_BASE,IRQ_EXT_A321); //always enabled
214 goto cpe_unmask_irq_exit;
217 #endif // CONFIG_ARCH_CPE
219 #ifdef CONFIG_ARCH_IA240
222 if( (irq==VIRQ_PCI_A)||(irq==VIRQ_PCI_B)||(irq==VIRQ_PCI_C)||(irq==VIRQ_PCI_D) ) {
224 goto cpe_unmask_irq_exit;
225 ftpci_clear_irq(irq-64);
226 cpe_int_clear_irq(CPE_IC_VA_BASE,IRQ_PCI);
227 cpe_int_enable_irq(CPE_IC_VA_BASE,IRQ_PCI); //always enabled
228 goto cpe_unmask_irq_exit;
231 #endif // CONFIG_ARCH_IA240
234 spin_unlock_irqrestore(&cpe_int_lock, flags);
237 void cpe_mask_ack_irq(unsigned int irq)
241 spin_lock_irqsave(&cpe_int_lock, flags);
242 if ( irq < 32 ) { //irq
243 cpe_int_disable_irq(CPE_IC_VA_BASE,irq);
244 goto cpe_mask_ack_irq_exit;
247 if ( irq < 64 ) { //fiq
249 cpe_int_disable_fiq(CPE_IC_VA_BASE,irq);
250 goto cpe_mask_ack_irq_exit;
253 #ifdef CONFIG_ARCH_CPE
254 if ( irq < 96 ) { //a321 irq
256 cpe_int_disable_irq(CPE_A321_IC_VA_BASE,irq);
257 goto cpe_mask_ack_irq_exit;
259 if ( irq < 150 ) { //a321 fiq
261 cpe_int_disable_fiq(CPE_A321_IC_VA_BASE,irq);
262 goto cpe_mask_ack_irq_exit;
266 if( (irq==VIRQ_PCI_A)||(irq==VIRQ_PCI_B)||(irq==VIRQ_PCI_C)||(irq==VIRQ_PCI_D) ) {
268 goto cpe_mask_ack_irq_exit;
269 cpe_int_disable_irq(CPE_A321_IC_VA_BASE,IRQ_A321_PCI); //always enabled
270 goto cpe_mask_ack_irq_exit;
273 #endif // CONFIG_ARCH_CPE
275 #ifdef CONFIG_ARCH_IA240
278 if( (irq==VIRQ_PCI_A)||(irq==VIRQ_PCI_B)||(irq==VIRQ_PCI_C)||(irq==VIRQ_PCI_D) ) {
280 goto cpe_mask_ack_irq_exit;
281 cpe_int_disable_irq(CPE_IC_VA_BASE,IRQ_PCI);
282 goto cpe_mask_ack_irq_exit;
285 #endif // CONFIG_ARCH_IA240
287 cpe_mask_ack_irq_exit:
288 spin_unlock_irqrestore(&cpe_int_lock, flags);
291 void cpe_mask_irq(unsigned int irq)
293 cpe_mask_ack_irq(irq);
296 void cpe_int_init(void)
298 spin_lock_init(&cpe_int_lock);
299 //init interrupt controller
300 outl(0, CPE_IC_VA_BASE+IRQ_MASK_REG);
301 outl(0, CPE_IC_VA_BASE+FIQ_MASK_REG);
302 outl(0xffffffff, CPE_IC_VA_BASE+IRQ_CLEAR_REG);
303 outl(0xffffffff, CPE_IC_VA_BASE+FIQ_CLEAR_REG);
305 #ifdef CONFIG_ARCH_CPE
306 //init a321 interrupt controller
307 outl(0, CPE_A321_IC_VA_BASE+IRQ_MASK_REG);
308 outl(0, CPE_A321_IC_VA_BASE+FIQ_MASK_REG);
309 outl(0xffffffff, CPE_A321_IC_VA_BASE+IRQ_CLEAR_REG);
310 outl(0xffffffff, CPE_A321_IC_VA_BASE+FIQ_CLEAR_REG);
311 cpe_int_set_irq(IRQ_EXT_A321, LEVEL, H_ACTIVE);
312 cpe_int_enable_irq(CPE_IC_VA_BASE,IRQ_EXT_A321);
313 #endif // CONFIG_ARCH_CPE
316 EXPORT_SYMBOL(cpe_int_set_irq);
317 EXPORT_SYMBOL(cpe_int_clear_irq);