Merge branch 'ec-cleanup' into release
[linux-2.6-block.git] / arch / sparc / kernel / sun4d_irq.c
CommitLineData
88278ca2 1/*
e54f8548 2 * SS1000/SC2000 interrupt handling.
1da177e4
LT
3 *
4 * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
5 * Heavily based on arch/sparc/kernel/irq.c.
6 */
7
1da177e4 8#include <linux/kernel_stat.h>
1da177e4 9#include <linux/seq_file.h>
e54f8548 10
1da177e4 11#include <asm/timer.h>
1da177e4
LT
12#include <asm/traps.h>
13#include <asm/irq.h>
14#include <asm/io.h>
1da177e4
LT
15#include <asm/sbi.h>
16#include <asm/cacheflush.h>
17
81265fd9 18#include "kernel.h"
32231a66
AV
19#include "irq.h"
20
e54f8548
SR
21/* Sun4d interrupts fall roughly into two categories. SBUS and
22 * cpu local. CPU local interrupts cover the timer interrupts
23 * and whatnot, and we encode those as normal PILs between
24 * 0 and 15.
25 *
26 * SBUS interrupts are encoded integers including the board number
27 * (plus one), the SBUS level, and the SBUS slot number. Sun4D
28 * IRQ dispatch is done by:
29 *
30 * 1) Reading the BW local interrupt table in order to get the bus
31 * interrupt mask.
32 *
33 * This table is indexed by SBUS interrupt level which can be
34 * derived from the PIL we got interrupted on.
35 *
36 * 2) For each bus showing interrupt pending from #1, read the
37 * SBI interrupt state register. This will indicate which slots
38 * have interrupts pending for that SBUS interrupt level.
39 */
40
f5f10857
DM
41struct sun4d_timer_regs {
42 u32 l10_timer_limit;
43 u32 l10_cur_countx;
44 u32 l10_limit_noclear;
45 u32 ctrl;
46 u32 l10_cur_count;
47};
48
49static struct sun4d_timer_regs __iomem *sun4d_timers;
50
1da177e4
LT
51#define TIMER_IRQ 10
52
53#define MAX_STATIC_ALLOC 4
c61c65cd 54static unsigned char sbus_tid[32];
1da177e4 55
a54123e2 56static struct irqaction *irq_action[NR_IRQS];
1da177e4 57
c61c65cd 58static struct sbus_action {
1da177e4
LT
59 struct irqaction *action;
60 /* For SMP this needs to be extended */
61} *sbus_actions;
62
63static int pil_to_sbus[] = {
e54f8548
SR
64 0,
65 0,
66 1,
67 2,
68 0,
69 3,
70 0,
71 4,
72 0,
73 5,
74 0,
75 6,
76 0,
77 7,
78 0,
79 0,
1da177e4
LT
80};
81
82static int sbus_to_pil[] = {
e54f8548
SR
83 0,
84 2,
85 3,
86 5,
87 7,
88 9,
89 11,
90 13,
1da177e4
LT
91};
92
93static int nsbi;
f8376e93
DM
94
95/* Exported for sun4d_smp.c */
1da177e4 96DEFINE_SPINLOCK(sun4d_imsk_lock);
1da177e4
LT
97
98int show_sun4d_interrupts(struct seq_file *p, void *v)
99{
100 int i = *(loff_t *) v, j = 0, k = 0, sbusl;
e54f8548 101 struct irqaction *action;
1da177e4
LT
102 unsigned long flags;
103#ifdef CONFIG_SMP
104 int x;
105#endif
106
107 spin_lock_irqsave(&irq_action_lock, flags);
108 if (i < NR_IRQS) {
109 sbusl = pil_to_sbus[i];
110 if (!sbusl) {
e54f8548
SR
111 action = *(i + irq_action);
112 if (!action)
113 goto out_unlock;
1da177e4
LT
114 } else {
115 for (j = 0; j < nsbi; j++) {
116 for (k = 0; k < 4; k++)
e54f8548
SR
117 action = sbus_actions[(j << 5) + (sbusl << 2) + k].action;
118 if (action)
1da177e4
LT
119 goto found_it;
120 }
121 goto out_unlock;
122 }
123found_it: seq_printf(p, "%3d: ", i);
124#ifndef CONFIG_SMP
125 seq_printf(p, "%10u ", kstat_irqs(i));
126#else
394e3902
AM
127 for_each_online_cpu(x)
128 seq_printf(p, "%10u ",
129 kstat_cpu(cpu_logical_map(x)).irqs[i]);
1da177e4
LT
130#endif
131 seq_printf(p, "%c %s",
67413202 132 (action->flags & IRQF_DISABLED) ? '+' : ' ',
1da177e4
LT
133 action->name);
134 action = action->next;
135 for (;;) {
136 for (; action; action = action->next) {
137 seq_printf(p, ",%s %s",
67413202 138 (action->flags & IRQF_DISABLED) ? " +" : "",
1da177e4
LT
139 action->name);
140 }
e54f8548
SR
141 if (!sbusl)
142 break;
1da177e4 143 k++;
e54f8548
SR
144 if (k < 4) {
145 action = sbus_actions[(j << 5) + (sbusl << 2) + k].action;
146 } else {
1da177e4 147 j++;
e54f8548
SR
148 if (j == nsbi)
149 break;
1da177e4 150 k = 0;
e54f8548 151 action = sbus_actions[(j << 5) + (sbusl << 2)].action;
1da177e4
LT
152 }
153 }
154 seq_putc(p, '\n');
155 }
156out_unlock:
157 spin_unlock_irqrestore(&irq_action_lock, flags);
158 return 0;
159}
160
161void sun4d_free_irq(unsigned int irq, void *dev_id)
162{
163 struct irqaction *action, **actionp;
164 struct irqaction *tmp = NULL;
e54f8548 165 unsigned long flags;
1da177e4
LT
166
167 spin_lock_irqsave(&irq_action_lock, flags);
168 if (irq < 15)
169 actionp = irq + irq_action;
170 else
171 actionp = &(sbus_actions[irq - (1 << 5)].action);
172 action = *actionp;
173 if (!action) {
e54f8548 174 printk(KERN_ERR "Trying to free free IRQ%d\n", irq);
1da177e4
LT
175 goto out_unlock;
176 }
177 if (dev_id) {
178 for (; action; action = action->next) {
179 if (action->dev_id == dev_id)
180 break;
181 tmp = action;
182 }
183 if (!action) {
e54f8548
SR
184 printk(KERN_ERR "Trying to free free shared IRQ%d\n",
185 irq);
1da177e4
LT
186 goto out_unlock;
187 }
67413202 188 } else if (action->flags & IRQF_SHARED) {
e54f8548
SR
189 printk(KERN_ERR "Trying to free shared IRQ%d with NULL device ID\n",
190 irq);
1da177e4
LT
191 goto out_unlock;
192 }
e54f8548
SR
193 if (action->flags & SA_STATIC_ALLOC) {
194 /*
195 * This interrupt is marked as specially allocated
1da177e4
LT
196 * so it is a bad idea to free it.
197 */
e54f8548 198 printk(KERN_ERR "Attempt to free statically allocated IRQ%d (%s)\n",
1da177e4
LT
199 irq, action->name);
200 goto out_unlock;
201 }
e54f8548 202
0d0659c7 203 if (tmp)
1da177e4
LT
204 tmp->next = action->next;
205 else
206 *actionp = action->next;
207
208 spin_unlock_irqrestore(&irq_action_lock, flags);
209
210 synchronize_irq(irq);
211
212 spin_lock_irqsave(&irq_action_lock, flags);
213
214 kfree(action);
215
216 if (!(*actionp))
0f516813 217 __disable_irq(irq);
1da177e4
LT
218
219out_unlock:
220 spin_unlock_irqrestore(&irq_action_lock, flags);
221}
222
e54f8548 223void sun4d_handler_irq(int pil, struct pt_regs *regs)
1da177e4 224{
0d84438d 225 struct pt_regs *old_regs;
e54f8548 226 struct irqaction *action;
1da177e4
LT
227 int cpu = smp_processor_id();
228 /* SBUS IRQ level (1 - 7) */
d4d1ec48 229 int sbusl = pil_to_sbus[pil];
e54f8548 230
1da177e4
LT
231 /* FIXME: Is this necessary?? */
232 cc_get_ipen();
e54f8548 233
d4d1ec48 234 cc_set_iclr(1 << pil);
e54f8548 235
0d84438d 236 old_regs = set_irq_regs(regs);
1da177e4 237 irq_enter();
d4d1ec48 238 kstat_cpu(cpu).irqs[pil]++;
1da177e4 239 if (!sbusl) {
d4d1ec48 240 action = *(pil + irq_action);
1da177e4 241 if (!action)
d4d1ec48 242 unexpected_irq(pil, NULL, regs);
1da177e4 243 do {
d4d1ec48 244 action->handler(pil, action->dev_id);
1da177e4
LT
245 action = action->next;
246 } while (action);
247 } else {
248 int bus_mask = bw_get_intr_mask(sbusl) & 0x3ffff;
249 int sbino;
250 struct sbus_action *actionp;
251 unsigned mask, slot;
252 int sbil = (sbusl << 2);
e54f8548 253
1da177e4 254 bw_clear_intr_mask(sbusl, bus_mask);
e54f8548 255
1da177e4
LT
256 /* Loop for each pending SBI */
257 for (sbino = 0; bus_mask; sbino++, bus_mask >>= 1)
258 if (bus_mask & 1) {
259 mask = acquire_sbi(SBI2DEVID(sbino), 0xf << sbil);
260 mask &= (0xf << sbil);
261 actionp = sbus_actions + (sbino << 5) + (sbil);
262 /* Loop for each pending SBI slot */
263 for (slot = (1 << sbil); mask; slot <<= 1, actionp++)
264 if (mask & slot) {
265 mask &= ~slot;
266 action = actionp->action;
e54f8548 267
1da177e4 268 if (!action)
d4d1ec48 269 unexpected_irq(pil, NULL, regs);
1da177e4 270 do {
d4d1ec48 271 action->handler(pil, action->dev_id);
1da177e4
LT
272 action = action->next;
273 } while (action);
274 release_sbi(SBI2DEVID(sbino), slot);
275 }
276 }
277 }
278 irq_exit();
0d84438d 279 set_irq_regs(old_regs);
1da177e4
LT
280}
281
1da177e4 282int sun4d_request_irq(unsigned int irq,
40220c1a 283 irq_handler_t handler,
e54f8548 284 unsigned long irqflags, const char *devname, void *dev_id)
1da177e4
LT
285{
286 struct irqaction *action, *tmp = NULL, **actionp;
287 unsigned long flags;
288 int ret;
e54f8548
SR
289
290 if (irq > 14 && irq < (1 << 5)) {
1da177e4
LT
291 ret = -EINVAL;
292 goto out;
293 }
294
295 if (!handler) {
296 ret = -EINVAL;
297 goto out;
298 }
299
300 spin_lock_irqsave(&irq_action_lock, flags);
301
302 if (irq >= (1 << 5))
303 actionp = &(sbus_actions[irq - (1 << 5)].action);
304 else
305 actionp = irq + irq_action;
306 action = *actionp;
e54f8548 307
1da177e4 308 if (action) {
67413202 309 if ((action->flags & IRQF_SHARED) && (irqflags & IRQF_SHARED)) {
70044df4
SR
310 for (tmp = action; tmp->next; tmp = tmp->next)
311 /* find last entry - tmp used below */;
1da177e4
LT
312 } else {
313 ret = -EBUSY;
314 goto out_unlock;
315 }
67413202 316 if ((action->flags & IRQF_DISABLED) ^ (irqflags & IRQF_DISABLED)) {
e54f8548
SR
317 printk(KERN_ERR "Attempt to mix fast and slow interrupts on IRQ%d denied\n",
318 irq);
1da177e4
LT
319 ret = -EBUSY;
320 goto out_unlock;
321 }
322 action = NULL; /* Or else! */
323 }
324
325 /* If this is flagged as statically allocated then we use our
326 * private struct which is never freed.
327 */
328 if (irqflags & SA_STATIC_ALLOC) {
329 if (static_irq_count < MAX_STATIC_ALLOC)
330 action = &static_irqaction[static_irq_count++];
331 else
e54f8548
SR
332 printk(KERN_ERR "Request for IRQ%d (%s) SA_STATIC_ALLOC failed using kmalloc\n",
333 irq, devname);
1da177e4 334 }
e54f8548 335
1da177e4 336 if (action == NULL)
e54f8548
SR
337 action = kmalloc(sizeof(struct irqaction), GFP_ATOMIC);
338
339 if (!action) {
1da177e4
LT
340 ret = -ENOMEM;
341 goto out_unlock;
342 }
343
344 action->handler = handler;
345 action->flags = irqflags;
1da177e4
LT
346 action->name = devname;
347 action->next = NULL;
348 action->dev_id = dev_id;
349
350 if (tmp)
351 tmp->next = action;
352 else
353 *actionp = action;
e54f8548 354
0f516813 355 __enable_irq(irq);
1da177e4
LT
356
357 ret = 0;
358out_unlock:
359 spin_unlock_irqrestore(&irq_action_lock, flags);
360out:
361 return ret;
362}
363
364static void sun4d_disable_irq(unsigned int irq)
365{
1da177e4
LT
366 int tid = sbus_tid[(irq >> 5) - 1];
367 unsigned long flags;
e54f8548 368
f8376e93
DM
369 if (irq < NR_IRQS)
370 return;
371
1da177e4
LT
372 spin_lock_irqsave(&sun4d_imsk_lock, flags);
373 cc_set_imsk_other(tid, cc_get_imsk_other(tid) | (1 << sbus_to_pil[(irq >> 2) & 7]));
374 spin_unlock_irqrestore(&sun4d_imsk_lock, flags);
1da177e4
LT
375}
376
377static void sun4d_enable_irq(unsigned int irq)
378{
1da177e4
LT
379 int tid = sbus_tid[(irq >> 5) - 1];
380 unsigned long flags;
e54f8548 381
f8376e93
DM
382 if (irq < NR_IRQS)
383 return;
384
1da177e4
LT
385 spin_lock_irqsave(&sun4d_imsk_lock, flags);
386 cc_set_imsk_other(tid, cc_get_imsk_other(tid) & ~(1 << sbus_to_pil[(irq >> 2) & 7]));
387 spin_unlock_irqrestore(&sun4d_imsk_lock, flags);
1da177e4
LT
388}
389
390#ifdef CONFIG_SMP
391static void sun4d_set_cpu_int(int cpu, int level)
392{
393 sun4d_send_ipi(cpu, level);
394}
395
396static void sun4d_clear_ipi(int cpu, int level)
397{
398}
399
400static void sun4d_set_udt(int cpu)
401{
402}
403
404/* Setup IRQ distribution scheme. */
405void __init sun4d_distribute_irqs(void)
406{
71d37211
DM
407 struct device_node *dp;
408
1da177e4
LT
409 int cpuid = cpu_logical_map(1);
410
411 if (cpuid == -1)
412 cpuid = cpu_logical_map(0);
71d37211
DM
413 for_each_node_by_name(dp, "sbi") {
414 int devid = of_getintprop_default(dp, "device-id", 0);
415 int board = of_getintprop_default(dp, "board#", 0);
416 sbus_tid[board] = cpuid;
417 set_sbi_tid(devid, cpuid << 3);
1da177e4 418 }
e54f8548 419 printk(KERN_ERR "All sbus IRQs directed to CPU%d\n", cpuid);
1da177e4
LT
420}
421#endif
e54f8548 422
1da177e4
LT
423static void sun4d_clear_clock_irq(void)
424{
f5f10857 425 sbus_readl(&sun4d_timers->l10_timer_limit);
1da177e4
LT
426}
427
1da177e4
LT
428static void sun4d_load_profile_irq(int cpu, unsigned int limit)
429{
430 bw_set_prof_limit(cpu, limit);
431}
432
f5f10857 433static void __init sun4d_load_profile_irqs(void)
1da177e4 434{
f5f10857 435 int cpu = 0, mid;
1da177e4 436
f5f10857
DM
437 while (!cpu_find_by_instance(cpu, NULL, &mid)) {
438 sun4d_load_profile_irq(mid >> 3, 0);
439 cpu++;
440 }
441}
442
1d05995b
SR
443unsigned int sun4d_build_device_irq(struct platform_device *op,
444 unsigned int real_irq)
445{
446 static int pil_to_sbus[] = {
447 0, 0, 1, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 0,
448 };
449 struct device_node *dp = op->dev.of_node;
450 struct device_node *io_unit, *sbi = dp->parent;
451 const struct linux_prom_registers *regs;
452 int board, slot;
453 int sbusl;
454
455 while (sbi) {
456 if (!strcmp(sbi->name, "sbi"))
457 break;
458
459 sbi = sbi->parent;
460 }
461 if (!sbi)
462 goto err_out;
463
464 regs = of_get_property(dp, "reg", NULL);
465 if (!regs)
466 goto err_out;
467
468 slot = regs->which_io;
469
470 /*
471 * If SBI's parent is not io-unit or the io-unit lacks
472 * a "board#" property, something is very wrong.
473 */
474 if (!sbi->parent || strcmp(sbi->parent->name, "io-unit")) {
475 printk("%s: Error, parent is not io-unit.\n", sbi->full_name);
476 goto err_out;
477 }
478 io_unit = sbi->parent;
479 board = of_getintprop_default(io_unit, "board#", -1);
480 if (board == -1) {
481 printk("%s: Error, lacks board# property.\n", io_unit->full_name);
482 goto err_out;
483 }
484
485 sbusl = pil_to_sbus[real_irq];
486 if (sbusl)
487 return (((board + 1) << 5) + (sbusl << 2) + slot);
488
489err_out:
490 return real_irq;
491}
492
f5f10857
DM
493static void __init sun4d_fixup_trap_table(void)
494{
1da177e4 495#ifdef CONFIG_SMP
f5f10857 496 unsigned long flags;
f5f10857 497 struct tt_entry *trap_table = &sparc_ttable[SP_TRAP_IRQ1 + (14 - 1)];
f5f10857
DM
498
499 /* Adjust so that we jump directly to smp4d_ticker */
500 lvl14_save[2] += smp4d_ticker - real_irq_entry;
501
502 /* For SMP we use the level 14 ticker, however the bootup code
503 * has copied the firmware's level 14 vector into the boot cpu's
504 * trap table, we must fix this now or we get squashed.
505 */
506 local_irq_save(flags);
507 patchme_maybe_smp_msg[0] = 0x01000000; /* NOP out the branch */
508 trap_table->inst_one = lvl14_save[0];
509 trap_table->inst_two = lvl14_save[1];
510 trap_table->inst_three = lvl14_save[2];
511 trap_table->inst_four = lvl14_save[3];
512 local_flush_cache_all();
513 local_irq_restore(flags);
1da177e4 514#endif
f5f10857
DM
515}
516
517static void __init sun4d_init_timers(irq_handler_t counter_fn)
518{
519 struct device_node *dp;
520 struct resource res;
521 const u32 *reg;
522 int err;
523
524 dp = of_find_node_by_name(NULL, "cpu-unit");
525 if (!dp) {
526 prom_printf("sun4d_init_timers: Unable to find cpu-unit\n");
527 prom_halt();
528 }
529
530 /* Which cpu-unit we use is arbitrary, we can view the bootbus timer
531 * registers via any cpu's mapping. The first 'reg' property is the
532 * bootbus.
533 */
534 reg = of_get_property(dp, "reg", NULL);
c2e27c35 535 of_node_put(dp);
f5f10857
DM
536 if (!reg) {
537 prom_printf("sun4d_init_timers: No reg property\n");
538 prom_halt();
539 }
540
541 res.start = reg[1];
542 res.end = reg[2] - 1;
543 res.flags = reg[0] & 0xff;
544 sun4d_timers = of_ioremap(&res, BW_TIMER_LIMIT,
545 sizeof(struct sun4d_timer_regs), "user timer");
546 if (!sun4d_timers) {
547 prom_printf("sun4d_init_timers: Can't map timer regs\n");
548 prom_halt();
549 }
550
551 sbus_writel((((1000000/HZ) + 1) << 10), &sun4d_timers->l10_timer_limit);
1da177e4 552
1da177e4 553 master_l10_counter = &sun4d_timers->l10_cur_count;
1da177e4 554
f5f10857 555 err = request_irq(TIMER_IRQ, counter_fn,
67413202 556 (IRQF_DISABLED | SA_STATIC_ALLOC),
1da177e4 557 "timer", NULL);
f5f10857 558 if (err) {
e54f8548
SR
559 prom_printf("sun4d_init_timers: request_irq() failed with %d\n",
560 err);
1da177e4
LT
561 prom_halt();
562 }
f5f10857
DM
563 sun4d_load_profile_irqs();
564 sun4d_fixup_trap_table();
1da177e4
LT
565}
566
567void __init sun4d_init_sbi_irq(void)
568{
71d37211 569 struct device_node *dp;
f8376e93
DM
570 int target_cpu = 0;
571
572#ifdef CONFIG_SMP
573 target_cpu = boot_cpu_id;
574#endif
1da177e4
LT
575
576 nsbi = 0;
71d37211 577 for_each_node_by_name(dp, "sbi")
1da177e4 578 nsbi++;
e54f8548 579 sbus_actions = kzalloc(nsbi * 8 * 4 * sizeof(struct sbus_action), GFP_ATOMIC);
d4accd60
DM
580 if (!sbus_actions) {
581 prom_printf("SUN4D: Cannot allocate sbus_actions, halting.\n");
582 prom_halt();
583 }
71d37211
DM
584 for_each_node_by_name(dp, "sbi") {
585 int devid = of_getintprop_default(dp, "device-id", 0);
586 int board = of_getintprop_default(dp, "board#", 0);
587 unsigned int mask;
588
f8376e93
DM
589 set_sbi_tid(devid, target_cpu << 3);
590 sbus_tid[board] = target_cpu;
591
1da177e4 592 /* Get rid of pending irqs from PROM */
71d37211 593 mask = acquire_sbi(devid, 0xffffffff);
1da177e4 594 if (mask) {
e54f8548
SR
595 printk(KERN_ERR "Clearing pending IRQs %08x on SBI %d\n",
596 mask, board);
71d37211 597 release_sbi(devid, mask);
1da177e4
LT
598 }
599 }
600}
601
1da177e4
LT
602void __init sun4d_init_IRQ(void)
603{
604 local_irq_disable();
605
1da177e4
LT
606 BTFIXUPSET_CALL(enable_irq, sun4d_enable_irq, BTFIXUPCALL_NORM);
607 BTFIXUPSET_CALL(disable_irq, sun4d_disable_irq, BTFIXUPCALL_NORM);
608 BTFIXUPSET_CALL(clear_clock_irq, sun4d_clear_clock_irq, BTFIXUPCALL_NORM);
1da177e4 609 BTFIXUPSET_CALL(load_profile_irq, sun4d_load_profile_irq, BTFIXUPCALL_NORM);
bbdc2661
SR
610
611 sparc_irq_config.init_timers = sun4d_init_timers;
1d05995b 612 sparc_irq_config.build_device_irq = sun4d_build_device_irq;
bbdc2661 613
1da177e4
LT
614#ifdef CONFIG_SMP
615 BTFIXUPSET_CALL(set_cpu_int, sun4d_set_cpu_int, BTFIXUPCALL_NORM);
616 BTFIXUPSET_CALL(clear_cpu_int, sun4d_clear_ipi, BTFIXUPCALL_NOP);
617 BTFIXUPSET_CALL(set_irq_udt, sun4d_set_udt, BTFIXUPCALL_NOP);
618#endif
619 /* Cannot enable interrupts until OBP ticker is disabled. */
620}