Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /* |
2 | * linux/arch/alpha/kernel/sys_sable.c | |
3 | * | |
4 | * Copyright (C) 1995 David A Rusling | |
5 | * Copyright (C) 1996 Jay A Estabrook | |
6 | * Copyright (C) 1998, 1999 Richard Henderson | |
7 | * | |
8 | * Code supporting the Sable, Sable-Gamma, and Lynx systems. | |
9 | */ | |
10 | ||
1da177e4 LT |
11 | #include <linux/kernel.h> |
12 | #include <linux/types.h> | |
13 | #include <linux/mm.h> | |
14 | #include <linux/sched.h> | |
15 | #include <linux/pci.h> | |
16 | #include <linux/init.h> | |
17 | ||
18 | #include <asm/ptrace.h> | |
19 | #include <asm/system.h> | |
20 | #include <asm/dma.h> | |
21 | #include <asm/irq.h> | |
22 | #include <asm/mmu_context.h> | |
23 | #include <asm/io.h> | |
24 | #include <asm/pgtable.h> | |
25 | #include <asm/core_t2.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 | DEFINE_SPINLOCK(sable_lynx_irq_lock); | |
34 | ||
35 | typedef struct irq_swizzle_struct | |
36 | { | |
37 | char irq_to_mask[64]; | |
38 | char mask_to_irq[64]; | |
39 | ||
40 | /* Note mask bit is true for DISABLED irqs. */ | |
41 | unsigned long shadow_mask; | |
42 | ||
43 | void (*update_irq_hw)(unsigned long bit, unsigned long mask); | |
44 | void (*ack_irq_hw)(unsigned long bit); | |
45 | ||
46 | } irq_swizzle_t; | |
47 | ||
48 | static irq_swizzle_t *sable_lynx_irq_swizzle; | |
49 | ||
4b1135a2 | 50 | static void sable_lynx_init_irq(int nr_of_irqs); |
1da177e4 LT |
51 | |
52 | #if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_SABLE) | |
53 | ||
54 | /***********************************************************************/ | |
55 | /* | |
56 | * For SABLE, which is really baroque, we manage 40 IRQ's, but the | |
57 | * hardware really only supports 24, not via normal ISA PIC, | |
58 | * but cascaded custom 8259's, etc. | |
59 | * 0-7 (char at 536) | |
60 | * 8-15 (char at 53a) | |
61 | * 16-23 (char at 53c) | |
62 | * | |
63 | * Summary Registers (536/53a/53c): | |
64 | * | |
65 | * Bit Meaning Kernel IRQ | |
66 | *------------------------------------------ | |
67 | * 0 PCI slot 0 34 | |
68 | * 1 NCR810 (builtin) 33 | |
69 | * 2 TULIP (builtin) 32 | |
70 | * 3 mouse 12 | |
71 | * 4 PCI slot 1 35 | |
72 | * 5 PCI slot 2 36 | |
73 | * 6 keyboard 1 | |
74 | * 7 floppy 6 | |
75 | * 8 COM2 3 | |
76 | * 9 parallel port 7 | |
77 | *10 EISA irq 3 - | |
78 | *11 EISA irq 4 - | |
79 | *12 EISA irq 5 5 | |
80 | *13 EISA irq 6 - | |
81 | *14 EISA irq 7 - | |
82 | *15 COM1 4 | |
83 | *16 EISA irq 9 9 | |
84 | *17 EISA irq 10 10 | |
85 | *18 EISA irq 11 11 | |
86 | *19 EISA irq 12 - | |
87 | *20 EISA irq 13 - | |
88 | *21 EISA irq 14 14 | |
89 | *22 NC 15 | |
90 | *23 IIC - | |
91 | */ | |
92 | ||
93 | static void | |
94 | sable_update_irq_hw(unsigned long bit, unsigned long mask) | |
95 | { | |
96 | int port = 0x537; | |
97 | ||
98 | if (bit >= 16) { | |
99 | port = 0x53d; | |
100 | mask >>= 16; | |
101 | } else if (bit >= 8) { | |
102 | port = 0x53b; | |
103 | mask >>= 8; | |
104 | } | |
105 | ||
106 | outb(mask, port); | |
107 | } | |
108 | ||
109 | static void | |
110 | sable_ack_irq_hw(unsigned long bit) | |
111 | { | |
112 | int port, val1, val2; | |
113 | ||
114 | if (bit >= 16) { | |
115 | port = 0x53c; | |
116 | val1 = 0xE0 | (bit - 16); | |
117 | val2 = 0xE0 | 4; | |
118 | } else if (bit >= 8) { | |
119 | port = 0x53a; | |
120 | val1 = 0xE0 | (bit - 8); | |
121 | val2 = 0xE0 | 3; | |
122 | } else { | |
123 | port = 0x536; | |
124 | val1 = 0xE0 | (bit - 0); | |
125 | val2 = 0xE0 | 1; | |
126 | } | |
127 | ||
128 | outb(val1, port); /* ack the slave */ | |
129 | outb(val2, 0x534); /* ack the master */ | |
130 | } | |
131 | ||
132 | static irq_swizzle_t sable_irq_swizzle = { | |
133 | { | |
134 | -1, 6, -1, 8, 15, 12, 7, 9, /* pseudo PIC 0-7 */ | |
135 | -1, 16, 17, 18, 3, -1, 21, 22, /* pseudo PIC 8-15 */ | |
136 | -1, -1, -1, -1, -1, -1, -1, -1, /* pseudo EISA 0-7 */ | |
137 | -1, -1, -1, -1, -1, -1, -1, -1, /* pseudo EISA 8-15 */ | |
138 | 2, 1, 0, 4, 5, -1, -1, -1, /* pseudo PCI */ | |
139 | -1, -1, -1, -1, -1, -1, -1, -1, /* */ | |
140 | -1, -1, -1, -1, -1, -1, -1, -1, /* */ | |
141 | -1, -1, -1, -1, -1, -1, -1, -1 /* */ | |
142 | }, | |
143 | { | |
144 | 34, 33, 32, 12, 35, 36, 1, 6, /* mask 0-7 */ | |
145 | 3, 7, -1, -1, 5, -1, -1, 4, /* mask 8-15 */ | |
146 | 9, 10, 11, -1, -1, 14, 15, -1, /* mask 16-23 */ | |
147 | -1, -1, -1, -1, -1, -1, -1, -1, /* */ | |
148 | -1, -1, -1, -1, -1, -1, -1, -1, /* */ | |
149 | -1, -1, -1, -1, -1, -1, -1, -1, /* */ | |
150 | -1, -1, -1, -1, -1, -1, -1, -1, /* */ | |
151 | -1, -1, -1, -1, -1, -1, -1, -1 /* */ | |
152 | }, | |
153 | -1, | |
154 | sable_update_irq_hw, | |
155 | sable_ack_irq_hw | |
156 | }; | |
157 | ||
158 | static void __init | |
159 | sable_init_irq(void) | |
160 | { | |
161 | outb(-1, 0x537); /* slave 0 */ | |
162 | outb(-1, 0x53b); /* slave 1 */ | |
163 | outb(-1, 0x53d); /* slave 2 */ | |
164 | outb(0x44, 0x535); /* enable cascades in master */ | |
165 | ||
166 | sable_lynx_irq_swizzle = &sable_irq_swizzle; | |
167 | sable_lynx_init_irq(40); | |
168 | } | |
169 | ||
170 | /* | |
171 | * PCI Fixup configuration for ALPHA SABLE (2100). | |
172 | * | |
173 | * The device to slot mapping looks like: | |
174 | * | |
175 | * Slot Device | |
176 | * 0 TULIP | |
177 | * 1 SCSI | |
178 | * 2 PCI-EISA bridge | |
179 | * 3 none | |
180 | * 4 none | |
181 | * 5 none | |
182 | * 6 PCI on board slot 0 | |
183 | * 7 PCI on board slot 1 | |
184 | * 8 PCI on board slot 2 | |
185 | * | |
186 | * | |
187 | * This two layered interrupt approach means that we allocate IRQ 16 and | |
188 | * above for PCI interrupts. The IRQ relates to which bit the interrupt | |
189 | * comes in on. This makes interrupt processing much easier. | |
190 | */ | |
191 | /* | |
192 | * NOTE: the IRQ assignments below are arbitrary, but need to be consistent | |
193 | * with the values in the irq swizzling tables above. | |
194 | */ | |
195 | ||
196 | static int __init | |
197 | sable_map_irq(struct pci_dev *dev, u8 slot, u8 pin) | |
198 | { | |
199 | static char irq_tab[9][5] __initdata = { | |
200 | /*INT INTA INTB INTC INTD */ | |
201 | { 32+0, 32+0, 32+0, 32+0, 32+0}, /* IdSel 0, TULIP */ | |
202 | { 32+1, 32+1, 32+1, 32+1, 32+1}, /* IdSel 1, SCSI */ | |
203 | { -1, -1, -1, -1, -1}, /* IdSel 2, SIO */ | |
204 | { -1, -1, -1, -1, -1}, /* IdSel 3, none */ | |
205 | { -1, -1, -1, -1, -1}, /* IdSel 4, none */ | |
206 | { -1, -1, -1, -1, -1}, /* IdSel 5, none */ | |
207 | { 32+2, 32+2, 32+2, 32+2, 32+2}, /* IdSel 6, slot 0 */ | |
208 | { 32+3, 32+3, 32+3, 32+3, 32+3}, /* IdSel 7, slot 1 */ | |
209 | { 32+4, 32+4, 32+4, 32+4, 32+4} /* IdSel 8, slot 2 */ | |
210 | }; | |
211 | long min_idsel = 0, max_idsel = 8, irqs_per_slot = 5; | |
212 | return COMMON_TABLE_LOOKUP; | |
213 | } | |
214 | #endif /* defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_SABLE) */ | |
215 | ||
216 | #if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_LYNX) | |
217 | ||
218 | /***********************************************************************/ | |
219 | /* LYNX hardware specifics | |
220 | */ | |
221 | /* | |
222 | * For LYNX, which is also baroque, we manage 64 IRQs, via a custom IC. | |
223 | * | |
224 | * Bit Meaning Kernel IRQ | |
225 | *------------------------------------------ | |
226 | * 0 | |
227 | * 1 | |
228 | * 2 | |
229 | * 3 mouse 12 | |
230 | * 4 | |
231 | * 5 | |
232 | * 6 keyboard 1 | |
233 | * 7 floppy 6 | |
234 | * 8 COM2 3 | |
235 | * 9 parallel port 7 | |
236 | *10 EISA irq 3 - | |
237 | *11 EISA irq 4 - | |
238 | *12 EISA irq 5 5 | |
239 | *13 EISA irq 6 - | |
240 | *14 EISA irq 7 - | |
241 | *15 COM1 4 | |
242 | *16 EISA irq 9 9 | |
243 | *17 EISA irq 10 10 | |
244 | *18 EISA irq 11 11 | |
245 | *19 EISA irq 12 - | |
246 | *20 | |
247 | *21 EISA irq 14 14 | |
248 | *22 EISA irq 15 15 | |
249 | *23 IIC - | |
250 | *24 VGA (builtin) - | |
251 | *25 | |
252 | *26 | |
253 | *27 | |
254 | *28 NCR810 (builtin) 28 | |
255 | *29 | |
256 | *30 | |
257 | *31 | |
258 | *32 PCI 0 slot 4 A primary bus 32 | |
259 | *33 PCI 0 slot 4 B primary bus 33 | |
260 | *34 PCI 0 slot 4 C primary bus 34 | |
261 | *35 PCI 0 slot 4 D primary bus | |
262 | *36 PCI 0 slot 5 A primary bus | |
263 | *37 PCI 0 slot 5 B primary bus | |
264 | *38 PCI 0 slot 5 C primary bus | |
265 | *39 PCI 0 slot 5 D primary bus | |
266 | *40 PCI 0 slot 6 A primary bus | |
267 | *41 PCI 0 slot 6 B primary bus | |
268 | *42 PCI 0 slot 6 C primary bus | |
269 | *43 PCI 0 slot 6 D primary bus | |
270 | *44 PCI 0 slot 7 A primary bus | |
271 | *45 PCI 0 slot 7 B primary bus | |
272 | *46 PCI 0 slot 7 C primary bus | |
273 | *47 PCI 0 slot 7 D primary bus | |
274 | *48 PCI 0 slot 0 A secondary bus | |
275 | *49 PCI 0 slot 0 B secondary bus | |
276 | *50 PCI 0 slot 0 C secondary bus | |
277 | *51 PCI 0 slot 0 D secondary bus | |
278 | *52 PCI 0 slot 1 A secondary bus | |
279 | *53 PCI 0 slot 1 B secondary bus | |
280 | *54 PCI 0 slot 1 C secondary bus | |
281 | *55 PCI 0 slot 1 D secondary bus | |
282 | *56 PCI 0 slot 2 A secondary bus | |
283 | *57 PCI 0 slot 2 B secondary bus | |
284 | *58 PCI 0 slot 2 C secondary bus | |
285 | *59 PCI 0 slot 2 D secondary bus | |
286 | *60 PCI 0 slot 3 A secondary bus | |
287 | *61 PCI 0 slot 3 B secondary bus | |
288 | *62 PCI 0 slot 3 C secondary bus | |
289 | *63 PCI 0 slot 3 D secondary bus | |
290 | */ | |
291 | ||
292 | static void | |
293 | lynx_update_irq_hw(unsigned long bit, unsigned long mask) | |
294 | { | |
295 | /* | |
296 | * Write the AIR register on the T3/T4 with the | |
297 | * address of the IC mask register (offset 0x40) | |
298 | */ | |
299 | *(vulp)T2_AIR = 0x40; | |
300 | mb(); | |
301 | *(vulp)T2_AIR; /* re-read to force write */ | |
302 | mb(); | |
303 | *(vulp)T2_DIR = mask; | |
304 | mb(); | |
305 | mb(); | |
306 | } | |
307 | ||
308 | static void | |
309 | lynx_ack_irq_hw(unsigned long bit) | |
310 | { | |
311 | *(vulp)T2_VAR = (u_long) bit; | |
312 | mb(); | |
313 | mb(); | |
314 | } | |
315 | ||
316 | static irq_swizzle_t lynx_irq_swizzle = { | |
317 | { /* irq_to_mask */ | |
318 | -1, 6, -1, 8, 15, 12, 7, 9, /* pseudo PIC 0-7 */ | |
319 | -1, 16, 17, 18, 3, -1, 21, 22, /* pseudo PIC 8-15 */ | |
320 | -1, -1, -1, -1, -1, -1, -1, -1, /* pseudo */ | |
321 | -1, -1, -1, -1, 28, -1, -1, -1, /* pseudo */ | |
322 | 32, 33, 34, 35, 36, 37, 38, 39, /* mask 32-39 */ | |
323 | 40, 41, 42, 43, 44, 45, 46, 47, /* mask 40-47 */ | |
324 | 48, 49, 50, 51, 52, 53, 54, 55, /* mask 48-55 */ | |
325 | 56, 57, 58, 59, 60, 61, 62, 63 /* mask 56-63 */ | |
326 | }, | |
327 | { /* mask_to_irq */ | |
328 | -1, -1, -1, 12, -1, -1, 1, 6, /* mask 0-7 */ | |
329 | 3, 7, -1, -1, 5, -1, -1, 4, /* mask 8-15 */ | |
330 | 9, 10, 11, -1, -1, 14, 15, -1, /* mask 16-23 */ | |
331 | -1, -1, -1, -1, 28, -1, -1, -1, /* mask 24-31 */ | |
332 | 32, 33, 34, 35, 36, 37, 38, 39, /* mask 32-39 */ | |
333 | 40, 41, 42, 43, 44, 45, 46, 47, /* mask 40-47 */ | |
334 | 48, 49, 50, 51, 52, 53, 54, 55, /* mask 48-55 */ | |
335 | 56, 57, 58, 59, 60, 61, 62, 63 /* mask 56-63 */ | |
336 | }, | |
337 | -1, | |
338 | lynx_update_irq_hw, | |
339 | lynx_ack_irq_hw | |
340 | }; | |
341 | ||
342 | static void __init | |
343 | lynx_init_irq(void) | |
344 | { | |
345 | sable_lynx_irq_swizzle = &lynx_irq_swizzle; | |
346 | sable_lynx_init_irq(64); | |
347 | } | |
348 | ||
349 | /* | |
350 | * PCI Fixup configuration for ALPHA LYNX (2100A) | |
351 | * | |
352 | * The device to slot mapping looks like: | |
353 | * | |
354 | * Slot Device | |
355 | * 0 none | |
356 | * 1 none | |
357 | * 2 PCI-EISA bridge | |
358 | * 3 PCI-PCI bridge | |
359 | * 4 NCR 810 (Demi-Lynx only) | |
360 | * 5 none | |
361 | * 6 PCI on board slot 4 | |
362 | * 7 PCI on board slot 5 | |
363 | * 8 PCI on board slot 6 | |
364 | * 9 PCI on board slot 7 | |
365 | * | |
366 | * And behind the PPB we have: | |
367 | * | |
368 | * 11 PCI on board slot 0 | |
369 | * 12 PCI on board slot 1 | |
370 | * 13 PCI on board slot 2 | |
371 | * 14 PCI on board slot 3 | |
372 | */ | |
373 | /* | |
374 | * NOTE: the IRQ assignments below are arbitrary, but need to be consistent | |
375 | * with the values in the irq swizzling tables above. | |
376 | */ | |
377 | ||
378 | static int __init | |
379 | lynx_map_irq(struct pci_dev *dev, u8 slot, u8 pin) | |
380 | { | |
381 | static char irq_tab[19][5] __initdata = { | |
382 | /*INT INTA INTB INTC INTD */ | |
383 | { -1, -1, -1, -1, -1}, /* IdSel 13, PCEB */ | |
384 | { -1, -1, -1, -1, -1}, /* IdSel 14, PPB */ | |
385 | { 28, 28, 28, 28, 28}, /* IdSel 15, NCR demi */ | |
386 | { -1, -1, -1, -1, -1}, /* IdSel 16, none */ | |
387 | { 32, 32, 33, 34, 35}, /* IdSel 17, slot 4 */ | |
388 | { 36, 36, 37, 38, 39}, /* IdSel 18, slot 5 */ | |
389 | { 40, 40, 41, 42, 43}, /* IdSel 19, slot 6 */ | |
390 | { 44, 44, 45, 46, 47}, /* IdSel 20, slot 7 */ | |
391 | { -1, -1, -1, -1, -1}, /* IdSel 22, none */ | |
392 | /* The following are actually behind the PPB. */ | |
393 | { -1, -1, -1, -1, -1}, /* IdSel 16 none */ | |
394 | { 28, 28, 28, 28, 28}, /* IdSel 17 NCR lynx */ | |
395 | { -1, -1, -1, -1, -1}, /* IdSel 18 none */ | |
396 | { -1, -1, -1, -1, -1}, /* IdSel 19 none */ | |
397 | { -1, -1, -1, -1, -1}, /* IdSel 20 none */ | |
398 | { -1, -1, -1, -1, -1}, /* IdSel 21 none */ | |
399 | { 48, 48, 49, 50, 51}, /* IdSel 22 slot 0 */ | |
400 | { 52, 52, 53, 54, 55}, /* IdSel 23 slot 1 */ | |
401 | { 56, 56, 57, 58, 59}, /* IdSel 24 slot 2 */ | |
402 | { 60, 60, 61, 62, 63} /* IdSel 25 slot 3 */ | |
403 | }; | |
404 | const long min_idsel = 2, max_idsel = 20, irqs_per_slot = 5; | |
405 | return COMMON_TABLE_LOOKUP; | |
406 | } | |
407 | ||
408 | static u8 __init | |
409 | lynx_swizzle(struct pci_dev *dev, u8 *pinp) | |
410 | { | |
411 | int slot, pin = *pinp; | |
412 | ||
413 | if (dev->bus->number == 0) { | |
414 | slot = PCI_SLOT(dev->devfn); | |
415 | } | |
416 | /* Check for the built-in bridge */ | |
417 | else if (PCI_SLOT(dev->bus->self->devfn) == 3) { | |
418 | slot = PCI_SLOT(dev->devfn) + 11; | |
419 | } | |
420 | else | |
421 | { | |
422 | /* Must be a card-based bridge. */ | |
423 | do { | |
424 | if (PCI_SLOT(dev->bus->self->devfn) == 3) { | |
425 | slot = PCI_SLOT(dev->devfn) + 11; | |
426 | break; | |
427 | } | |
1be9baa0 | 428 | pin = pci_swizzle_interrupt_pin(dev, pin); |
1da177e4 LT |
429 | |
430 | /* Move up the chain of bridges. */ | |
431 | dev = dev->bus->self; | |
432 | /* Slot of the next bridge. */ | |
433 | slot = PCI_SLOT(dev->devfn); | |
434 | } while (dev->bus->self); | |
435 | } | |
436 | *pinp = pin; | |
437 | return slot; | |
438 | } | |
439 | ||
440 | #endif /* defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_LYNX) */ | |
441 | ||
442 | /***********************************************************************/ | |
443 | /* GENERIC irq routines */ | |
444 | ||
445 | static inline void | |
c90c10c8 | 446 | sable_lynx_enable_irq(struct irq_data *d) |
1da177e4 LT |
447 | { |
448 | unsigned long bit, mask; | |
449 | ||
c90c10c8 | 450 | bit = sable_lynx_irq_swizzle->irq_to_mask[d->irq]; |
1da177e4 LT |
451 | spin_lock(&sable_lynx_irq_lock); |
452 | mask = sable_lynx_irq_swizzle->shadow_mask &= ~(1UL << bit); | |
453 | sable_lynx_irq_swizzle->update_irq_hw(bit, mask); | |
454 | spin_unlock(&sable_lynx_irq_lock); | |
455 | #if 0 | |
5f0e3da6 | 456 | printk("%s: mask 0x%lx bit 0x%lx irq 0x%x\n", |
bbb8d343 | 457 | __func__, mask, bit, irq); |
1da177e4 LT |
458 | #endif |
459 | } | |
460 | ||
461 | static void | |
c90c10c8 | 462 | sable_lynx_disable_irq(struct irq_data *d) |
1da177e4 LT |
463 | { |
464 | unsigned long bit, mask; | |
465 | ||
c90c10c8 | 466 | bit = sable_lynx_irq_swizzle->irq_to_mask[d->irq]; |
1da177e4 LT |
467 | spin_lock(&sable_lynx_irq_lock); |
468 | mask = sable_lynx_irq_swizzle->shadow_mask |= 1UL << bit; | |
469 | sable_lynx_irq_swizzle->update_irq_hw(bit, mask); | |
470 | spin_unlock(&sable_lynx_irq_lock); | |
471 | #if 0 | |
5f0e3da6 | 472 | printk("%s: mask 0x%lx bit 0x%lx irq 0x%x\n", |
bbb8d343 | 473 | __func__, mask, bit, irq); |
1da177e4 LT |
474 | #endif |
475 | } | |
476 | ||
1da177e4 | 477 | static void |
c90c10c8 | 478 | sable_lynx_mask_and_ack_irq(struct irq_data *d) |
1da177e4 LT |
479 | { |
480 | unsigned long bit, mask; | |
481 | ||
c90c10c8 | 482 | bit = sable_lynx_irq_swizzle->irq_to_mask[d->irq]; |
1da177e4 LT |
483 | spin_lock(&sable_lynx_irq_lock); |
484 | mask = sable_lynx_irq_swizzle->shadow_mask |= 1UL << bit; | |
485 | sable_lynx_irq_swizzle->update_irq_hw(bit, mask); | |
486 | sable_lynx_irq_swizzle->ack_irq_hw(bit); | |
487 | spin_unlock(&sable_lynx_irq_lock); | |
488 | } | |
489 | ||
44377f62 | 490 | static struct irq_chip sable_lynx_irq_type = { |
8ab1221c | 491 | .name = "SABLE/LYNX", |
c90c10c8 TG |
492 | .irq_unmask = sable_lynx_enable_irq, |
493 | .irq_mask = sable_lynx_disable_irq, | |
494 | .irq_mask_ack = sable_lynx_mask_and_ack_irq, | |
1da177e4 LT |
495 | }; |
496 | ||
497 | static void | |
7ca56053 | 498 | sable_lynx_srm_device_interrupt(unsigned long vector) |
1da177e4 LT |
499 | { |
500 | /* Note that the vector reported by the SRM PALcode corresponds | |
501 | to the interrupt mask bits, but we have to manage via the | |
502 | so-called legacy IRQs for many common devices. */ | |
503 | ||
504 | int bit, irq; | |
505 | ||
506 | bit = (vector - 0x800) >> 4; | |
507 | irq = sable_lynx_irq_swizzle->mask_to_irq[bit]; | |
508 | #if 0 | |
509 | printk("%s: vector 0x%lx bit 0x%x irq 0x%x\n", | |
bbb8d343 | 510 | __func__, vector, bit, irq); |
1da177e4 | 511 | #endif |
3dbb8c62 | 512 | handle_irq(irq); |
1da177e4 LT |
513 | } |
514 | ||
515 | static void __init | |
4b1135a2 | 516 | sable_lynx_init_irq(int nr_of_irqs) |
1da177e4 LT |
517 | { |
518 | long i; | |
519 | ||
4b1135a2 | 520 | for (i = 0; i < nr_of_irqs; ++i) { |
a9eb076b TG |
521 | irq_set_chip_and_handler(i, &sable_lynx_irq_type, |
522 | handle_level_irq); | |
c90c10c8 | 523 | irq_set_status_flags(i, IRQ_LEVEL); |
1da177e4 LT |
524 | } |
525 | ||
526 | common_init_isa_dma(); | |
527 | } | |
528 | ||
529 | static void __init | |
530 | sable_lynx_init_pci(void) | |
531 | { | |
532 | common_init_pci(); | |
533 | } | |
534 | ||
535 | /*****************************************************************/ | |
536 | /* | |
537 | * The System Vectors | |
538 | * | |
539 | * In order that T2_HAE_ADDRESS should be a constant, we play | |
540 | * these games with GAMMA_BIAS. | |
541 | */ | |
542 | ||
543 | #if defined(CONFIG_ALPHA_GENERIC) || \ | |
544 | (defined(CONFIG_ALPHA_SABLE) && !defined(CONFIG_ALPHA_GAMMA)) | |
545 | #undef GAMMA_BIAS | |
546 | #define GAMMA_BIAS 0 | |
547 | struct alpha_machine_vector sable_mv __initmv = { | |
548 | .vector_name = "Sable", | |
549 | DO_EV4_MMU, | |
550 | DO_DEFAULT_RTC, | |
551 | DO_T2_IO, | |
552 | .machine_check = t2_machine_check, | |
553 | .max_isa_dma_address = ALPHA_SABLE_MAX_ISA_DMA_ADDRESS, | |
554 | .min_io_address = EISA_DEFAULT_IO_BASE, | |
555 | .min_mem_address = T2_DEFAULT_MEM_BASE, | |
556 | ||
557 | .nr_irqs = 40, | |
558 | .device_interrupt = sable_lynx_srm_device_interrupt, | |
559 | ||
560 | .init_arch = t2_init_arch, | |
561 | .init_irq = sable_init_irq, | |
562 | .init_rtc = common_init_rtc, | |
563 | .init_pci = sable_lynx_init_pci, | |
564 | .kill_arch = t2_kill_arch, | |
565 | .pci_map_irq = sable_map_irq, | |
566 | .pci_swizzle = common_swizzle, | |
567 | ||
568 | .sys = { .t2 = { | |
569 | .gamma_bias = 0 | |
570 | } } | |
571 | }; | |
572 | ALIAS_MV(sable) | |
573 | #endif /* GENERIC || (SABLE && !GAMMA) */ | |
574 | ||
575 | #if defined(CONFIG_ALPHA_GENERIC) || \ | |
576 | (defined(CONFIG_ALPHA_SABLE) && defined(CONFIG_ALPHA_GAMMA)) | |
577 | #undef GAMMA_BIAS | |
578 | #define GAMMA_BIAS _GAMMA_BIAS | |
579 | struct alpha_machine_vector sable_gamma_mv __initmv = { | |
580 | .vector_name = "Sable-Gamma", | |
581 | DO_EV5_MMU, | |
582 | DO_DEFAULT_RTC, | |
583 | DO_T2_IO, | |
584 | .machine_check = t2_machine_check, | |
585 | .max_isa_dma_address = ALPHA_SABLE_MAX_ISA_DMA_ADDRESS, | |
586 | .min_io_address = EISA_DEFAULT_IO_BASE, | |
587 | .min_mem_address = T2_DEFAULT_MEM_BASE, | |
588 | ||
589 | .nr_irqs = 40, | |
590 | .device_interrupt = sable_lynx_srm_device_interrupt, | |
591 | ||
592 | .init_arch = t2_init_arch, | |
593 | .init_irq = sable_init_irq, | |
594 | .init_rtc = common_init_rtc, | |
595 | .init_pci = sable_lynx_init_pci, | |
596 | .kill_arch = t2_kill_arch, | |
597 | .pci_map_irq = sable_map_irq, | |
598 | .pci_swizzle = common_swizzle, | |
599 | ||
600 | .sys = { .t2 = { | |
601 | .gamma_bias = _GAMMA_BIAS | |
602 | } } | |
603 | }; | |
604 | ALIAS_MV(sable_gamma) | |
605 | #endif /* GENERIC || (SABLE && GAMMA) */ | |
606 | ||
607 | #if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_LYNX) | |
608 | #undef GAMMA_BIAS | |
609 | #define GAMMA_BIAS _GAMMA_BIAS | |
610 | struct alpha_machine_vector lynx_mv __initmv = { | |
611 | .vector_name = "Lynx", | |
612 | DO_EV4_MMU, | |
613 | DO_DEFAULT_RTC, | |
614 | DO_T2_IO, | |
615 | .machine_check = t2_machine_check, | |
616 | .max_isa_dma_address = ALPHA_SABLE_MAX_ISA_DMA_ADDRESS, | |
617 | .min_io_address = EISA_DEFAULT_IO_BASE, | |
618 | .min_mem_address = T2_DEFAULT_MEM_BASE, | |
619 | ||
620 | .nr_irqs = 64, | |
621 | .device_interrupt = sable_lynx_srm_device_interrupt, | |
622 | ||
623 | .init_arch = t2_init_arch, | |
624 | .init_irq = lynx_init_irq, | |
625 | .init_rtc = common_init_rtc, | |
626 | .init_pci = sable_lynx_init_pci, | |
627 | .kill_arch = t2_kill_arch, | |
628 | .pci_map_irq = lynx_map_irq, | |
629 | .pci_swizzle = lynx_swizzle, | |
630 | ||
631 | .sys = { .t2 = { | |
632 | .gamma_bias = _GAMMA_BIAS | |
633 | } } | |
634 | }; | |
635 | ALIAS_MV(lynx) | |
636 | #endif /* GENERIC || LYNX */ |