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