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#include <linux/reboot.h>
19#include <linux/bitops.h>
20
21#include <asm/ptrace.h>
22#include <asm/io.h>
23#include <asm/dma.h>
24#include <asm/mmu_context.h>
25#include <asm/irq.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 if (request_irq(16 + 31, no_action, 0, "isa-cascade", NULL))
136 pr_err("Failed to register isa-cascade interrupt\n");
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
184
185static int
186alcor_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
187{
188 static char irq_tab[7][5] = {
189
190
191 {16+13, 16+13, 16+13, 16+13, 16+13},
192 { 16+8, 16+8, 16+9, 16+10, 16+11},
193 {16+16, 16+16, 16+17, 16+18, 16+19},
194 {16+12, 16+12, 16+13, 16+14, 16+15},
195 { -1, -1, -1, -1, -1},
196 { 16+0, 16+0, 16+1, 16+2, 16+3},
197 { 16+4, 16+4, 16+5, 16+6, 16+7},
198 };
199 const long min_idsel = 6, max_idsel = 12, irqs_per_slot = 5;
200 return COMMON_TABLE_LOOKUP;
201}
202
203static void
204alcor_kill_arch(int mode)
205{
206 cia_kill_arch(mode);
207
208#ifndef ALPHA_RESTORE_SRM_SETUP
209 switch(mode) {
210 case LINUX_REBOOT_CMD_RESTART:
211
212 if (alpha_using_srm) {
213 *(vuip) GRU_RESET = 0x0000dead;
214 mb();
215 }
216 break;
217 case LINUX_REBOOT_CMD_HALT:
218 break;
219 case LINUX_REBOOT_CMD_POWER_OFF:
220 break;
221 }
222
223 halt();
224#endif
225}
226
227static void __init
228alcor_init_pci(void)
229{
230 struct pci_dev *dev;
231
232 cia_init_pci();
233
234
235
236
237
238
239 dev = pci_get_device(PCI_VENDOR_ID_DEC,
240 PCI_DEVICE_ID_DEC_TULIP,
241 NULL);
242 if (dev && dev->devfn == PCI_DEVFN(6,0)) {
243 alpha_mv.sys.cia.gru_int_req_bits = XLT_GRU_INT_REQ_BITS;
244 printk(KERN_INFO "%s: Detected AS500 or XLT motherboard.\n",
245 __func__);
246 }
247 pci_dev_put(dev);
248}
249
250
251
252
253
254
255struct alpha_machine_vector alcor_mv __initmv = {
256 .vector_name = "Alcor",
257 DO_EV5_MMU,
258 DO_DEFAULT_RTC,
259 DO_CIA_IO,
260 .machine_check = cia_machine_check,
261 .max_isa_dma_address = ALPHA_ALCOR_MAX_ISA_DMA_ADDRESS,
262 .min_io_address = EISA_DEFAULT_IO_BASE,
263 .min_mem_address = CIA_DEFAULT_MEM_BASE,
264
265 .nr_irqs = 48,
266 .device_interrupt = alcor_device_interrupt,
267
268 .init_arch = cia_init_arch,
269 .init_irq = alcor_init_irq,
270 .init_rtc = common_init_rtc,
271 .init_pci = alcor_init_pci,
272 .kill_arch = alcor_kill_arch,
273 .pci_map_irq = alcor_map_irq,
274 .pci_swizzle = common_swizzle,
275
276 .sys = { .cia = {
277 .gru_int_req_bits = ALCOR_GRU_INT_REQ_BITS
278 }}
279};
280ALIAS_MV(alcor)
281
282struct alpha_machine_vector xlt_mv __initmv = {
283 .vector_name = "XLT",
284 DO_EV5_MMU,
285 DO_DEFAULT_RTC,
286 DO_CIA_IO,
287 .machine_check = cia_machine_check,
288 .max_isa_dma_address = ALPHA_MAX_ISA_DMA_ADDRESS,
289 .min_io_address = EISA_DEFAULT_IO_BASE,
290 .min_mem_address = CIA_DEFAULT_MEM_BASE,
291
292 .nr_irqs = 48,
293 .device_interrupt = alcor_device_interrupt,
294
295 .init_arch = cia_init_arch,
296 .init_irq = alcor_init_irq,
297 .init_rtc = common_init_rtc,
298 .init_pci = alcor_init_pci,
299 .kill_arch = alcor_kill_arch,
300 .pci_map_irq = alcor_map_irq,
301 .pci_swizzle = common_swizzle,
302
303 .sys = { .cia = {
304 .gru_int_req_bits = XLT_GRU_INT_REQ_BITS
305 }}
306};
307
308
309
310