This source file includes following definitions.
- sable_update_irq_hw
- sable_ack_irq_hw
- sable_init_irq
- sable_map_irq
- lynx_update_irq_hw
- lynx_ack_irq_hw
- lynx_init_irq
- lynx_map_irq
- lynx_swizzle
- sable_lynx_enable_irq
- sable_lynx_disable_irq
- sable_lynx_mask_and_ack_irq
- sable_lynx_srm_device_interrupt
- sable_lynx_init_irq
- sable_lynx_init_pci
1
2
3
4
5
6
7
8
9
10
11
12 #include <linux/kernel.h>
13 #include <linux/types.h>
14 #include <linux/mm.h>
15 #include <linux/sched.h>
16 #include <linux/pci.h>
17 #include <linux/init.h>
18
19 #include <asm/ptrace.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
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
50 static void sable_lynx_init_irq(int nr_of_irqs);
51
52 #if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_SABLE)
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
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);
129 outb(val2, 0x534);
130 }
131
132 static irq_swizzle_t sable_irq_swizzle = {
133 {
134 -1, 6, -1, 8, 15, 12, 7, 9,
135 -1, 16, 17, 18, 3, -1, 21, 22,
136 -1, -1, -1, -1, -1, -1, -1, -1,
137 -1, -1, -1, -1, -1, -1, -1, -1,
138 2, 1, 0, 4, 5, -1, -1, -1,
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,
145 3, 7, -1, -1, 5, -1, -1, 4,
146 9, 10, 11, -1, -1, 14, 15, -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 -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);
162 outb(-1, 0x53b);
163 outb(-1, 0x53d);
164 outb(0x44, 0x535);
165
166 sable_lynx_irq_swizzle = &sable_irq_swizzle;
167 sable_lynx_init_irq(40);
168 }
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196 static int
197 sable_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
198 {
199 static char irq_tab[9][5] = {
200
201 { 32+0, 32+0, 32+0, 32+0, 32+0},
202 { 32+1, 32+1, 32+1, 32+1, 32+1},
203 { -1, -1, -1, -1, -1},
204 { -1, -1, -1, -1, -1},
205 { -1, -1, -1, -1, -1},
206 { -1, -1, -1, -1, -1},
207 { 32+2, 32+2, 32+2, 32+2, 32+2},
208 { 32+3, 32+3, 32+3, 32+3, 32+3},
209 { 32+4, 32+4, 32+4, 32+4, 32+4}
210 };
211 long min_idsel = 0, max_idsel = 8, irqs_per_slot = 5;
212 return COMMON_TABLE_LOOKUP;
213 }
214 #endif
215
216 #if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_LYNX)
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
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 void
293 lynx_update_irq_hw(unsigned long bit, unsigned long mask)
294 {
295
296
297
298
299 *(vulp)T2_AIR = 0x40;
300 mb();
301 *(vulp)T2_AIR;
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 {
318 -1, 6, -1, 8, 15, 12, 7, 9,
319 -1, 16, 17, 18, 3, -1, 21, 22,
320 -1, -1, -1, -1, -1, -1, -1, -1,
321 -1, -1, -1, -1, 28, -1, -1, -1,
322 32, 33, 34, 35, 36, 37, 38, 39,
323 40, 41, 42, 43, 44, 45, 46, 47,
324 48, 49, 50, 51, 52, 53, 54, 55,
325 56, 57, 58, 59, 60, 61, 62, 63
326 },
327 {
328 -1, -1, -1, 12, -1, -1, 1, 6,
329 3, 7, -1, -1, 5, -1, -1, 4,
330 9, 10, 11, -1, -1, 14, 15, -1,
331 -1, -1, -1, -1, 28, -1, -1, -1,
332 32, 33, 34, 35, 36, 37, 38, 39,
333 40, 41, 42, 43, 44, 45, 46, 47,
334 48, 49, 50, 51, 52, 53, 54, 55,
335 56, 57, 58, 59, 60, 61, 62, 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
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378 static int
379 lynx_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
380 {
381 static char irq_tab[19][5] = {
382
383 { -1, -1, -1, -1, -1},
384 { -1, -1, -1, -1, -1},
385 { 28, 28, 28, 28, 28},
386 { -1, -1, -1, -1, -1},
387 { 32, 32, 33, 34, 35},
388 { 36, 36, 37, 38, 39},
389 { 40, 40, 41, 42, 43},
390 { 44, 44, 45, 46, 47},
391 { -1, -1, -1, -1, -1},
392
393 { -1, -1, -1, -1, -1},
394 { 28, 28, 28, 28, 28},
395 { -1, -1, -1, -1, -1},
396 { -1, -1, -1, -1, -1},
397 { -1, -1, -1, -1, -1},
398 { -1, -1, -1, -1, -1},
399 { 48, 48, 49, 50, 51},
400 { 52, 52, 53, 54, 55},
401 { 56, 56, 57, 58, 59},
402 { 60, 60, 61, 62, 63}
403 };
404 const long min_idsel = 2, max_idsel = 20, irqs_per_slot = 5;
405 return COMMON_TABLE_LOOKUP;
406 }
407
408 static u8
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
417 else if (PCI_SLOT(dev->bus->self->devfn) == 3) {
418 slot = PCI_SLOT(dev->devfn) + 11;
419 }
420 else
421 {
422
423 do {
424 if (PCI_SLOT(dev->bus->self->devfn) == 3) {
425 slot = PCI_SLOT(dev->devfn) + 11;
426 break;
427 }
428 pin = pci_swizzle_interrupt_pin(dev, pin);
429
430
431 dev = dev->bus->self;
432
433 slot = PCI_SLOT(dev->devfn);
434 } while (dev->bus->self);
435 }
436 *pinp = pin;
437 return slot;
438 }
439
440 #endif
441
442
443
444
445 static inline void
446 sable_lynx_enable_irq(struct irq_data *d)
447 {
448 unsigned long bit, mask;
449
450 bit = sable_lynx_irq_swizzle->irq_to_mask[d->irq];
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
456 printk("%s: mask 0x%lx bit 0x%lx irq 0x%x\n",
457 __func__, mask, bit, irq);
458 #endif
459 }
460
461 static void
462 sable_lynx_disable_irq(struct irq_data *d)
463 {
464 unsigned long bit, mask;
465
466 bit = sable_lynx_irq_swizzle->irq_to_mask[d->irq];
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
472 printk("%s: mask 0x%lx bit 0x%lx irq 0x%x\n",
473 __func__, mask, bit, irq);
474 #endif
475 }
476
477 static void
478 sable_lynx_mask_and_ack_irq(struct irq_data *d)
479 {
480 unsigned long bit, mask;
481
482 bit = sable_lynx_irq_swizzle->irq_to_mask[d->irq];
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
490 static struct irq_chip sable_lynx_irq_type = {
491 .name = "SABLE/LYNX",
492 .irq_unmask = sable_lynx_enable_irq,
493 .irq_mask = sable_lynx_disable_irq,
494 .irq_mask_ack = sable_lynx_mask_and_ack_irq,
495 };
496
497 static void
498 sable_lynx_srm_device_interrupt(unsigned long vector)
499 {
500
501
502
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",
510 __func__, vector, bit, irq);
511 #endif
512 handle_irq(irq);
513 }
514
515 static void __init
516 sable_lynx_init_irq(int nr_of_irqs)
517 {
518 long i;
519
520 for (i = 0; i < nr_of_irqs; ++i) {
521 irq_set_chip_and_handler(i, &sable_lynx_irq_type,
522 handle_level_irq);
523 irq_set_status_flags(i, IRQ_LEVEL);
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
538
539
540
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
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
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