* better
[mascara-docs.git] / i386 / linux-2.3.21 / arch / alpha / kernel / sys_sx164.c
bloba8c7698fb602c5e29906432bb1bbfaf8994ce2ff
1 /*
2 * linux/arch/alpha/kernel/sys_sx164.c
4 * Copyright (C) 1995 David A Rusling
5 * Copyright (C) 1996 Jay A Estabrook
6 * Copyright (C) 1998, 1999 Richard Henderson
8 * Code supporting the SX164 (PCA56+PYXIS).
9 */
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>
18 #include <asm/ptrace.h>
19 #include <asm/system.h>
20 #include <asm/dma.h>
21 #include <asm/irq.h>
22 #include <asm/bitops.h>
23 #include <asm/mmu_context.h>
24 #include <asm/io.h>
25 #include <asm/pgtable.h>
26 #include <asm/core_pyxis.h>
28 #include "proto.h"
29 #include "irq_impl.h"
30 #include "pci_impl.h"
31 #include "machvec_impl.h"
34 static void
35 sx164_update_irq_hw(unsigned long irq, unsigned long mask, int unmask_p)
37 if (irq >= 16) {
38 /* Make CERTAIN none of the bogus ints get enabled */
39 *(vulp)PYXIS_INT_MASK =
40 ~((long)mask >> 16) & ~0x000000000000003bUL;
41 mb();
42 /* ... and read it back to make sure it got written. */
43 *(vulp)PYXIS_INT_MASK;
45 else if (irq >= 8)
46 outb(mask >> 8, 0xA1); /* ISA PIC2 */
47 else
48 outb(mask, 0x21); /* ISA PIC1 */
51 static void
52 sx164_srm_update_irq_hw(unsigned long irq, unsigned long mask, int unmask_p)
54 if (irq >= 16) {
55 if (unmask_p)
56 cserve_ena(irq - 16);
57 else
58 cserve_dis(irq - 16);
60 else if (irq >= 8)
61 outb(mask >> 8, 0xA1); /* ISA PIC2 */
62 else
63 outb(mask, 0x21); /* ISA PIC1 */
66 static void
67 sx164_device_interrupt(unsigned long vector, struct pt_regs *regs)
69 unsigned long pld, tmp;
70 unsigned int i;
72 /* Read the interrupt summary register of PYXIS */
73 pld = *(vulp)PYXIS_INT_REQ;
76 * For now, AND off any bits we are not interested in:
77 * HALT (2), timer (6), ISA Bridge (7)
78 * then all the PCI slots/INTXs (8-23)
80 /* Maybe HALT should only be used for SRM console boots? */
81 pld &= 0x0000000000ffffc0UL;
84 * Now for every possible bit set, work through them and call
85 * the appropriate interrupt handler.
87 while (pld) {
88 i = ffz(~pld);
89 pld &= pld - 1; /* clear least bit set */
90 if (i == 7) {
91 isa_device_interrupt(vector, regs);
92 } else if (i == 6) {
93 continue;
94 } else {
95 /* if not timer int */
96 handle_irq(16 + i, 16 + i, regs);
98 *(vulp)PYXIS_INT_REQ = 1UL << i; mb();
99 tmp = *(vulp)PYXIS_INT_REQ;
103 static void
104 sx164_init_irq(void)
106 outb(0, DMA1_RESET_REG);
107 outb(0, DMA2_RESET_REG);
108 outb(DMA_MODE_CASCADE, DMA2_MODE_REG);
109 outb(0, DMA2_MASK_REG);
111 if (alpha_using_srm) {
112 alpha_mv.update_irq_hw = sx164_srm_update_irq_hw;
113 alpha_mv.device_interrupt = srm_device_interrupt;
115 else {
116 /* Note invert on MASK bits. */
117 *(vulp)PYXIS_INT_MASK = ~((long)alpha_irq_mask >> 16);
118 mb();
119 *(vulp)PYXIS_INT_MASK;
122 enable_irq(16 + 6); /* enable timer */
123 enable_irq(16 + 7); /* enable ISA PIC cascade */
124 enable_irq(2); /* enable cascade */
128 * PCI Fixup configuration.
130 * Summary @ PYXIS_INT_REQ:
131 * Bit Meaning
132 * 0 RSVD
133 * 1 NMI
134 * 2 Halt/Reset switch
135 * 3 MBZ
136 * 4 RAZ
137 * 5 RAZ
138 * 6 Interval timer (RTC)
139 * 7 PCI-ISA Bridge
140 * 8 Interrupt Line A from slot 3
141 * 9 Interrupt Line A from slot 2
142 *10 Interrupt Line A from slot 1
143 *11 Interrupt Line A from slot 0
144 *12 Interrupt Line B from slot 3
145 *13 Interrupt Line B from slot 2
146 *14 Interrupt Line B from slot 1
147 *15 Interrupt line B from slot 0
148 *16 Interrupt Line C from slot 3
149 *17 Interrupt Line C from slot 2
150 *18 Interrupt Line C from slot 1
151 *19 Interrupt Line C from slot 0
152 *20 Interrupt Line D from slot 3
153 *21 Interrupt Line D from slot 2
154 *22 Interrupt Line D from slot 1
155 *23 Interrupt Line D from slot 0
157 * IdSel
158 * 5 32 bit PCI option slot 2
159 * 6 64 bit PCI option slot 0
160 * 7 64 bit PCI option slot 1
161 * 8 Cypress I/O
162 * 9 32 bit PCI option slot 3
166 static int __init
167 sx164_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
169 static char irq_tab[5][5] __initlocaldata = {
170 /*INT INTA INTB INTC INTD */
171 { 16+ 9, 16+ 9, 16+13, 16+17, 16+21}, /* IdSel 5 slot 2 J17 */
172 { 16+11, 16+11, 16+15, 16+19, 16+23}, /* IdSel 6 slot 0 J19 */
173 { 16+10, 16+10, 16+14, 16+18, 16+22}, /* IdSel 7 slot 1 J18 */
174 { -1, -1, -1, -1, -1}, /* IdSel 8 SIO */
175 { 16+ 8, 16+ 8, 16+12, 16+16, 16+20} /* IdSel 9 slot 3 J15 */
177 const long min_idsel = 5, max_idsel = 9, irqs_per_slot = 5;
178 return COMMON_TABLE_LOOKUP;
181 void __init
182 sx164_init_pci(void)
184 common_init_pci();
185 SMC669_Init(0);
190 * The System Vector
193 struct alpha_machine_vector sx164_mv __initmv = {
194 vector_name: "SX164",
195 DO_EV5_MMU,
196 DO_DEFAULT_RTC,
197 DO_PYXIS_IO,
198 DO_PYXIS_BUS,
199 machine_check: pyxis_machine_check,
200 max_dma_address: ALPHA_MAX_DMA_ADDRESS,
201 min_io_address: DEFAULT_IO_BASE,
202 min_mem_address: DEFAULT_MEM_BASE,
204 nr_irqs: 40,
205 irq_probe_mask: _PROBE_MASK(40),
206 update_irq_hw: sx164_update_irq_hw,
207 ack_irq: common_ack_irq,
208 device_interrupt: sx164_device_interrupt,
210 init_arch: pyxis_init_arch,
211 init_irq: sx164_init_irq,
212 init_pit: common_init_pit,
213 init_pci: sx164_init_pci,
214 kill_arch: common_kill_arch,
215 pci_map_irq: sx164_map_irq,
216 pci_swizzle: common_swizzle,
218 ALIAS_MV(sx164)