File: /usr/src/linux/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 }
228