This source file includes following definitions.
- wildfire_update_irq_hw
- wildfire_init_irq_hw
- wildfire_enable_irq
- wildfire_disable_irq
- wildfire_mask_and_ack_irq
- wildfire_init_irq_per_pca
- wildfire_init_irq
- wildfire_device_interrupt
- wildfire_map_irq
1
2
3
4
5
6
7
8
9
10 #include <linux/kernel.h>
11 #include <linux/types.h>
12 #include <linux/mm.h>
13 #include <linux/sched.h>
14 #include <linux/pci.h>
15 #include <linux/init.h>
16 #include <linux/bitops.h>
17
18 #include <asm/ptrace.h>
19 #include <asm/dma.h>
20 #include <asm/irq.h>
21 #include <asm/mmu_context.h>
22 #include <asm/io.h>
23 #include <asm/pgtable.h>
24 #include <asm/core_wildfire.h>
25 #include <asm/hwrpb.h>
26 #include <asm/tlbflush.h>
27
28 #include "proto.h"
29 #include "irq_impl.h"
30 #include "pci_impl.h"
31 #include "machvec_impl.h"
32
33 static unsigned long cached_irq_mask[WILDFIRE_NR_IRQS/(sizeof(long)*8)];
34
35 DEFINE_SPINLOCK(wildfire_irq_lock);
36
37 static int doing_init_irq_hw = 0;
38
39 static void
40 wildfire_update_irq_hw(unsigned int irq)
41 {
42 int qbbno = (irq >> 8) & (WILDFIRE_MAX_QBB - 1);
43 int pcano = (irq >> 6) & (WILDFIRE_PCA_PER_QBB - 1);
44 wildfire_pca *pca;
45 volatile unsigned long * enable0;
46
47 if (!WILDFIRE_PCA_EXISTS(qbbno, pcano)) {
48 if (!doing_init_irq_hw) {
49 printk(KERN_ERR "wildfire_update_irq_hw:"
50 " got irq %d for non-existent PCA %d"
51 " on QBB %d.\n",
52 irq, pcano, qbbno);
53 }
54 return;
55 }
56
57 pca = WILDFIRE_pca(qbbno, pcano);
58 enable0 = (unsigned long *) &pca->pca_int[0].enable;
59
60 *enable0 = cached_irq_mask[qbbno * WILDFIRE_PCA_PER_QBB + pcano];
61 mb();
62 *enable0;
63 }
64
65 static void __init
66 wildfire_init_irq_hw(void)
67 {
68 #if 0
69 register wildfire_pca * pca = WILDFIRE_pca(0, 0);
70 volatile unsigned long * enable0, * enable1, * enable2, *enable3;
71 volatile unsigned long * target0, * target1, * target2, *target3;
72
73 enable0 = (unsigned long *) &pca->pca_int[0].enable;
74 enable1 = (unsigned long *) &pca->pca_int[1].enable;
75 enable2 = (unsigned long *) &pca->pca_int[2].enable;
76 enable3 = (unsigned long *) &pca->pca_int[3].enable;
77
78 target0 = (unsigned long *) &pca->pca_int[0].target;
79 target1 = (unsigned long *) &pca->pca_int[1].target;
80 target2 = (unsigned long *) &pca->pca_int[2].target;
81 target3 = (unsigned long *) &pca->pca_int[3].target;
82
83 *enable0 = *enable1 = *enable2 = *enable3 = 0;
84
85 *target0 = (1UL<<8) | WILDFIRE_QBB(0);
86 *target1 = *target2 = *target3 = 0;
87
88 mb();
89
90 *enable0; *enable1; *enable2; *enable3;
91 *target0; *target1; *target2; *target3;
92
93 #else
94 int i;
95
96 doing_init_irq_hw = 1;
97
98
99 for (i = 0; i < WILDFIRE_NR_IRQS; i+=WILDFIRE_IRQ_PER_PCA)
100 wildfire_update_irq_hw(i);
101
102 doing_init_irq_hw = 0;
103 #endif
104 }
105
106 static void
107 wildfire_enable_irq(struct irq_data *d)
108 {
109 unsigned int irq = d->irq;
110
111 if (irq < 16)
112 i8259a_enable_irq(d);
113
114 spin_lock(&wildfire_irq_lock);
115 set_bit(irq, &cached_irq_mask);
116 wildfire_update_irq_hw(irq);
117 spin_unlock(&wildfire_irq_lock);
118 }
119
120 static void
121 wildfire_disable_irq(struct irq_data *d)
122 {
123 unsigned int irq = d->irq;
124
125 if (irq < 16)
126 i8259a_disable_irq(d);
127
128 spin_lock(&wildfire_irq_lock);
129 clear_bit(irq, &cached_irq_mask);
130 wildfire_update_irq_hw(irq);
131 spin_unlock(&wildfire_irq_lock);
132 }
133
134 static void
135 wildfire_mask_and_ack_irq(struct irq_data *d)
136 {
137 unsigned int irq = d->irq;
138
139 if (irq < 16)
140 i8259a_mask_and_ack_irq(d);
141
142 spin_lock(&wildfire_irq_lock);
143 clear_bit(irq, &cached_irq_mask);
144 wildfire_update_irq_hw(irq);
145 spin_unlock(&wildfire_irq_lock);
146 }
147
148 static struct irq_chip wildfire_irq_type = {
149 .name = "WILDFIRE",
150 .irq_unmask = wildfire_enable_irq,
151 .irq_mask = wildfire_disable_irq,
152 .irq_mask_ack = wildfire_mask_and_ack_irq,
153 };
154
155 static void __init
156 wildfire_init_irq_per_pca(int qbbno, int pcano)
157 {
158 int i, irq_bias;
159 static struct irqaction isa_enable = {
160 .handler = no_action,
161 .name = "isa_enable",
162 };
163
164 irq_bias = qbbno * (WILDFIRE_PCA_PER_QBB * WILDFIRE_IRQ_PER_PCA)
165 + pcano * WILDFIRE_IRQ_PER_PCA;
166
167 #if 0
168 unsigned long io_bias;
169
170
171 io_bias = WILDFIRE_IO(qbbno, pcano<<1) - WILDFIRE_IO_BIAS;
172
173 outb(0, DMA1_RESET_REG + io_bias);
174 outb(0, DMA2_RESET_REG + io_bias);
175 outb(DMA_MODE_CASCADE, DMA2_MODE_REG + io_bias);
176 outb(0, DMA2_MASK_REG + io_bias);
177 #endif
178
179 #if 0
180
181 init_i8259a_irqs();
182 #endif
183
184 for (i = 0; i < 16; ++i) {
185 if (i == 2)
186 continue;
187 irq_set_chip_and_handler(i + irq_bias, &wildfire_irq_type,
188 handle_level_irq);
189 irq_set_status_flags(i + irq_bias, IRQ_LEVEL);
190 }
191
192 irq_set_chip_and_handler(36 + irq_bias, &wildfire_irq_type,
193 handle_level_irq);
194 irq_set_status_flags(36 + irq_bias, IRQ_LEVEL);
195 for (i = 40; i < 64; ++i) {
196 irq_set_chip_and_handler(i + irq_bias, &wildfire_irq_type,
197 handle_level_irq);
198 irq_set_status_flags(i + irq_bias, IRQ_LEVEL);
199 }
200
201 setup_irq(32+irq_bias, &isa_enable);
202 }
203
204 static void __init
205 wildfire_init_irq(void)
206 {
207 int qbbno, pcano;
208
209 #if 1
210 wildfire_init_irq_hw();
211 init_i8259a_irqs();
212 #endif
213
214 for (qbbno = 0; qbbno < WILDFIRE_MAX_QBB; qbbno++) {
215 if (WILDFIRE_QBB_EXISTS(qbbno)) {
216 for (pcano = 0; pcano < WILDFIRE_PCA_PER_QBB; pcano++) {
217 if (WILDFIRE_PCA_EXISTS(qbbno, pcano)) {
218 wildfire_init_irq_per_pca(qbbno, pcano);
219 }
220 }
221 }
222 }
223 }
224
225 static void
226 wildfire_device_interrupt(unsigned long vector)
227 {
228 int irq;
229
230 irq = (vector - 0x800) >> 4;
231
232
233
234
235
236
237
238 handle_irq(irq);
239 return;
240 }
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292 static int
293 wildfire_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
294 {
295 static char irq_tab[8][5] = {
296
297 { -1, -1, -1, -1, -1},
298 { 36, 36, 36+1, 36+2, 36+3},
299 { 40, 40, 40+1, 40+2, 40+3},
300 { 44, 44, 44+1, 44+2, 44+3},
301 { 48, 48, 48+1, 48+2, 48+3},
302 { 52, 52, 52+1, 52+2, 52+3},
303 { 56, 56, 56+1, 56+2, 56+3},
304 { 60, 60, 60+1, 60+2, 60+3},
305 };
306 long min_idsel = 0, max_idsel = 7, irqs_per_slot = 5;
307
308 struct pci_controller *hose = dev->sysdata;
309 int irq = COMMON_TABLE_LOOKUP;
310
311 if (irq > 0) {
312 int qbbno = hose->index >> 3;
313 int pcano = (hose->index >> 1) & 3;
314 irq += (qbbno << 8) + (pcano << 6);
315 }
316 return irq;
317 }
318
319
320
321
322
323
324 struct alpha_machine_vector wildfire_mv __initmv = {
325 .vector_name = "WILDFIRE",
326 DO_EV6_MMU,
327 DO_DEFAULT_RTC,
328 DO_WILDFIRE_IO,
329 .machine_check = wildfire_machine_check,
330 .max_isa_dma_address = ALPHA_MAX_ISA_DMA_ADDRESS,
331 .min_io_address = DEFAULT_IO_BASE,
332 .min_mem_address = DEFAULT_MEM_BASE,
333
334 .nr_irqs = WILDFIRE_NR_IRQS,
335 .device_interrupt = wildfire_device_interrupt,
336
337 .init_arch = wildfire_init_arch,
338 .init_irq = wildfire_init_irq,
339 .init_rtc = common_init_rtc,
340 .init_pci = common_init_pci,
341 .kill_arch = wildfire_kill_arch,
342 .pci_map_irq = wildfire_map_irq,
343 .pci_swizzle = common_swizzle,
344
345 .pa_to_nid = wildfire_pa_to_nid,
346 .cpuid_to_nid = wildfire_cpuid_to_nid,
347 .node_mem_start = wildfire_node_mem_start,
348 .node_mem_size = wildfire_node_mem_size,
349 };
350 ALIAS_MV(wildfire)