1
2
3
4
5
6
7
8
9
10
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#include <linux/reboot.h>
18#include <linux/bitops.h>
19
20#include <asm/ptrace.h>
21#include <asm/io.h>
22#include <asm/dma.h>
23#include <asm/mmu_context.h>
24#include <asm/irq.h>
25#include <asm/pgtable.h>
26#include <asm/core_cia.h>
27#include <asm/tlbflush.h>
28
29#include "proto.h"
30#include "irq_impl.h"
31#include "pci_impl.h"
32#include "machvec_impl.h"
33
34
35
36static unsigned long cached_irq_mask;
37
38static inline void
39alcor_update_irq_hw(unsigned long mask)
40{
41 *(vuip)GRU_INT_MASK = mask;
42 mb();
43}
44
45static inline void
46alcor_enable_irq(struct irq_data *d)
47{
48 alcor_update_irq_hw(cached_irq_mask |= 1UL << (d->irq - 16));
49}
50
51static void
52alcor_disable_irq(struct irq_data *d)
53{
54 alcor_update_irq_hw(cached_irq_mask &= ~(1UL << (d->irq - 16)));
55}
56
57static void
58alcor_mask_and_ack_irq(struct irq_data *d)
59{
60 alcor_disable_irq(d);
61
62
63 *(vuip)GRU_INT_CLEAR = 1 << (d->irq - 16); mb();
64 *(vuip)GRU_INT_CLEAR = 0; mb();
65}
66
67static void
68alcor_isa_mask_and_ack_irq(struct irq_data *d)
69{
70 i8259a_mask_and_ack_irq(d);
71
72
73 *(vuip)GRU_INT_CLEAR = 0x80000000; mb();
74 *(vuip)GRU_INT_CLEAR = 0; mb();
75}
76
77static struct irq_chip alcor_irq_type = {
78 .name = "ALCOR",
79 .irq_unmask = alcor_enable_irq,
80 .irq_mask = alcor_disable_irq,
81 .irq_mask_ack = alcor_mask_and_ack_irq,
82};
83
84static void
85alcor_device_interrupt(unsigned long vector)
86{
87 unsigned long pld;
88 unsigned int i;
89
90
91 pld = (*(vuip)GRU_INT_REQ) & GRU_INT_REQ_BITS;
92
93
94
95
96
97 while (pld) {
98 i = ffz(~pld);
99 pld &= pld - 1;
100 if (i == 31) {
101 isa_device_interrupt(vector);
102 } else {
103 handle_irq(16 + i);
104 }
105 }
106}
107
108static void __init
109alcor_init_irq(void)
110{
111 long i;
112
113 if (alpha_using_srm)
114 alpha_mv.device_interrupt = srm_device_interrupt;
115
116 *(vuip)GRU_INT_MASK = 0; mb();
117 *(vuip)GRU_INT_EDGE = 0; mb();
118 *(vuip)GRU_INT_HILO = 0x80000000U; mb();
119 *(vuip)GRU_INT_CLEAR = 0; mb();
120
121 for (i = 16; i < 48; ++i) {
122
123
124
125 if (i >= 16+20 && i <= 16+30)
126 continue;
127 irq_set_chip_and_handler(i, &alcor_irq_type, handle_level_irq);
128 irq_set_status_flags(i, IRQ_LEVEL);
129 }
130 i8259a_irq_type.irq_ack = alcor_isa_mask_and_ack_irq;
131
132 init_i8259a_irqs();
133 common_init_isa_dma();
134
135 setup_irq(16+31, &isa_cascade_irqaction);
136}
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184static int __init
185alcor_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
186{
187 static char irq_tab[7][5] __initdata = {
188
189
190 {16+13, 16+13, 16+13, 16+13, 16+13},
191 { 16+8, 16+8, 16+9, 16+10, 16+11},
192 {16+16, 16+16, 16+17, 16+18, 16+19},
193 {16+12, 16+12, 16+13, 16+14, 16+15},
194 { -1, -1, -1, -1, -1},
195 { 16+0, 16+0, 16+1, 16+2, 16+3},
196 { 16+4, 16+4, 16+5, 16+6, 16+7},
197 };
198 const long min_idsel = 6, max_idsel = 12, irqs_per_slot = 5;
199 return COMMON_TABLE_LOOKUP;
200}
201
202static void
203alcor_kill_arch(int mode)
204{
205 cia_kill_arch(mode);
206
207#ifndef ALPHA_RESTORE_SRM_SETUP
208 switch(mode) {
209 case LINUX_REBOOT_CMD_RESTART:
210
211 if (alpha_using_srm) {
212 *(vuip) GRU_RESET = 0x0000dead;
213 mb();
214 }
215 break;
216 case LINUX_REBOOT_CMD_HALT:
217 break;
218 case LINUX_REBOOT_CMD_POWER_OFF:
219 break;
220 }
221
222 halt();
223#endif
224}
225
226static void __init
227alcor_init_pci(void)
228{
229 struct pci_dev *dev;
230
231 cia_init_pci();
232
233
234
235
236
237
238 dev = pci_get_device(PCI_VENDOR_ID_DEC,
239 PCI_DEVICE_ID_DEC_TULIP,
240 NULL);
241 if (dev && dev->devfn == PCI_DEVFN(6,0)) {
242 alpha_mv.sys.cia.gru_int_req_bits = XLT_GRU_INT_REQ_BITS;
243 printk(KERN_INFO "%s: Detected AS500 or XLT motherboard.\n",
244 __func__);
245 }
246 pci_dev_put(dev);
247}
248
249
250
251
252
253
254struct alpha_machine_vector alcor_mv __initmv = {
255 .vector_name = "Alcor",
256 DO_EV5_MMU,
257 DO_DEFAULT_RTC,
258 DO_CIA_IO,
259 .machine_check = cia_machine_check,
260 .max_isa_dma_address = ALPHA_ALCOR_MAX_ISA_DMA_ADDRESS,
261 .min_io_address = EISA_DEFAULT_IO_BASE,
262 .min_mem_address = CIA_DEFAULT_MEM_BASE,
263
264 .nr_irqs = 48,
265 .device_interrupt = alcor_device_interrupt,
266
267 .init_arch = cia_init_arch,
268 .init_irq = alcor_init_irq,
269 .init_rtc = common_init_rtc,
270 .init_pci = alcor_init_pci,
271 .kill_arch = alcor_kill_arch,
272 .pci_map_irq = alcor_map_irq,
273 .pci_swizzle = common_swizzle,
274
275 .sys = { .cia = {
276 .gru_int_req_bits = ALCOR_GRU_INT_REQ_BITS
277 }}
278};
279ALIAS_MV(alcor)
280
281struct alpha_machine_vector xlt_mv __initmv = {
282 .vector_name = "XLT",
283 DO_EV5_MMU,
284 DO_DEFAULT_RTC,
285 DO_CIA_IO,
286 .machine_check = cia_machine_check,
287 .max_isa_dma_address = ALPHA_MAX_ISA_DMA_ADDRESS,
288 .min_io_address = EISA_DEFAULT_IO_BASE,
289 .min_mem_address = CIA_DEFAULT_MEM_BASE,
290
291 .nr_irqs = 48,
292 .device_interrupt = alcor_device_interrupt,
293
294 .init_arch = cia_init_arch,
295 .init_irq = alcor_init_irq,
296 .init_rtc = common_init_rtc,
297 .init_pci = alcor_init_pci,
298 .kill_arch = alcor_kill_arch,
299 .pci_map_irq = alcor_map_irq,
300 .pci_swizzle = common_swizzle,
301
302 .sys = { .cia = {
303 .gru_int_req_bits = XLT_GRU_INT_REQ_BITS
304 }}
305};
306
307
308
309