more changes on original files
[linux-2.4.git] / include / asm-arm / arch-cl7500 / irq.h
1 /*
2  * include/asm-arm/arch-cl7500/irq.h
3  *
4  * Copyright (C) 1996 Russell King
5  * Copyright (C) 1999, 2001 Nexus Electronics Ltd.
6  *
7  * Changelog:
8  *   10-10-1996 RMK     Brought up to date with arch-sa110eval
9  *   22-08-1998 RMK     Restructured IRQ routines
10  *   11-08-1999 PJB     Created ARM7500 version, derived from RiscPC code
11  */
12
13 #include <asm/hardware/iomd.h>
14 #include <asm/io.h>
15
16 static inline int fixup_irq(unsigned int irq)
17 {
18         if (irq == IRQ_ISA) {
19                 int isabits = *((volatile unsigned int *)0xe002b700);
20                 if (isabits == 0) {
21                         printk("Spurious ISA IRQ!\n");
22                         return irq;
23                 }
24                 irq = IRQ_ISA_BASE;
25                 while (!(isabits & 1)) {
26                         irq++;
27                         isabits >>= 1;
28                 }
29         }
30
31         return irq;
32 }
33
34 static void cl7500_mask_irq_ack_a(unsigned int irq)
35 {
36         unsigned int val, mask;
37
38         mask = 1 << irq;
39         val = iomd_readb(IOMD_IRQMASKA);
40         iomd_writeb(val & ~mask, IOMD_IRQMASKA);
41         iomd_writeb(mask, IOMD_IRQCLRA);
42 }
43
44 static void cl7500_mask_irq_a(unsigned int irq)
45 {
46         unsigned int val, mask;
47
48         mask = 1 << irq;
49         val = iomd_readb(IOMD_IRQMASKA);
50         iomd_writeb(val & ~mask, IOMD_IRQMASKA);
51 }
52
53 static void cl7500_unmask_irq_a(unsigned int irq)
54 {
55         unsigned int val, mask;
56
57         mask = 1 << irq;
58         val = iomd_readb(IOMD_IRQMASKA);
59         iomd_writeb(val | mask, IOMD_IRQMASKA);
60 }
61
62 static void cl7500_mask_irq_b(unsigned int irq)
63 {
64         unsigned int val, mask;
65
66         mask = 1 << (irq & 7);
67         val = iomd_readb(IOMD_IRQMASKB);
68         iomd_writeb(val & ~mask, IOMD_IRQMASKB);
69 }
70
71 static void cl7500_unmask_irq_b(unsigned int irq)
72 {
73         unsigned int val, mask;
74
75         mask = 1 << (irq & 7);
76         val = iomd_readb(IOMD_IRQMASKB);
77         iomd_writeb(val | mask, IOMD_IRQMASKB);
78 }
79
80 static void cl7500_mask_irq_c(unsigned int irq)
81 {
82         unsigned int val, mask;
83
84         mask = 1 << (irq & 7);
85         val = iomd_readb(IOMD_IRQMASKC);
86         iomd_writeb(val & ~mask, IOMD_IRQMASKC);
87 }
88
89 static void cl7500_unmask_irq_c(unsigned int irq)
90 {
91         unsigned int val, mask;
92
93         mask = 1 << (irq & 7);
94         val = iomd_readb(IOMD_IRQMASKC);
95         iomd_writeb(val | mask, IOMD_IRQMASKC);
96 }
97
98
99 static void cl7500_mask_irq_d(unsigned int irq)
100 {
101         unsigned int val, mask;
102
103         mask = 1 << (irq & 7);
104         val = iomd_readb(IOMD_IRQMASKD);
105         iomd_writeb(val & ~mask, IOMD_IRQMASKD);
106 }
107
108 static void cl7500_unmask_irq_d(unsigned int irq)
109 {
110         unsigned int val, mask;
111
112         mask = 1 << (irq & 7);
113         val = iomd_readb(IOMD_IRQMASKD);
114         iomd_writeb(val | mask, IOMD_IRQMASKD);
115 }
116
117 static void cl7500_mask_irq_dma(unsigned int irq)
118 {
119         unsigned int val, mask;
120
121         mask = 1 << (irq & 7);
122         val = iomd_readb(IOMD_DMAMASK);
123         iomd_writeb(val & ~mask, IOMD_DMAMASK);
124 }
125
126 static void cl7500_unmask_irq_dma(unsigned int irq)
127 {
128         unsigned int val, mask;
129
130         mask = 1 << (irq & 7);
131         val = iomd_readb(IOMD_DMAMASK);
132         iomd_writeb(val | mask, IOMD_DMAMASK);
133 }
134
135 static void cl7500_mask_irq_fiq(unsigned int irq)
136 {
137         unsigned int val, mask;
138
139         mask = 1 << (irq & 7);
140         val = iomd_readb(IOMD_FIQMASK);
141         iomd_writeb(val & ~mask, IOMD_FIQMASK);
142 }
143
144 static void cl7500_unmask_irq_fiq(unsigned int irq)
145 {
146         unsigned int val, mask;
147
148         mask = 1 << (irq & 7);
149         val = iomd_readb(IOMD_FIQMASK);
150         iomd_writeb(val | mask, IOMD_FIQMASK);
151 }
152
153 static void no_action(int cpl, void *dev_id, struct pt_regs *regs)
154 {
155 }
156
157 static struct irqaction irq_isa = { no_action, 0, 0, "isa", NULL, NULL };
158
159 static __inline__ void irq_init_irq(void)
160 {
161         int irq;
162
163         iomd_writeb(0, IOMD_IRQMASKA);
164         iomd_writeb(0, IOMD_IRQMASKB);
165         iomd_writeb(0, IOMD_FIQMASK);
166         iomd_writeb(0, IOMD_DMAMASK);
167
168         for (irq = 0; irq < NR_IRQS; irq++) {
169                 switch (irq) {
170                 case 0 ... 6:
171                         irq_desc[irq].probe_ok = 1;
172                 case 7:
173                         irq_desc[irq].valid    = 1;
174                         irq_desc[irq].mask_ack = cl7500_mask_irq_ack_a;
175                         irq_desc[irq].mask     = cl7500_mask_irq_a;
176                         irq_desc[irq].unmask   = cl7500_unmask_irq_a;
177                         break;
178
179                 case 9 ... 15:
180                         irq_desc[irq].probe_ok = 1;
181                 case 8:
182                         irq_desc[irq].valid    = 1;
183                         irq_desc[irq].mask_ack = cl7500_mask_irq_b;
184                         irq_desc[irq].mask     = cl7500_mask_irq_b;
185                         irq_desc[irq].unmask   = cl7500_unmask_irq_b;
186                         break;
187
188                 case 16 ... 22:
189                         irq_desc[irq].valid    = 1;
190                         irq_desc[irq].mask_ack = cl7500_mask_irq_dma;
191                         irq_desc[irq].mask     = cl7500_mask_irq_dma;
192                         irq_desc[irq].unmask   = cl7500_unmask_irq_dma;
193                         break;
194
195                 case 24 ... 31:
196                         irq_desc[irq].valid    = 1;
197                         irq_desc[irq].mask_ack = cl7500_mask_irq_c;
198                         irq_desc[irq].mask     = cl7500_mask_irq_c;
199                         irq_desc[irq].unmask   = cl7500_unmask_irq_c;
200                         break;
201
202                 case 40 ... 47:
203                         irq_desc[irq].valid    = 1;
204                         irq_desc[irq].mask_ack = cl7500_mask_irq_d;
205                         irq_desc[irq].mask     = cl7500_mask_irq_d;
206                         irq_desc[irq].unmask   = cl7500_unmask_irq_d;
207                         break;
208
209                 case 48 ... 55:
210                         irq_desc[irq].valid      = 1;
211                         irq_desc[irq].probe_ok   = 1;
212                         irq_desc[irq].mask_ack   = no_action;
213                         irq_desc[irq].mask       = no_action;
214                         irq_desc[irq].unmask     = no_action;
215                         break;
216
217                 case 64 ... 72:
218                         irq_desc[irq].valid    = 1;
219                         irq_desc[irq].mask_ack = cl7500_mask_irq_fiq;
220                         irq_desc[irq].mask     = cl7500_mask_irq_fiq;
221                         irq_desc[irq].unmask   = cl7500_unmask_irq_fiq;
222                         break;
223                 }
224         }
225
226         setup_arm_irq(IRQ_ISA, &irq_isa);
227 }