1 |
199 |
simons |
/*
|
2 |
|
|
* linux/arch/alpha/kernel/irq.c
|
3 |
|
|
*
|
4 |
|
|
* Copyright (C) 1995 Linus Torvalds
|
5 |
|
|
*
|
6 |
|
|
* This file contains the code used by various IRQ handling routines:
|
7 |
|
|
* asking for different IRQ's should be done through these routines
|
8 |
|
|
* instead of just grabbing them. Thus setups with different IRQ numbers
|
9 |
|
|
* shouldn't result in any weird surprises, and installing new handlers
|
10 |
|
|
* should be easier.
|
11 |
|
|
*/
|
12 |
|
|
|
13 |
|
|
#include <linux/config.h>
|
14 |
|
|
#include <linux/ptrace.h>
|
15 |
|
|
#include <linux/errno.h>
|
16 |
|
|
#include <linux/kernel_stat.h>
|
17 |
|
|
#include <linux/signal.h>
|
18 |
|
|
#include <linux/sched.h>
|
19 |
|
|
#include <linux/interrupt.h>
|
20 |
|
|
#include <linux/malloc.h>
|
21 |
|
|
#include <linux/random.h>
|
22 |
|
|
|
23 |
|
|
#include <asm/system.h>
|
24 |
|
|
#include <asm/io.h>
|
25 |
|
|
#include <asm/irq.h>
|
26 |
|
|
#include <asm/bitops.h>
|
27 |
|
|
#include <asm/dma.h>
|
28 |
|
|
|
29 |
|
|
extern void timer_interrupt(struct pt_regs * regs);
|
30 |
|
|
extern void cserve_update_hw(unsigned long, unsigned long);
|
31 |
|
|
|
32 |
|
|
#if NR_IRQS > 64
|
33 |
|
|
# error Unable to handle more than 64 irq levels.
|
34 |
|
|
#endif
|
35 |
|
|
|
36 |
|
|
/* Reserved interrupts. These must NEVER be requested by any driver!
|
37 |
|
|
*/
|
38 |
|
|
#define IS_RESERVED_IRQ(irq) ((irq)==2) /* IRQ 2 used by hw cascade */
|
39 |
|
|
|
40 |
|
|
/*
|
41 |
|
|
* Shadow-copy of masked interrupts.
|
42 |
|
|
* The bits are used as follows:
|
43 |
|
|
* 0.. 7 first (E)ISA PIC (irq level 0..7)
|
44 |
|
|
* 8..15 second (E)ISA PIC (irq level 8..15)
|
45 |
|
|
* Systems with PCI interrupt lines managed by GRU (e.g., Alcor, XLT):
|
46 |
|
|
* or PYXIS (e.g. Miata, PC164-LX)
|
47 |
|
|
* 16..47 PCI interrupts 0..31 (xxx_INT_MASK reg)
|
48 |
|
|
* Mikasa:
|
49 |
|
|
* 16..31 PCI interrupts 0..15 (short at I/O port 536)
|
50 |
|
|
* Other systems (not Mikasa) with 16 PCI interrupt lines:
|
51 |
|
|
* 16..23 PCI interrupts 0.. 7 (char at I/O port 26)
|
52 |
|
|
* 24..31 PCI interrupts 8..15 (char at I/O port 27)
|
53 |
|
|
* Systems with 17 PCI interrupt lines (e.g., Cabriolet and eb164):
|
54 |
|
|
* 16..32 PCI interrupts 0..31 (int at I/O port 804)
|
55 |
|
|
* Takara:
|
56 |
|
|
* 16..19 PCI interrupts A thru D
|
57 |
|
|
* For SABLE, which is really baroque, we manage 40 IRQ's, but the
|
58 |
|
|
* hardware really only supports 24, not via normal ISA PIC,
|
59 |
|
|
* but cascaded custom 8259's, etc.
|
60 |
|
|
* 0-7 (char at 536)
|
61 |
|
|
* 8-15 (char at 53a)
|
62 |
|
|
* 16-23 (char at 53c)
|
63 |
|
|
*/
|
64 |
|
|
static unsigned long irq_mask = ~0UL;
|
65 |
|
|
|
66 |
|
|
#ifdef CONFIG_ALPHA_SABLE
|
67 |
|
|
/* note that the vector reported by the SRM PALcode corresponds to the
|
68 |
|
|
interrupt mask bits, but we have to manage via more normal IRQs */
|
69 |
|
|
static char sable_irq_to_mask[NR_IRQS] = {
|
70 |
|
|
-1, 6, -1, 8, 15, 12, 7, 9, /* pseudo PIC 0-7 */
|
71 |
|
|
-1, 16, 17, 18, 3, -1, 21, 22, /* pseudo PIC 8-15 */
|
72 |
|
|
-1, -1, -1, -1, -1, -1, -1, -1, /* pseudo EISA 0-7 */
|
73 |
|
|
-1, -1, -1, -1, -1, -1, -1, -1, /* pseudo EISA 8-15 */
|
74 |
|
|
2, 1, 0, 4, 5, -1, -1, -1, /* pseudo PCI */
|
75 |
|
|
};
|
76 |
|
|
#define IRQ_TO_MASK(irq) (sable_irq_to_mask[(irq)])
|
77 |
|
|
static char sable_mask_to_irq[NR_IRQS] = {
|
78 |
|
|
34, 33, 32, 12, 35, 36, 1, 6, /* mask 0-7 */
|
79 |
|
|
3, 7, -1, -1, 5, -1, -1, 4, /* mask 8-15 */
|
80 |
|
|
9, 10, 11, -1, -1, 14, 15, -1, /* mask 16-23 */
|
81 |
|
|
};
|
82 |
|
|
#else /* CONFIG_ALPHA_SABLE */
|
83 |
|
|
#define IRQ_TO_MASK(irq) (irq)
|
84 |
|
|
#endif /* CONFIG_ALPHA_SABLE */
|
85 |
|
|
|
86 |
|
|
/*
|
87 |
|
|
* Update the hardware with the irq mask passed in MASK. The function
|
88 |
|
|
* exploits the fact that it is known that only bit IRQ has changed.
|
89 |
|
|
*
|
90 |
|
|
* There deliberately isn't a case in here for the Takara since it
|
91 |
|
|
* wouldn't work anyway because the interrupt controller is bizarre.
|
92 |
|
|
*/
|
93 |
|
|
static void update_hw(unsigned long irq, unsigned long mask)
|
94 |
|
|
{
|
95 |
|
|
#ifdef CONFIG_ALPHA_ALCOR
|
96 |
|
|
/* always mask out 20..30 (which are unused) */
|
97 |
|
|
mask |= 0x7ff00000UL << 16;
|
98 |
|
|
#endif
|
99 |
|
|
switch (irq) {
|
100 |
|
|
|
101 |
|
|
#ifdef CONFIG_ALPHA_SABLE
|
102 |
|
|
/* SABLE does everything different, so we manage it that way... :-( */
|
103 |
|
|
/* the "irq" argument is really the mask bit number */
|
104 |
|
|
case 0 ... 7:
|
105 |
|
|
outb(mask, 0x537);
|
106 |
|
|
break;
|
107 |
|
|
case 8 ... 15:
|
108 |
|
|
outb(mask >> 8, 0x53b);
|
109 |
|
|
break;
|
110 |
|
|
case 16 ... 23:
|
111 |
|
|
outb(mask >> 16, 0x53d);
|
112 |
|
|
break;
|
113 |
|
|
#else /* SABLE */
|
114 |
|
|
|
115 |
|
|
#if defined(CONFIG_ALPHA_NORITAKE)
|
116 |
|
|
/* note inverted sense of mask bits: */
|
117 |
|
|
case 16 ... 31:
|
118 |
|
|
outw(~(mask >> 16), 0x54a);
|
119 |
|
|
break;
|
120 |
|
|
case 32 ... 47:
|
121 |
|
|
outw(~(mask >> 32), 0x54c);
|
122 |
|
|
break;
|
123 |
|
|
#endif /* NORITAKE */
|
124 |
|
|
|
125 |
|
|
#if defined(CONFIG_ALPHA_MIATA)
|
126 |
|
|
case 16 ... 47:
|
127 |
|
|
{ unsigned long temp;
|
128 |
|
|
/* note inverted sense of mask bits: */
|
129 |
|
|
/* make CERTAIN none of the bogus ints get enabled */
|
130 |
|
|
*(unsigned long *)PYXIS_INT_MASK =
|
131 |
|
|
~((long)mask >> 16) & ~0x400000000000063bUL; mb();
|
132 |
|
|
temp = *(unsigned long *)PYXIS_INT_MASK;
|
133 |
|
|
break;
|
134 |
|
|
}
|
135 |
|
|
#endif /* MIATA */
|
136 |
|
|
|
137 |
|
|
#if defined(CONFIG_ALPHA_RUFFIAN)
|
138 |
|
|
case 16 ... 47:
|
139 |
|
|
{ unsigned long temp;
|
140 |
|
|
/* note inverted sense of mask bits: */
|
141 |
|
|
/* make CERTAIN none of the bogus ints get enabled */
|
142 |
|
|
*(unsigned long *)PYXIS_INT_MASK =
|
143 |
|
|
~((long)mask >> 16) & 0x00000000ffffffbfUL; mb();
|
144 |
|
|
temp = *(unsigned long *)PYXIS_INT_MASK;
|
145 |
|
|
break;
|
146 |
|
|
}
|
147 |
|
|
#endif /* RUFFIAN */
|
148 |
|
|
|
149 |
|
|
#if defined(CONFIG_ALPHA_SX164)
|
150 |
|
|
case 16 ... 39:
|
151 |
|
|
#if defined(CONFIG_ALPHA_SRM)
|
152 |
|
|
cserve_update_hw(irq, mask);
|
153 |
|
|
break;
|
154 |
|
|
#else
|
155 |
|
|
{ unsigned long temp;
|
156 |
|
|
/* make CERTAIN none of the bogus ints get enabled */
|
157 |
|
|
*(unsigned long *)PYXIS_INT_MASK =
|
158 |
|
|
~((long)mask >> 16) & ~0x000000000000003bUL; mb();
|
159 |
|
|
temp = *(unsigned long *)PYXIS_INT_MASK;
|
160 |
|
|
break;
|
161 |
|
|
}
|
162 |
|
|
#endif /* SRM */
|
163 |
|
|
#endif /* SX164 */
|
164 |
|
|
|
165 |
|
|
#if defined(CONFIG_ALPHA_ALCOR) || defined(CONFIG_ALPHA_XLT)
|
166 |
|
|
case 16 ... 47:
|
167 |
|
|
/* note inverted sense of mask bits: */
|
168 |
|
|
*(unsigned int *)GRU_INT_MASK = ~(mask >> 16); mb();
|
169 |
|
|
break;
|
170 |
|
|
#endif /* ALCOR || XLT */
|
171 |
|
|
|
172 |
|
|
#if defined(CONFIG_ALPHA_CABRIOLET) || \
|
173 |
|
|
defined(CONFIG_ALPHA_EB66P) || \
|
174 |
|
|
defined(CONFIG_ALPHA_EB164) || \
|
175 |
|
|
defined(CONFIG_ALPHA_PC164) || \
|
176 |
|
|
defined(CONFIG_ALPHA_LX164)
|
177 |
|
|
#if defined(CONFIG_ALPHA_SRM)
|
178 |
|
|
case 16 ... 34:
|
179 |
|
|
cserve_update_hw(irq, mask);
|
180 |
|
|
break;
|
181 |
|
|
#else /* SRM */
|
182 |
|
|
case 16 ... 34:
|
183 |
|
|
outl(irq_mask >> 16, 0x804);
|
184 |
|
|
break;
|
185 |
|
|
#endif /* SRM */
|
186 |
|
|
#endif /* CABRIO || EB66P || EB164 || PC164 || LX164 */
|
187 |
|
|
|
188 |
|
|
#if defined(CONFIG_ALPHA_MIKASA)
|
189 |
|
|
case 16 ... 31:
|
190 |
|
|
outw(~(mask >> 16), 0x536); /* note invert */
|
191 |
|
|
break;
|
192 |
|
|
#endif /* MIKASA */
|
193 |
|
|
|
194 |
|
|
#if defined(CONFIG_ALPHA_EB66) || defined(CONFIG_ALPHA_EB64P)
|
195 |
|
|
case 16 ... 23:
|
196 |
|
|
outb(mask >> 16, 0x26);
|
197 |
|
|
break;
|
198 |
|
|
case 24 ... 31:
|
199 |
|
|
outb(mask >> 24, 0x27);
|
200 |
|
|
break;
|
201 |
|
|
#endif /* EB66 || EB64P */
|
202 |
|
|
|
203 |
|
|
/* handle ISA irqs last---fast devices belong on PCI... */
|
204 |
|
|
/* this is common for all except SABLE! */
|
205 |
|
|
|
206 |
|
|
case 0 ... 7: /* ISA PIC1 */
|
207 |
|
|
outb(mask, 0x21);
|
208 |
|
|
break;
|
209 |
|
|
|
210 |
|
|
case 8 ...15: /* ISA PIC2 */
|
211 |
|
|
outb(mask >> 8, 0xA1);
|
212 |
|
|
break;
|
213 |
|
|
|
214 |
|
|
#endif /* SABLE */
|
215 |
|
|
|
216 |
|
|
} /* end switch (irq) */
|
217 |
|
|
}
|
218 |
|
|
|
219 |
|
|
static inline void mask_irq(unsigned long irq)
|
220 |
|
|
{
|
221 |
|
|
irq_mask |= (1UL << irq);
|
222 |
|
|
update_hw(irq, irq_mask);
|
223 |
|
|
}
|
224 |
|
|
|
225 |
|
|
static inline void unmask_irq(unsigned long irq)
|
226 |
|
|
{
|
227 |
|
|
irq_mask &= ~(1UL << irq);
|
228 |
|
|
update_hw(irq, irq_mask);
|
229 |
|
|
}
|
230 |
|
|
|
231 |
|
|
void disable_irq(unsigned int irq_nr)
|
232 |
|
|
{
|
233 |
|
|
unsigned long flags;
|
234 |
|
|
|
235 |
|
|
save_flags(flags);
|
236 |
|
|
cli();
|
237 |
|
|
mask_irq(IRQ_TO_MASK(irq_nr));
|
238 |
|
|
restore_flags(flags);
|
239 |
|
|
}
|
240 |
|
|
|
241 |
|
|
void enable_irq(unsigned int irq_nr)
|
242 |
|
|
{
|
243 |
|
|
unsigned long flags;
|
244 |
|
|
|
245 |
|
|
save_flags(flags);
|
246 |
|
|
cli();
|
247 |
|
|
unmask_irq(IRQ_TO_MASK(irq_nr));
|
248 |
|
|
restore_flags(flags);
|
249 |
|
|
}
|
250 |
|
|
|
251 |
|
|
/*
|
252 |
|
|
* Initial irq handlers.
|
253 |
|
|
*/
|
254 |
|
|
static struct irqaction *irq_action[NR_IRQS];
|
255 |
|
|
|
256 |
|
|
int get_irq_list(char *buf)
|
257 |
|
|
{
|
258 |
|
|
int i, len = 0;
|
259 |
|
|
struct irqaction * action;
|
260 |
|
|
|
261 |
|
|
for (i = 0 ; i < NR_IRQS ; i++) {
|
262 |
|
|
action = irq_action[i];
|
263 |
|
|
if (!action)
|
264 |
|
|
continue;
|
265 |
|
|
len += sprintf(buf+len, "%2d: %8d %c %s",
|
266 |
|
|
i, kstat.interrupts[i],
|
267 |
|
|
(action->flags & SA_INTERRUPT) ? '+' : ' ',
|
268 |
|
|
action->name);
|
269 |
|
|
for (action=action->next; action; action = action->next) {
|
270 |
|
|
len += sprintf(buf+len, ",%s %s",
|
271 |
|
|
(action->flags & SA_INTERRUPT) ? " +" : "",
|
272 |
|
|
action->name);
|
273 |
|
|
}
|
274 |
|
|
len += sprintf(buf+len, "\n");
|
275 |
|
|
}
|
276 |
|
|
return len;
|
277 |
|
|
}
|
278 |
|
|
|
279 |
|
|
static inline void ack_irq(int irq)
|
280 |
|
|
{
|
281 |
|
|
#ifdef CONFIG_ALPHA_SABLE
|
282 |
|
|
/* note that the "irq" here is really the mask bit number */
|
283 |
|
|
switch (irq) {
|
284 |
|
|
case 0 ... 7:
|
285 |
|
|
outb(0xE0 | (irq - 0), 0x536);
|
286 |
|
|
outb(0xE0 | 1, 0x534); /* slave 0 */
|
287 |
|
|
break;
|
288 |
|
|
case 8 ... 15:
|
289 |
|
|
outb(0xE0 | (irq - 8), 0x53a);
|
290 |
|
|
outb(0xE0 | 3, 0x534); /* slave 1 */
|
291 |
|
|
break;
|
292 |
|
|
case 16 ... 24:
|
293 |
|
|
outb(0xE0 | (irq - 16), 0x53c);
|
294 |
|
|
outb(0xE0 | 4, 0x534); /* slave 2 */
|
295 |
|
|
break;
|
296 |
|
|
}
|
297 |
|
|
#else /* CONFIG_ALPHA_SABLE */
|
298 |
|
|
if (irq < 16) {
|
299 |
|
|
#if defined(CONFIG_ALPHA_RUFFIAN)
|
300 |
|
|
/* ack pyxis ISA interrupt */
|
301 |
|
|
*(unsigned long *)PYXIS_INT_REQ = (0x01UL << 7);
|
302 |
|
|
if (irq > 7) {
|
303 |
|
|
outb(0x20,0xa0);
|
304 |
|
|
}
|
305 |
|
|
outb(0x20,0x20);
|
306 |
|
|
#else /* RUFFIAN */
|
307 |
|
|
/* ACK the interrupt making it the lowest priority */
|
308 |
|
|
/* First the slave .. */
|
309 |
|
|
if (irq > 7) {
|
310 |
|
|
outb(0xE0 | (irq - 8), 0xa0);
|
311 |
|
|
irq = 2;
|
312 |
|
|
}
|
313 |
|
|
/* .. then the master */
|
314 |
|
|
outb(0xE0 | irq, 0x20);
|
315 |
|
|
#if defined(CONFIG_ALPHA_ALCOR) || defined(CONFIG_ALPHA_XLT)
|
316 |
|
|
/* on ALCOR/XLT, need to dismiss interrupt via GRU */
|
317 |
|
|
*(int *)GRU_INT_CLEAR = 0x80000000; mb();
|
318 |
|
|
*(int *)GRU_INT_CLEAR = 0x00000000; mb();
|
319 |
|
|
#endif /* ALCOR || XLT */
|
320 |
|
|
#endif /* RUFFIAN */
|
321 |
|
|
}
|
322 |
|
|
#if defined(CONFIG_ALPHA_RUFFIAN)
|
323 |
|
|
else {
|
324 |
|
|
/* ack pyxis int */
|
325 |
|
|
*(unsigned long *)PYXIS_INT_REQ = (1UL << (irq-16));
|
326 |
|
|
}
|
327 |
|
|
#endif /* RUFFIAN */
|
328 |
|
|
|
329 |
|
|
#endif /* CONFIG_ALPHA_SABLE */
|
330 |
|
|
}
|
331 |
|
|
|
332 |
|
|
int request_irq(unsigned int irq,
|
333 |
|
|
void (*handler)(int, void *, struct pt_regs *),
|
334 |
|
|
unsigned long irqflags,
|
335 |
|
|
const char * devname,
|
336 |
|
|
void *dev_id)
|
337 |
|
|
{
|
338 |
|
|
int shared = 0;
|
339 |
|
|
struct irqaction * action, **p;
|
340 |
|
|
unsigned long flags;
|
341 |
|
|
|
342 |
|
|
if (irq >= NR_IRQS)
|
343 |
|
|
return -EINVAL;
|
344 |
|
|
if (IS_RESERVED_IRQ(irq))
|
345 |
|
|
return -EINVAL;
|
346 |
|
|
if (!handler)
|
347 |
|
|
return -EINVAL;
|
348 |
|
|
p = irq_action + irq;
|
349 |
|
|
action = *p;
|
350 |
|
|
if (action) {
|
351 |
|
|
/* Can't share interrupts unless both agree to */
|
352 |
|
|
if (!(action->flags & irqflags & SA_SHIRQ))
|
353 |
|
|
return -EBUSY;
|
354 |
|
|
|
355 |
|
|
/* Can't share interrupts unless both are same type */
|
356 |
|
|
if ((action->flags ^ irqflags) & SA_INTERRUPT)
|
357 |
|
|
return -EBUSY;
|
358 |
|
|
|
359 |
|
|
/* add new interrupt at end of irq queue */
|
360 |
|
|
do {
|
361 |
|
|
p = &action->next;
|
362 |
|
|
action = *p;
|
363 |
|
|
} while (action);
|
364 |
|
|
shared = 1;
|
365 |
|
|
}
|
366 |
|
|
|
367 |
|
|
action = (struct irqaction *)kmalloc(sizeof(struct irqaction),
|
368 |
|
|
GFP_KERNEL);
|
369 |
|
|
if (!action)
|
370 |
|
|
return -ENOMEM;
|
371 |
|
|
|
372 |
|
|
if (irqflags & SA_SAMPLE_RANDOM)
|
373 |
|
|
rand_initialize_irq(irq);
|
374 |
|
|
|
375 |
|
|
action->handler = handler;
|
376 |
|
|
action->flags = irqflags;
|
377 |
|
|
action->mask = 0;
|
378 |
|
|
action->name = devname;
|
379 |
|
|
action->next = NULL;
|
380 |
|
|
action->dev_id = dev_id;
|
381 |
|
|
|
382 |
|
|
save_flags(flags);
|
383 |
|
|
cli();
|
384 |
|
|
*p = action;
|
385 |
|
|
|
386 |
|
|
if (!shared)
|
387 |
|
|
unmask_irq(IRQ_TO_MASK(irq));
|
388 |
|
|
|
389 |
|
|
restore_flags(flags);
|
390 |
|
|
return 0;
|
391 |
|
|
}
|
392 |
|
|
|
393 |
|
|
void free_irq(unsigned int irq, void *dev_id)
|
394 |
|
|
{
|
395 |
|
|
struct irqaction * action, **p;
|
396 |
|
|
unsigned long flags;
|
397 |
|
|
|
398 |
|
|
if (irq >= NR_IRQS) {
|
399 |
|
|
printk("Trying to free IRQ%d\n",irq);
|
400 |
|
|
return;
|
401 |
|
|
}
|
402 |
|
|
if (IS_RESERVED_IRQ(irq)) {
|
403 |
|
|
printk("Trying to free reserved IRQ %d\n", irq);
|
404 |
|
|
return;
|
405 |
|
|
}
|
406 |
|
|
for (p = irq + irq_action; (action = *p) != NULL; p = &action->next) {
|
407 |
|
|
if (action->dev_id != dev_id)
|
408 |
|
|
continue;
|
409 |
|
|
|
410 |
|
|
/* Found it - now free it */
|
411 |
|
|
save_flags(flags);
|
412 |
|
|
cli();
|
413 |
|
|
*p = action->next;
|
414 |
|
|
if (!irq[irq_action])
|
415 |
|
|
mask_irq(IRQ_TO_MASK(irq));
|
416 |
|
|
restore_flags(flags);
|
417 |
|
|
kfree(action);
|
418 |
|
|
return;
|
419 |
|
|
}
|
420 |
|
|
printk("Trying to free free IRQ%d\n",irq);
|
421 |
|
|
}
|
422 |
|
|
|
423 |
|
|
static inline void handle_nmi(struct pt_regs * regs)
|
424 |
|
|
{
|
425 |
|
|
printk("Whee.. NMI received. Probable hardware error\n");
|
426 |
|
|
printk("61=%02x, 461=%02x\n", inb(0x61), inb(0x461));
|
427 |
|
|
}
|
428 |
|
|
|
429 |
|
|
static void unexpected_irq(int irq, struct pt_regs * regs)
|
430 |
|
|
{
|
431 |
|
|
struct irqaction *action;
|
432 |
|
|
int i;
|
433 |
|
|
|
434 |
|
|
printk("IO device interrupt, irq = %d\n", irq);
|
435 |
|
|
printk("PC = %016lx PS=%04lx\n", regs->pc, regs->ps);
|
436 |
|
|
printk("Expecting: ");
|
437 |
|
|
for (i = 0; i < 16; i++)
|
438 |
|
|
if ((action = irq_action[i]))
|
439 |
|
|
while (action->handler) {
|
440 |
|
|
printk("[%s:%d] ", action->name, i);
|
441 |
|
|
action = action->next;
|
442 |
|
|
}
|
443 |
|
|
printk("\n");
|
444 |
|
|
#if defined(CONFIG_ALPHA_JENSEN)
|
445 |
|
|
printk("64=%02x, 60=%02x, 3fa=%02x 2fa=%02x\n",
|
446 |
|
|
inb(0x64), inb(0x60), inb(0x3fa), inb(0x2fa));
|
447 |
|
|
outb(0x0c, 0x3fc);
|
448 |
|
|
outb(0x0c, 0x2fc);
|
449 |
|
|
outb(0,0x61);
|
450 |
|
|
outb(0,0x461);
|
451 |
|
|
#endif
|
452 |
|
|
}
|
453 |
|
|
|
454 |
|
|
static inline void handle_irq(int irq, struct pt_regs * regs)
|
455 |
|
|
{
|
456 |
|
|
struct irqaction * action = irq_action[irq];
|
457 |
|
|
|
458 |
|
|
kstat.interrupts[irq]++;
|
459 |
|
|
if (!action) {
|
460 |
|
|
unexpected_irq(irq, regs);
|
461 |
|
|
return;
|
462 |
|
|
}
|
463 |
|
|
do {
|
464 |
|
|
action->handler(irq, action->dev_id, regs);
|
465 |
|
|
action = action->next;
|
466 |
|
|
} while (action);
|
467 |
|
|
}
|
468 |
|
|
|
469 |
|
|
static inline void device_interrupt(int irq, int ack, struct pt_regs * regs)
|
470 |
|
|
{
|
471 |
|
|
struct irqaction * action;
|
472 |
|
|
|
473 |
|
|
if ((unsigned) irq > NR_IRQS) {
|
474 |
|
|
printk("device_interrupt: illegal interrupt %d\n", irq);
|
475 |
|
|
return;
|
476 |
|
|
}
|
477 |
|
|
|
478 |
|
|
#if defined(CONFIG_ALPHA_RUFFIAN)
|
479 |
|
|
/* RUFFIAN uses ISA IRQ #0 to deliver clock ticks */
|
480 |
|
|
if (irq == 0) {
|
481 |
|
|
timer_interrupt(regs);
|
482 |
|
|
ack_irq(0);
|
483 |
|
|
return;
|
484 |
|
|
}
|
485 |
|
|
#endif /* RUFFIAN */
|
486 |
|
|
|
487 |
|
|
kstat.interrupts[irq]++;
|
488 |
|
|
action = irq_action[irq];
|
489 |
|
|
|
490 |
|
|
/*
|
491 |
|
|
* For normal interrupts, we mask it out, and then ACK it.
|
492 |
|
|
* This way another (more timing-critical) interrupt can
|
493 |
|
|
* come through while we're doing this one.
|
494 |
|
|
*
|
495 |
|
|
* Note! An irq without a handler gets masked and acked, but
|
496 |
|
|
* never unmasked. The autoirq stuff depends on this (it looks
|
497 |
|
|
* at the masks before and after doing the probing).
|
498 |
|
|
*/
|
499 |
|
|
mask_irq(ack);
|
500 |
|
|
ack_irq(ack);
|
501 |
|
|
if (!action) {
|
502 |
|
|
#if 1
|
503 |
|
|
printk("device_interrupt: unexpected interrupt %d\n", irq);
|
504 |
|
|
#endif
|
505 |
|
|
return;
|
506 |
|
|
}
|
507 |
|
|
if (action->flags & SA_SAMPLE_RANDOM)
|
508 |
|
|
add_interrupt_randomness(irq);
|
509 |
|
|
do {
|
510 |
|
|
action->handler(irq, action->dev_id, regs);
|
511 |
|
|
action = action->next;
|
512 |
|
|
} while (action);
|
513 |
|
|
unmask_irq(ack);
|
514 |
|
|
}
|
515 |
|
|
|
516 |
|
|
#ifdef CONFIG_PCI
|
517 |
|
|
|
518 |
|
|
/*
|
519 |
|
|
* Handle ISA interrupt via the PICs.
|
520 |
|
|
*/
|
521 |
|
|
static inline void isa_device_interrupt(unsigned long vector,
|
522 |
|
|
struct pt_regs * regs)
|
523 |
|
|
{
|
524 |
|
|
#if defined(CONFIG_ALPHA_APECS)
|
525 |
|
|
# define IACK_SC APECS_IACK_SC
|
526 |
|
|
#elif defined(CONFIG_ALPHA_LCA)
|
527 |
|
|
# define IACK_SC LCA_IACK_SC
|
528 |
|
|
#elif defined(CONFIG_ALPHA_CIA)
|
529 |
|
|
# define IACK_SC CIA_IACK_SC
|
530 |
|
|
#elif defined(CONFIG_ALPHA_PYXIS)
|
531 |
|
|
# define IACK_SC PYXIS_IACK_SC
|
532 |
|
|
#else
|
533 |
|
|
/*
|
534 |
|
|
* This is bogus but necessary to get it to compile
|
535 |
|
|
* on all platforms. If you try to use this on any
|
536 |
|
|
* other than the intended platforms, you'll notice
|
537 |
|
|
* real fast...
|
538 |
|
|
*/
|
539 |
|
|
# define IACK_SC 1L
|
540 |
|
|
#endif
|
541 |
|
|
int j;
|
542 |
|
|
|
543 |
|
|
#if 1
|
544 |
|
|
/*
|
545 |
|
|
* Generate a PCI interrupt acknowledge cycle. The PIC will
|
546 |
|
|
* respond with the interrupt vector of the highest priority
|
547 |
|
|
* interrupt that is pending. The PALcode sets up the
|
548 |
|
|
* interrupts vectors such that irq level L generates vector
|
549 |
|
|
* L.
|
550 |
|
|
*/
|
551 |
|
|
j = *(volatile int *) IACK_SC;
|
552 |
|
|
j &= 0xff;
|
553 |
|
|
if (j == 7) {
|
554 |
|
|
if (!(inb(0x20) & 0x80)) {
|
555 |
|
|
/* it's only a passive release... */
|
556 |
|
|
return;
|
557 |
|
|
}
|
558 |
|
|
}
|
559 |
|
|
device_interrupt(j, j, regs);
|
560 |
|
|
#else
|
561 |
|
|
unsigned long pic;
|
562 |
|
|
|
563 |
|
|
/*
|
564 |
|
|
* It seems to me that the probability of two or more *device*
|
565 |
|
|
* interrupts occurring at almost exactly the same time is
|
566 |
|
|
* pretty low. So why pay the price of checking for
|
567 |
|
|
* additional interrupts here if the common case can be
|
568 |
|
|
* handled so much easier?
|
569 |
|
|
*/
|
570 |
|
|
/*
|
571 |
|
|
* The first read of gives you *all* interrupting lines.
|
572 |
|
|
* Therefore, read the mask register and and out those lines
|
573 |
|
|
* not enabled. Note that some documentation has 21 and a1
|
574 |
|
|
* write only. This is not true.
|
575 |
|
|
*/
|
576 |
|
|
pic = inb(0x20) | (inb(0xA0) << 8); /* read isr */
|
577 |
|
|
pic &= ~irq_mask; /* apply mask */
|
578 |
|
|
pic &= 0xFFFB; /* mask out cascade & hibits */
|
579 |
|
|
|
580 |
|
|
while (pic) {
|
581 |
|
|
j = ffz(~pic);
|
582 |
|
|
pic &= pic - 1;
|
583 |
|
|
device_interrupt(j, j, regs);
|
584 |
|
|
}
|
585 |
|
|
#endif
|
586 |
|
|
}
|
587 |
|
|
|
588 |
|
|
#if defined(CONFIG_ALPHA_ALCOR) || defined(CONFIG_ALPHA_XLT)
|
589 |
|
|
/* we have to conditionally compile this because of GRU_xxx symbols */
|
590 |
|
|
static inline void alcor_and_xlt_device_interrupt(unsigned long vector,
|
591 |
|
|
struct pt_regs * regs)
|
592 |
|
|
{
|
593 |
|
|
unsigned long pld;
|
594 |
|
|
unsigned int i;
|
595 |
|
|
unsigned long flags;
|
596 |
|
|
|
597 |
|
|
save_flags(flags);
|
598 |
|
|
cli();
|
599 |
|
|
|
600 |
|
|
/* read the interrupt summary register of the GRU */
|
601 |
|
|
pld = (*(unsigned int *)GRU_INT_REQ) & GRU_INT_REQ_BITS;
|
602 |
|
|
|
603 |
|
|
#if 0
|
604 |
|
|
printk("[0x%08lx/0x%04x]", pld, inb(0x20) | (inb(0xA0) << 8));
|
605 |
|
|
#endif
|
606 |
|
|
|
607 |
|
|
/*
|
608 |
|
|
* Now for every possible bit set, work through them and call
|
609 |
|
|
* the appropriate interrupt handler.
|
610 |
|
|
*/
|
611 |
|
|
while (pld) {
|
612 |
|
|
i = ffz(~pld);
|
613 |
|
|
pld &= pld - 1; /* clear least bit set */
|
614 |
|
|
if (i == 31) {
|
615 |
|
|
isa_device_interrupt(vector, regs);
|
616 |
|
|
} else {
|
617 |
|
|
device_interrupt(16 + i, 16 + i, regs);
|
618 |
|
|
}
|
619 |
|
|
}
|
620 |
|
|
restore_flags(flags);
|
621 |
|
|
}
|
622 |
|
|
#endif /* ALCOR || XLT */
|
623 |
|
|
|
624 |
|
|
static inline void cabriolet_and_eb66p_device_interrupt(unsigned long vector,
|
625 |
|
|
struct pt_regs * regs)
|
626 |
|
|
{
|
627 |
|
|
unsigned long pld;
|
628 |
|
|
unsigned int i;
|
629 |
|
|
unsigned long flags;
|
630 |
|
|
|
631 |
|
|
save_flags(flags);
|
632 |
|
|
cli();
|
633 |
|
|
|
634 |
|
|
/* read the interrupt summary registers */
|
635 |
|
|
pld = inb(0x804) | (inb(0x805) << 8) | (inb(0x806) << 16);
|
636 |
|
|
|
637 |
|
|
#if 0
|
638 |
|
|
printk("[0x%04X/0x%04X]", pld, inb(0x20) | (inb(0xA0) << 8));
|
639 |
|
|
#endif
|
640 |
|
|
|
641 |
|
|
/*
|
642 |
|
|
* Now for every possible bit set, work through them and call
|
643 |
|
|
* the appropriate interrupt handler.
|
644 |
|
|
*/
|
645 |
|
|
while (pld) {
|
646 |
|
|
i = ffz(~pld);
|
647 |
|
|
pld &= pld - 1; /* clear least bit set */
|
648 |
|
|
if (i == 4) {
|
649 |
|
|
isa_device_interrupt(vector, regs);
|
650 |
|
|
} else {
|
651 |
|
|
device_interrupt(16 + i, 16 + i, regs);
|
652 |
|
|
}
|
653 |
|
|
}
|
654 |
|
|
restore_flags(flags);
|
655 |
|
|
}
|
656 |
|
|
|
657 |
|
|
static inline void mikasa_device_interrupt(unsigned long vector,
|
658 |
|
|
struct pt_regs * regs)
|
659 |
|
|
{
|
660 |
|
|
unsigned long pld;
|
661 |
|
|
unsigned int i;
|
662 |
|
|
unsigned long flags;
|
663 |
|
|
|
664 |
|
|
save_flags(flags);
|
665 |
|
|
cli();
|
666 |
|
|
|
667 |
|
|
/* read the interrupt summary registers */
|
668 |
|
|
pld = (((unsigned long) (~inw(0x534)) & 0x0000ffffUL) << 16) |
|
669 |
|
|
(((unsigned long) inb(0xa0)) << 8) |
|
670 |
|
|
((unsigned long) inb(0x20));
|
671 |
|
|
|
672 |
|
|
#if 0
|
673 |
|
|
printk("[0x%08lx]", pld);
|
674 |
|
|
#endif
|
675 |
|
|
|
676 |
|
|
/*
|
677 |
|
|
* Now for every possible bit set, work through them and call
|
678 |
|
|
* the appropriate interrupt handler.
|
679 |
|
|
*/
|
680 |
|
|
while (pld) {
|
681 |
|
|
i = ffz(~pld);
|
682 |
|
|
pld &= pld - 1; /* clear least bit set */
|
683 |
|
|
if (i < 16) {
|
684 |
|
|
isa_device_interrupt(vector, regs);
|
685 |
|
|
} else {
|
686 |
|
|
device_interrupt(i, i, regs);
|
687 |
|
|
}
|
688 |
|
|
}
|
689 |
|
|
restore_flags(flags);
|
690 |
|
|
}
|
691 |
|
|
|
692 |
|
|
static inline void eb66_and_eb64p_device_interrupt(unsigned long vector,
|
693 |
|
|
struct pt_regs * regs)
|
694 |
|
|
{
|
695 |
|
|
unsigned long pld;
|
696 |
|
|
unsigned int i;
|
697 |
|
|
unsigned long flags;
|
698 |
|
|
|
699 |
|
|
save_flags(flags);
|
700 |
|
|
cli();
|
701 |
|
|
|
702 |
|
|
/* read the interrupt summary registers */
|
703 |
|
|
pld = inb(0x26) | (inb(0x27) << 8);
|
704 |
|
|
/*
|
705 |
|
|
* Now, for every possible bit set, work through
|
706 |
|
|
* them and call the appropriate interrupt handler.
|
707 |
|
|
*/
|
708 |
|
|
while (pld) {
|
709 |
|
|
i = ffz(~pld);
|
710 |
|
|
pld &= pld - 1; /* clear least bit set */
|
711 |
|
|
|
712 |
|
|
if (i == 5) {
|
713 |
|
|
isa_device_interrupt(vector, regs);
|
714 |
|
|
} else {
|
715 |
|
|
device_interrupt(16 + i, 16 + i, regs);
|
716 |
|
|
}
|
717 |
|
|
}
|
718 |
|
|
restore_flags(flags);
|
719 |
|
|
}
|
720 |
|
|
|
721 |
|
|
#if defined(CONFIG_ALPHA_MIATA) || defined(CONFIG_ALPHA_SX164)
|
722 |
|
|
/* we have to conditionally compile this because of PYXIS_xxx symbols */
|
723 |
|
|
static inline void miata_device_interrupt(unsigned long vector,
|
724 |
|
|
struct pt_regs * regs)
|
725 |
|
|
{
|
726 |
|
|
unsigned long pld, tmp;
|
727 |
|
|
unsigned int i;
|
728 |
|
|
unsigned long flags;
|
729 |
|
|
|
730 |
|
|
save_flags(flags);
|
731 |
|
|
cli();
|
732 |
|
|
|
733 |
|
|
/* read the interrupt summary register of PYXIS */
|
734 |
|
|
pld = (*(volatile unsigned long *)PYXIS_INT_REQ);
|
735 |
|
|
|
736 |
|
|
#if 0
|
737 |
|
|
printk("[0x%08lx/0x%08lx/0x%04x]", pld,
|
738 |
|
|
*(volatile unsigned long *)PYXIS_INT_MASK,
|
739 |
|
|
inb(0x20) | (inb(0xA0) << 8));
|
740 |
|
|
#endif
|
741 |
|
|
|
742 |
|
|
#ifdef CONFIG_ALPHA_MIATA
|
743 |
|
|
/* for now, AND off any bits we are not interested in: */
|
744 |
|
|
/* HALT (2), timer (6), ISA Bridge (7), 21142 (8) */
|
745 |
|
|
/* then all the PCI slots/INTXs (12-31) */
|
746 |
|
|
/* maybe HALT should only be used for SRM console boots? */
|
747 |
|
|
pld &= 0x00000000fffff9c4UL;
|
748 |
|
|
#endif /* MIATA */
|
749 |
|
|
#ifdef CONFIG_ALPHA_SX164
|
750 |
|
|
/* for now, AND off any bits we are not interested in: */
|
751 |
|
|
/* HALT (2), timer (6), ISA Bridge (7) */
|
752 |
|
|
/* then all the PCI slots/INTXs (8-23) */
|
753 |
|
|
/* HALT should only be used for SRM console boots */
|
754 |
|
|
pld &= 0x0000000000ffffc0UL;
|
755 |
|
|
#endif /* SX164 */
|
756 |
|
|
|
757 |
|
|
/*
|
758 |
|
|
* Now for every possible bit set, work through them and call
|
759 |
|
|
* the appropriate interrupt handler.
|
760 |
|
|
*/
|
761 |
|
|
while (pld) {
|
762 |
|
|
i = ffz(~pld);
|
763 |
|
|
pld &= pld - 1; /* clear least bit set */
|
764 |
|
|
if (i == 7) {
|
765 |
|
|
isa_device_interrupt(vector, regs);
|
766 |
|
|
} else if (i == 6)
|
767 |
|
|
continue;
|
768 |
|
|
else { /* if not timer int */
|
769 |
|
|
device_interrupt(16 + i, 16 + i, regs);
|
770 |
|
|
}
|
771 |
|
|
*(unsigned long *)PYXIS_INT_REQ = 1UL << i; mb();
|
772 |
|
|
tmp = *(volatile unsigned long *)PYXIS_INT_REQ;
|
773 |
|
|
}
|
774 |
|
|
restore_flags(flags);
|
775 |
|
|
}
|
776 |
|
|
#endif /* MIATA || SX164 */
|
777 |
|
|
|
778 |
|
|
static inline void noritake_device_interrupt(unsigned long vector,
|
779 |
|
|
struct pt_regs * regs)
|
780 |
|
|
{
|
781 |
|
|
unsigned long pld;
|
782 |
|
|
unsigned int i;
|
783 |
|
|
unsigned long flags;
|
784 |
|
|
|
785 |
|
|
save_flags(flags);
|
786 |
|
|
cli();
|
787 |
|
|
|
788 |
|
|
/* read the interrupt summary registers */
|
789 |
|
|
/* read the interrupt summary registers of NORITAKE */
|
790 |
|
|
pld = ((unsigned long) inw(0x544) << 32) |
|
791 |
|
|
((unsigned long) inw(0x542) << 16) |
|
792 |
|
|
((unsigned long) inb(0xa0) << 8) |
|
793 |
|
|
((unsigned long) inb(0x20));
|
794 |
|
|
|
795 |
|
|
#if 0
|
796 |
|
|
printk("[0x%08lx]", pld);
|
797 |
|
|
#endif
|
798 |
|
|
|
799 |
|
|
/*
|
800 |
|
|
* Now for every possible bit set, work through them and call
|
801 |
|
|
* the appropriate interrupt handler.
|
802 |
|
|
*/
|
803 |
|
|
while (pld) {
|
804 |
|
|
i = ffz(~pld);
|
805 |
|
|
pld &= pld - 1; /* clear least bit set */
|
806 |
|
|
if (i < 16) {
|
807 |
|
|
isa_device_interrupt(vector, regs);
|
808 |
|
|
} else {
|
809 |
|
|
device_interrupt(i, i, regs);
|
810 |
|
|
}
|
811 |
|
|
}
|
812 |
|
|
restore_flags(flags);
|
813 |
|
|
}
|
814 |
|
|
|
815 |
|
|
#endif /* CONFIG_PCI */
|
816 |
|
|
|
817 |
|
|
#if defined(CONFIG_ALPHA_RUFFIAN)
|
818 |
|
|
static inline void ruffian_device_interrupt(unsigned long vector,
|
819 |
|
|
struct pt_regs * regs)
|
820 |
|
|
|
821 |
|
|
{
|
822 |
|
|
unsigned long pld, tmp;
|
823 |
|
|
unsigned int i;
|
824 |
|
|
unsigned long flags;
|
825 |
|
|
|
826 |
|
|
save_flags(flags);
|
827 |
|
|
cli();
|
828 |
|
|
|
829 |
|
|
/* read the interrupt summary register of PYXIS */
|
830 |
|
|
pld = (*(volatile unsigned long *)PYXIS_INT_REQ);
|
831 |
|
|
|
832 |
|
|
/* for now, AND off any bits we are not interested in:
|
833 |
|
|
* HALT (2), timer (6), ISA Bridge (7), 21142 (8)
|
834 |
|
|
* then all the PCI slots/INTXs (12-31)
|
835 |
|
|
* flash(5) :DWH:
|
836 |
|
|
*/
|
837 |
|
|
pld &= 0x00000000ffffff9fUL;/* was ffff7f */
|
838 |
|
|
|
839 |
|
|
/*
|
840 |
|
|
* Now for every possible bit set, work through them and call
|
841 |
|
|
* the appropriate interrupt handler.
|
842 |
|
|
*/
|
843 |
|
|
|
844 |
|
|
while (pld) {
|
845 |
|
|
i = ffz(~pld);
|
846 |
|
|
pld &= pld - 1; /* clear least bit set */
|
847 |
|
|
if (i == 7) {
|
848 |
|
|
isa_device_interrupt(vector, regs);
|
849 |
|
|
} else { /* if not timer int */
|
850 |
|
|
device_interrupt(16 + i,16 + i,regs);
|
851 |
|
|
}
|
852 |
|
|
*(unsigned long *)PYXIS_INT_REQ = 1UL << i; mb();
|
853 |
|
|
tmp = *(volatile unsigned long *)PYXIS_INT_REQ;
|
854 |
|
|
}
|
855 |
|
|
restore_flags(flags);
|
856 |
|
|
}
|
857 |
|
|
#endif /* RUFFIAN */
|
858 |
|
|
|
859 |
|
|
static inline void takara_device_interrupt(unsigned long vector,
|
860 |
|
|
struct pt_regs * regs)
|
861 |
|
|
{
|
862 |
|
|
unsigned long flags;
|
863 |
|
|
unsigned intstatus;
|
864 |
|
|
|
865 |
|
|
save_flags(flags);
|
866 |
|
|
cli();
|
867 |
|
|
|
868 |
|
|
/*
|
869 |
|
|
* The PALcode will have passed us vectors 0x800 or 0x810,
|
870 |
|
|
* which are fairly arbitrary values and serve only to tell
|
871 |
|
|
* us whether an interrupt has come in on IRQ0 or IRQ1. If
|
872 |
|
|
* it's IRQ1 it's a PCI interrupt; if it's IRQ0, it's
|
873 |
|
|
* probably ISA, but PCI interrupts can come through IRQ0
|
874 |
|
|
* as well if the interrupt controller isn't in accelerated
|
875 |
|
|
* mode.
|
876 |
|
|
*
|
877 |
|
|
* OTOH, the accelerator thing doesn't seem to be working
|
878 |
|
|
* overly well, so what we'll do instead is try directly
|
879 |
|
|
* examining the Master Interrupt Register to see if it's a
|
880 |
|
|
* PCI interrupt, and if _not_ then we'll pass it on to the
|
881 |
|
|
* ISA handler.
|
882 |
|
|
*/
|
883 |
|
|
|
884 |
|
|
intstatus = inw(0x500) & 15;
|
885 |
|
|
if (intstatus) {
|
886 |
|
|
/*
|
887 |
|
|
* This is a PCI interrupt. Check each bit and
|
888 |
|
|
* despatch an interrupt if it's set.
|
889 |
|
|
*/
|
890 |
|
|
if (intstatus & 8) device_interrupt(16+3, 16+3, regs);
|
891 |
|
|
if (intstatus & 4) device_interrupt(16+2, 16+2, regs);
|
892 |
|
|
if (intstatus & 2) device_interrupt(16+1, 16+1, regs);
|
893 |
|
|
if (intstatus & 1) device_interrupt(16+0, 16+0, regs);
|
894 |
|
|
} else
|
895 |
|
|
isa_device_interrupt (vector, regs);
|
896 |
|
|
|
897 |
|
|
restore_flags(flags);
|
898 |
|
|
}
|
899 |
|
|
|
900 |
|
|
/*
|
901 |
|
|
* Jensen is special: the vector is 0x8X0 for EISA interrupt X, and
|
902 |
|
|
* 0x9X0 for the local motherboard interrupts..
|
903 |
|
|
*
|
904 |
|
|
* 0x660 - NMI
|
905 |
|
|
*
|
906 |
|
|
* 0x800 - IRQ0 interval timer (not used, as we use the RTC timer)
|
907 |
|
|
* 0x810 - IRQ1 line printer (duh..)
|
908 |
|
|
* 0x860 - IRQ6 floppy disk
|
909 |
|
|
* 0x8E0 - IRQ14 SCSI controller
|
910 |
|
|
*
|
911 |
|
|
* 0x900 - COM1
|
912 |
|
|
* 0x920 - COM2
|
913 |
|
|
* 0x980 - keyboard
|
914 |
|
|
* 0x990 - mouse
|
915 |
|
|
*
|
916 |
|
|
* PCI-based systems are more sane: they don't have the local
|
917 |
|
|
* interrupts at all, and have only normal PCI interrupts from
|
918 |
|
|
* devices. Happily it's easy enough to do a sane mapping from the
|
919 |
|
|
* Jensen.. Note that this means that we may have to do a hardware
|
920 |
|
|
* "ack" to a different interrupt than we report to the rest of the
|
921 |
|
|
* world.
|
922 |
|
|
*/
|
923 |
|
|
static inline void srm_device_interrupt(unsigned long vector, struct pt_regs * regs)
|
924 |
|
|
{
|
925 |
|
|
int irq, ack;
|
926 |
|
|
unsigned long flags;
|
927 |
|
|
|
928 |
|
|
save_flags(flags);
|
929 |
|
|
cli();
|
930 |
|
|
|
931 |
|
|
#if 0
|
932 |
|
|
printk("srm_device_interrupt: vector 0x%lx\n", vector);
|
933 |
|
|
#endif
|
934 |
|
|
|
935 |
|
|
ack = irq = (vector - 0x800) >> 4;
|
936 |
|
|
|
937 |
|
|
#ifdef CONFIG_ALPHA_JENSEN
|
938 |
|
|
switch (vector) {
|
939 |
|
|
case 0x660: handle_nmi(regs); return;
|
940 |
|
|
/* local device interrupts: */
|
941 |
|
|
case 0x900: handle_irq(4, regs); return; /* com1 -> irq 4 */
|
942 |
|
|
case 0x920: handle_irq(3, regs); return; /* com2 -> irq 3 */
|
943 |
|
|
case 0x980: handle_irq(1, regs); return; /* kbd -> irq 1 */
|
944 |
|
|
case 0x990: handle_irq(9, regs); return; /* mouse -> irq 9 */
|
945 |
|
|
default:
|
946 |
|
|
if (vector > 0x900) {
|
947 |
|
|
printk("Unknown local interrupt %lx\n", vector);
|
948 |
|
|
}
|
949 |
|
|
}
|
950 |
|
|
/* irq1 is supposed to be the keyboard, silly Jensen (is this really needed??) */
|
951 |
|
|
if (irq == 1)
|
952 |
|
|
irq = 7;
|
953 |
|
|
#endif /* CONFIG_ALPHA_JENSEN */
|
954 |
|
|
|
955 |
|
|
#ifdef CONFIG_ALPHA_MIATA
|
956 |
|
|
/*
|
957 |
|
|
* I really hate to do this, but the MIATA SRM console ignores the
|
958 |
|
|
* low 8 bits in the interrupt summary register, and reports the
|
959 |
|
|
* vector 0x80 *lower* than I expected from the bit numbering in
|
960 |
|
|
* the documentation.
|
961 |
|
|
* This was done because the low 8 summary bits really aren't used
|
962 |
|
|
* for reporting any interrupts (the PCI-ISA bridge, bit 7, isn't
|
963 |
|
|
* used for this purpose, as PIC interrupts are delivered as the
|
964 |
|
|
* vectors 0x800-0x8f0).
|
965 |
|
|
* But I really don't want to change the fixup code for allocation
|
966 |
|
|
* of IRQs, nor the irq_mask maintenance stuff, both of which look
|
967 |
|
|
* nice and clean now.
|
968 |
|
|
* So, here's this grotty hack... :-(
|
969 |
|
|
*/
|
970 |
|
|
if (irq >= 16)
|
971 |
|
|
ack = irq = irq + 8;
|
972 |
|
|
#endif /* CONFIG_ALPHA_MIATA */
|
973 |
|
|
|
974 |
|
|
#ifdef CONFIG_ALPHA_NORITAKE
|
975 |
|
|
/*
|
976 |
|
|
* I really hate to do this, but the NORITAKE SRM console reports
|
977 |
|
|
* PCI vectors *lower* than I expected from the bit numbering in
|
978 |
|
|
* the documentation.
|
979 |
|
|
* But I really don't want to change the fixup code for allocation
|
980 |
|
|
* of IRQs, nor the irq_mask maintenance stuff, both of which look
|
981 |
|
|
* nice and clean now.
|
982 |
|
|
* So, here's this grotty hack... :-(
|
983 |
|
|
*/
|
984 |
|
|
if (irq >= 16)
|
985 |
|
|
ack = irq = irq + 1;
|
986 |
|
|
#endif /* CONFIG_ALPHA_NORITAKE */
|
987 |
|
|
|
988 |
|
|
#ifdef CONFIG_ALPHA_SABLE
|
989 |
|
|
irq = sable_mask_to_irq[(ack)];
|
990 |
|
|
#if 0
|
991 |
|
|
if (irq == 5 || irq == 9 || irq == 10 || irq == 11 ||
|
992 |
|
|
irq == 14 || irq == 15)
|
993 |
|
|
printk("srm_device_interrupt: vector=0x%lx ack=0x%x irq=0x%x\n",
|
994 |
|
|
vector, ack, irq);
|
995 |
|
|
#endif
|
996 |
|
|
#endif /* CONFIG_ALPHA_SABLE */
|
997 |
|
|
|
998 |
|
|
device_interrupt(irq, ack, regs);
|
999 |
|
|
|
1000 |
|
|
restore_flags(flags) ;
|
1001 |
|
|
}
|
1002 |
|
|
|
1003 |
|
|
/* PROBE_MASK is the bitset of irqs that we consider for autoprobing: */
|
1004 |
|
|
#if defined(CONFIG_ALPHA_P2K)
|
1005 |
|
|
/* always mask out unused timer irq 0 and RTC irq 8 */
|
1006 |
|
|
# define PROBE_MASK (((1UL << NR_IRQS) - 1) & ~0x101UL)
|
1007 |
|
|
#elif defined(CONFIG_ALPHA_ALCOR) || defined(CONFIG_ALPHA_XLT)
|
1008 |
|
|
/* always mask out unused timer irq 0, "irqs" 20-30, and the EISA cascade: */
|
1009 |
|
|
# define PROBE_MASK (((1UL << NR_IRQS) - 1) & ~0xfff000000001UL)
|
1010 |
|
|
#elif defined(CONFIG_ALPHA_RUFFIAN)
|
1011 |
|
|
/* must leave timer irq 0 in the mask */
|
1012 |
|
|
# define PROBE_MASK ((1UL << NR_IRQS) - 1)
|
1013 |
|
|
#else
|
1014 |
|
|
/* always mask out unused timer irq 0: */
|
1015 |
|
|
# define PROBE_MASK (((1UL << NR_IRQS) - 1) & ~1UL)
|
1016 |
|
|
#endif
|
1017 |
|
|
|
1018 |
|
|
/*
|
1019 |
|
|
* Start listening for interrupts..
|
1020 |
|
|
*/
|
1021 |
|
|
unsigned long probe_irq_on(void)
|
1022 |
|
|
{
|
1023 |
|
|
struct irqaction * action;
|
1024 |
|
|
unsigned long irqs = 0;
|
1025 |
|
|
unsigned long delay;
|
1026 |
|
|
unsigned int i;
|
1027 |
|
|
|
1028 |
|
|
for (i = NR_IRQS - 1; i > 0; i--) {
|
1029 |
|
|
if (!(PROBE_MASK & (1UL << i))) {
|
1030 |
|
|
continue;
|
1031 |
|
|
}
|
1032 |
|
|
action = irq_action[i];
|
1033 |
|
|
if (!action) {
|
1034 |
|
|
enable_irq(i);
|
1035 |
|
|
irqs |= (1UL << i);
|
1036 |
|
|
}
|
1037 |
|
|
}
|
1038 |
|
|
/*
|
1039 |
|
|
* Wait about 100ms for spurious interrupts to mask themselves
|
1040 |
|
|
* out again...
|
1041 |
|
|
*/
|
1042 |
|
|
for (delay = jiffies + HZ/10; delay > jiffies; )
|
1043 |
|
|
barrier();
|
1044 |
|
|
|
1045 |
|
|
/* now filter out any obviously spurious interrupts */
|
1046 |
|
|
return irqs & ~irq_mask;
|
1047 |
|
|
}
|
1048 |
|
|
|
1049 |
|
|
/*
|
1050 |
|
|
* Get the result of the IRQ probe.. A negative result means that
|
1051 |
|
|
* we have several candidates (but we return the lowest-numbered
|
1052 |
|
|
* one).
|
1053 |
|
|
*/
|
1054 |
|
|
int probe_irq_off(unsigned long irqs)
|
1055 |
|
|
{
|
1056 |
|
|
int i;
|
1057 |
|
|
|
1058 |
|
|
irqs &= irq_mask;
|
1059 |
|
|
if (!irqs)
|
1060 |
|
|
return 0;
|
1061 |
|
|
i = ffz(~irqs);
|
1062 |
|
|
if (irqs != (1UL << i))
|
1063 |
|
|
i = -i;
|
1064 |
|
|
return i;
|
1065 |
|
|
}
|
1066 |
|
|
|
1067 |
|
|
static void machine_check(unsigned long vector, unsigned long la, struct pt_regs * regs)
|
1068 |
|
|
{
|
1069 |
|
|
#if defined(CONFIG_ALPHA_LCA)
|
1070 |
|
|
extern void lca_machine_check (unsigned long vector, unsigned long la,
|
1071 |
|
|
struct pt_regs *regs);
|
1072 |
|
|
lca_machine_check(vector, la, regs);
|
1073 |
|
|
#elif defined(CONFIG_ALPHA_APECS)
|
1074 |
|
|
extern void apecs_machine_check(unsigned long vector, unsigned long la,
|
1075 |
|
|
struct pt_regs * regs);
|
1076 |
|
|
apecs_machine_check(vector, la, regs);
|
1077 |
|
|
#elif defined(CONFIG_ALPHA_CIA)
|
1078 |
|
|
extern void cia_machine_check(unsigned long vector, unsigned long la,
|
1079 |
|
|
struct pt_regs * regs);
|
1080 |
|
|
cia_machine_check(vector, la, regs);
|
1081 |
|
|
#elif defined(CONFIG_ALPHA_PYXIS)
|
1082 |
|
|
extern void pyxis_machine_check(unsigned long vector, unsigned long la,
|
1083 |
|
|
struct pt_regs * regs);
|
1084 |
|
|
pyxis_machine_check(vector, la, regs);
|
1085 |
|
|
#elif defined(CONFIG_ALPHA_T2)
|
1086 |
|
|
extern void t2_machine_check(unsigned long vector, unsigned long la,
|
1087 |
|
|
struct pt_regs * regs);
|
1088 |
|
|
t2_machine_check(vector, la, regs);
|
1089 |
|
|
#else
|
1090 |
|
|
printk("Machine check\n");
|
1091 |
|
|
#endif
|
1092 |
|
|
}
|
1093 |
|
|
|
1094 |
|
|
asmlinkage void do_entInt(unsigned long type, unsigned long vector, unsigned long la_ptr,
|
1095 |
|
|
unsigned long a3, unsigned long a4, unsigned long a5,
|
1096 |
|
|
struct pt_regs regs)
|
1097 |
|
|
{
|
1098 |
|
|
#if 0
|
1099 |
|
|
printk("do_entInt: type 0x%lx\n", type);
|
1100 |
|
|
#endif
|
1101 |
|
|
switch (type) {
|
1102 |
|
|
case 0:
|
1103 |
|
|
printk("Interprocessor interrupt? You must be kidding\n");
|
1104 |
|
|
break;
|
1105 |
|
|
case 1:
|
1106 |
|
|
timer_interrupt(®s);
|
1107 |
|
|
return;
|
1108 |
|
|
case 2:
|
1109 |
|
|
machine_check(vector, la_ptr, ®s);
|
1110 |
|
|
return;
|
1111 |
|
|
case 3:
|
1112 |
|
|
#if defined(CONFIG_ALPHA_JENSEN) || defined(CONFIG_ALPHA_NONAME) || \
|
1113 |
|
|
defined(CONFIG_ALPHA_P2K) || defined(CONFIG_ALPHA_SRM)
|
1114 |
|
|
srm_device_interrupt(vector, ®s);
|
1115 |
|
|
#else /* everyone else */
|
1116 |
|
|
|
1117 |
|
|
#if defined(CONFIG_ALPHA_MIATA) || defined(CONFIG_ALPHA_SX164)
|
1118 |
|
|
miata_device_interrupt(vector, ®s);
|
1119 |
|
|
#elif defined(CONFIG_ALPHA_NORITAKE)
|
1120 |
|
|
noritake_device_interrupt(vector, ®s);
|
1121 |
|
|
#elif defined(CONFIG_ALPHA_ALCOR) || defined(CONFIG_ALPHA_XLT)
|
1122 |
|
|
alcor_and_xlt_device_interrupt(vector, ®s);
|
1123 |
|
|
#elif defined(CONFIG_ALPHA_CABRIOLET) || defined(CONFIG_ALPHA_EB66P) || \
|
1124 |
|
|
defined(CONFIG_ALPHA_EB164) || defined(CONFIG_ALPHA_PC164) || \
|
1125 |
|
|
defined(CONFIG_ALPHA_LX164)
|
1126 |
|
|
cabriolet_and_eb66p_device_interrupt(vector, ®s);
|
1127 |
|
|
#elif defined(CONFIG_ALPHA_MIKASA)
|
1128 |
|
|
mikasa_device_interrupt(vector, ®s);
|
1129 |
|
|
#elif defined(CONFIG_ALPHA_EB66) || defined(CONFIG_ALPHA_EB64P)
|
1130 |
|
|
eb66_and_eb64p_device_interrupt(vector, ®s);
|
1131 |
|
|
#elif defined(CONFIG_ALPHA_RUFFIAN)
|
1132 |
|
|
ruffian_device_interrupt(vector, ®s);
|
1133 |
|
|
#elif defined(CONFIG_ALPHA_TAKARA)
|
1134 |
|
|
takara_device_interrupt(vector, ®s);
|
1135 |
|
|
#elif NR_IRQS == 16
|
1136 |
|
|
isa_device_interrupt(vector, ®s);
|
1137 |
|
|
#endif
|
1138 |
|
|
#endif /* everyone else */
|
1139 |
|
|
return;
|
1140 |
|
|
case 4:
|
1141 |
|
|
printk("Performance counter interrupt\n");
|
1142 |
|
|
break;;
|
1143 |
|
|
default:
|
1144 |
|
|
printk("Hardware intr %ld %lx? Huh?\n", type, vector);
|
1145 |
|
|
}
|
1146 |
|
|
printk("PC = %016lx PS=%04lx\n", regs.pc, regs.ps);
|
1147 |
|
|
}
|
1148 |
|
|
|
1149 |
|
|
extern asmlinkage void entInt(void);
|
1150 |
|
|
|
1151 |
|
|
void init_IRQ(void)
|
1152 |
|
|
{
|
1153 |
|
|
unsigned int temp;
|
1154 |
|
|
|
1155 |
|
|
wrent(entInt, 0);
|
1156 |
|
|
|
1157 |
|
|
outb(0, DMA1_RESET_REG);
|
1158 |
|
|
outb(0, DMA2_RESET_REG);
|
1159 |
|
|
|
1160 |
|
|
/* FIXME FIXME FIXME FIXME FIXME */
|
1161 |
|
|
#if !defined(CONFIG_ALPHA_SX164)
|
1162 |
|
|
outb(0, DMA1_CLR_MASK_REG);
|
1163 |
|
|
/* we need to figure out why this fails on the SX164 */
|
1164 |
|
|
outb(0, DMA2_CLR_MASK_REG);
|
1165 |
|
|
#endif /* !SX164 */
|
1166 |
|
|
/* end FIXMEs */
|
1167 |
|
|
|
1168 |
|
|
#if defined(CONFIG_ALPHA_SABLE)
|
1169 |
|
|
outb(irq_mask , 0x537); /* slave 0 */
|
1170 |
|
|
outb(irq_mask >> 8, 0x53b); /* slave 1 */
|
1171 |
|
|
outb(irq_mask >> 16, 0x53d); /* slave 2 */
|
1172 |
|
|
outb(0x44, 0x535); /* enable cascades in master */
|
1173 |
|
|
#else /* everybody but SABLE */
|
1174 |
|
|
|
1175 |
|
|
#if defined(CONFIG_ALPHA_MIATA)
|
1176 |
|
|
/* note invert on MASK bits */
|
1177 |
|
|
*(unsigned long *)PYXIS_INT_MASK =
|
1178 |
|
|
~((long)irq_mask >> 16) & ~0x400000000000063bUL; mb();
|
1179 |
|
|
#if 0
|
1180 |
|
|
/* these break on MiataGL so we'll try not to do it at all */
|
1181 |
|
|
*(unsigned long *)PYXIS_INT_HILO = 0x000000B2UL; mb();/* ISA/NMI HI */
|
1182 |
|
|
*(unsigned long *)PYXIS_RT_COUNT = 0UL; mb();/* clear count */
|
1183 |
|
|
#endif
|
1184 |
|
|
/* clear upper timer */
|
1185 |
|
|
*(unsigned long *)PYXIS_INT_REQ = 0x4000000000000180UL; mb();
|
1186 |
|
|
|
1187 |
|
|
/* Send -INTA pulses to clear any pending interrupts ...*/
|
1188 |
|
|
temp = *(volatile unsigned int *) IACK_SC;
|
1189 |
|
|
|
1190 |
|
|
enable_irq(16 + 2); /* enable HALT switch - SRM only? */
|
1191 |
|
|
enable_irq(16 + 6); /* enable timer */
|
1192 |
|
|
enable_irq(16 + 7); /* enable ISA PIC cascade */
|
1193 |
|
|
#endif /* MIATA */
|
1194 |
|
|
|
1195 |
|
|
#if defined(CONFIG_ALPHA_SX164)
|
1196 |
|
|
#if !defined(CONFIG_ALPHA_SRM)
|
1197 |
|
|
/* note invert on MASK bits */
|
1198 |
|
|
*(unsigned long *)PYXIS_INT_MASK = ~((long)irq_mask >> 16); mb();
|
1199 |
|
|
#if 0
|
1200 |
|
|
*(unsigned long *)PYXIS_INT_HILO = 0x000000B2UL; mb();/* ISA/NMI HI */
|
1201 |
|
|
*(unsigned long *)PYXIS_RT_COUNT = 0UL; mb();/* clear count */
|
1202 |
|
|
#endif
|
1203 |
|
|
#endif /* !SRM */
|
1204 |
|
|
enable_irq(16 + 6); /* enable timer */
|
1205 |
|
|
enable_irq(16 + 7); /* enable ISA PIC cascade */
|
1206 |
|
|
#endif /* SX164 */
|
1207 |
|
|
|
1208 |
|
|
#if defined(CONFIG_ALPHA_NORITAKE)
|
1209 |
|
|
outw(~(irq_mask >> 16), 0x54a); /* note invert */
|
1210 |
|
|
outw(~(irq_mask >> 32), 0x54c); /* note invert */
|
1211 |
|
|
#endif /* NORITAKE */
|
1212 |
|
|
|
1213 |
|
|
#if defined(CONFIG_ALPHA_ALCOR) || defined(CONFIG_ALPHA_XLT)
|
1214 |
|
|
*(unsigned int *)GRU_INT_MASK = ~(irq_mask >> 16); mb();/* invert */
|
1215 |
|
|
*(unsigned int *)GRU_INT_EDGE = 0UL; mb();/* all are level */
|
1216 |
|
|
*(unsigned int *)GRU_INT_HILO = 0x80000000UL; mb();/* ISA only HI */
|
1217 |
|
|
*(unsigned int *)GRU_INT_CLEAR = 0UL; mb();/* all clear */
|
1218 |
|
|
enable_irq(16 + 31); /* enable (E)ISA PIC cascade */
|
1219 |
|
|
#endif /* ALCOR || XLT */
|
1220 |
|
|
|
1221 |
|
|
#if defined(CONFIG_ALPHA_CABRIOLET) || defined(CONFIG_ALPHA_EB66P) || \
|
1222 |
|
|
defined(CONFIG_ALPHA_PC164) || defined(CONFIG_ALPHA_LX164) || \
|
1223 |
|
|
defined(CONFIG_ALPHA_EB164)
|
1224 |
|
|
#if !defined(CONFIG_ALPHA_SRM)
|
1225 |
|
|
outl(irq_mask >> 16, 0x804);
|
1226 |
|
|
#endif /* !SRM */
|
1227 |
|
|
/* Send -INTA pulses to clear any pending interrupts ...*/
|
1228 |
|
|
temp = *(volatile unsigned int *) IACK_SC;
|
1229 |
|
|
enable_irq(16 + 4); /* enable SIO cascade */
|
1230 |
|
|
#endif /* CABRIO || EB66P || PC164 || LX164 || EB164 */
|
1231 |
|
|
|
1232 |
|
|
#if defined(CONFIG_ALPHA_MIKASA)
|
1233 |
|
|
outw(~(irq_mask >> 16), 0x536); /* note invert */
|
1234 |
|
|
#endif /* MIKASA */
|
1235 |
|
|
|
1236 |
|
|
#if defined(CONFIG_ALPHA_EB66) || defined(CONFIG_ALPHA_EB64P)
|
1237 |
|
|
outb(irq_mask >> 16, 0x26);
|
1238 |
|
|
outb(irq_mask >> 24, 0x27);
|
1239 |
|
|
enable_irq(16 + 5); /* enable SIO cascade */
|
1240 |
|
|
#endif /* EB66 || EB64P */
|
1241 |
|
|
|
1242 |
|
|
#if defined(CONFIG_ALPHA_RUFFIAN)
|
1243 |
|
|
/* invert 6&7 for i82371 */
|
1244 |
|
|
*(unsigned long *)PYXIS_INT_HILO = 0x000000c0UL;mb();
|
1245 |
|
|
*(unsigned long *)PYXIS_INT_CNFG = 0x00002064UL;mb(); /* all clear */
|
1246 |
|
|
*(unsigned long *)PYXIS_INT_MASK = ((long)0x00000000UL);mb();
|
1247 |
|
|
*(unsigned long *)PYXIS_INT_REQ = 0xffffffffUL;mb();
|
1248 |
|
|
|
1249 |
|
|
outb(0x11,0xA0);
|
1250 |
|
|
outb(0x08,0xA1);
|
1251 |
|
|
outb(0x02,0xA1);
|
1252 |
|
|
outb(0x01,0xA1);
|
1253 |
|
|
outb(0xFF,0xA1);
|
1254 |
|
|
|
1255 |
|
|
outb(0x11,0x20);
|
1256 |
|
|
outb(0x00,0x21);
|
1257 |
|
|
outb(0x04,0x21);
|
1258 |
|
|
outb(0x01,0x21);
|
1259 |
|
|
outb(0xFF,0x21);
|
1260 |
|
|
|
1261 |
|
|
/* Send -INTA pulses to clear any pending interrupts ...*/
|
1262 |
|
|
temp = *(volatile unsigned int *) IACK_SC;
|
1263 |
|
|
|
1264 |
|
|
/* Finish writing the 82C59A PIC Operation Control Words */
|
1265 |
|
|
outb(0x20,0xA0);
|
1266 |
|
|
outb(0x20,0x20);
|
1267 |
|
|
|
1268 |
|
|
/* Turn on the interrupt controller, the timer interrupt */
|
1269 |
|
|
enable_irq(16 + 7); /* enable ISA PIC cascade */
|
1270 |
|
|
enable_irq(0); /* enable timer */
|
1271 |
|
|
#endif /* RUFFIAN */
|
1272 |
|
|
|
1273 |
|
|
#ifdef CONFIG_ALPHA_TAKARA
|
1274 |
|
|
{
|
1275 |
|
|
unsigned int ctlreg = inl(0x500);
|
1276 |
|
|
ctlreg &= ~0x8000; /* return to non-accelerated mode */
|
1277 |
|
|
outw(ctlreg >> 16, 0x502);
|
1278 |
|
|
outw(ctlreg & 0xFFFF, 0x500);
|
1279 |
|
|
ctlreg = 0x05107c00; /* enable the PCI interrupt register */
|
1280 |
|
|
printk("Setting to 0x%08x\n", ctlreg);
|
1281 |
|
|
outw(ctlreg >> 16, 0x502);
|
1282 |
|
|
outw(ctlreg & 0xFFFF, 0x500);
|
1283 |
|
|
}
|
1284 |
|
|
#endif /* TAKARA */
|
1285 |
|
|
|
1286 |
|
|
/* and finally, everyone but SABLE does this */
|
1287 |
|
|
enable_irq(2); /* enable 2nd PIC cascade */
|
1288 |
|
|
|
1289 |
|
|
#endif /* SABLE */
|
1290 |
|
|
}
|