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