aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc/kernel')
-rw-r--r--arch/sparc/kernel/sun4d_irq.c83
1 files changed, 48 insertions, 35 deletions
diff --git a/arch/sparc/kernel/sun4d_irq.c b/arch/sparc/kernel/sun4d_irq.c
index 1290b5998f83..7424967142f0 100644
--- a/arch/sparc/kernel/sun4d_irq.c
+++ b/arch/sparc/kernel/sun4d_irq.c
@@ -409,47 +409,55 @@ static void sun4d_set_udt(int cpu)
409/* Setup IRQ distribution scheme. */ 409/* Setup IRQ distribution scheme. */
410void __init sun4d_distribute_irqs(void) 410void __init sun4d_distribute_irqs(void)
411{ 411{
412 struct device_node *dp;
413
412#ifdef DISTRIBUTE_IRQS 414#ifdef DISTRIBUTE_IRQS
413 struct sbus_bus *sbus; 415 cpumask_t sbus_serving_map;
414 unsigned long sbus_serving_map;
415 416
416 sbus_serving_map = cpu_present_map; 417 sbus_serving_map = cpu_present_map;
417 for_each_sbus(sbus) { 418 for_each_node_by_name(dp, "sbi") {
418 if ((sbus->board * 2) == boot_cpu_id && (cpu_present_map & (1 << (sbus->board * 2 + 1)))) 419 int board = of_getintprop_default(dp, "board#", 0);
419 sbus_tid[sbus->board] = (sbus->board * 2 + 1); 420
420 else if (cpu_present_map & (1 << (sbus->board * 2))) 421 if ((board * 2) == boot_cpu_id && cpu_isset(board * 2 + 1, cpu_present_map))
421 sbus_tid[sbus->board] = (sbus->board * 2); 422 sbus_tid[board] = (board * 2 + 1);
422 else if (cpu_present_map & (1 << (sbus->board * 2 + 1))) 423 else if (cpu_isset(board * 2, cpu_present_map))
423 sbus_tid[sbus->board] = (sbus->board * 2 + 1); 424 sbus_tid[board] = (board * 2);
425 else if (cpu_isset(board * 2 + 1, cpu_present_map))
426 sbus_tid[board] = (board * 2 + 1);
424 else 427 else
425 sbus_tid[sbus->board] = 0xff; 428 sbus_tid[board] = 0xff;
426 if (sbus_tid[sbus->board] != 0xff) 429 if (sbus_tid[board] != 0xff)
427 sbus_serving_map &= ~(1 << sbus_tid[sbus->board]); 430 cpu_clear(sbus_tid[board], sbus_serving_map);
428 } 431 }
429 for_each_sbus(sbus) 432 for_each_node_by_name(dp, "sbi") {
430 if (sbus_tid[sbus->board] == 0xff) { 433 int board = of_getintprop_default(dp, "board#", 0);
434 if (sbus_tid[board] == 0xff) {
431 int i = 31; 435 int i = 31;
432 436
433 if (!sbus_serving_map) 437 if (cpus_empty(sbus_serving_map))
434 sbus_serving_map = cpu_present_map; 438 sbus_serving_map = cpu_present_map;
435 while (!(sbus_serving_map & (1 << i))) 439 while (cpu_isset(i, sbus_serving_map))
436 i--; 440 i--;
437 sbus_tid[sbus->board] = i; 441 sbus_tid[board] = i;
438 sbus_serving_map &= ~(1 << i); 442 cpu_clear(i, sbus_serving_map);
439 } 443 }
440 for_each_sbus(sbus) { 444 }
441 printk("sbus%d IRQs directed to CPU%d\n", sbus->board, sbus_tid[sbus->board]); 445 for_each_node_by_name(dp, "sbi") {
442 set_sbi_tid(sbus->devid, sbus_tid[sbus->board] << 3); 446 int devid = of_getintprop_default(dp, "device-id", 0);
447 int board = of_getintprop_default(dp, "board#", 0);
448 printk("sbus%d IRQs directed to CPU%d\n", board, sbus_tid[board]);
449 set_sbi_tid(devid, sbus_tid[board] << 3);
443 } 450 }
444#else 451#else
445 struct sbus_bus *sbus;
446 int cpuid = cpu_logical_map(1); 452 int cpuid = cpu_logical_map(1);
447 453
448 if (cpuid == -1) 454 if (cpuid == -1)
449 cpuid = cpu_logical_map(0); 455 cpuid = cpu_logical_map(0);
450 for_each_sbus(sbus) { 456 for_each_node_by_name(dp, "sbi") {
451 sbus_tid[sbus->board] = cpuid; 457 int devid = of_getintprop_default(dp, "device-id", 0);
452 set_sbi_tid(sbus->devid, cpuid << 3); 458 int board = of_getintprop_default(dp, "board#", 0);
459 sbus_tid[board] = cpuid;
460 set_sbi_tid(devid, cpuid << 3);
453 } 461 }
454 printk("All sbus IRQs directed to CPU%d\n", cpuid); 462 printk("All sbus IRQs directed to CPU%d\n", cpuid);
455#endif 463#endif
@@ -541,29 +549,34 @@ static void __init sun4d_init_timers(irq_handler_t counter_fn)
541 549
542void __init sun4d_init_sbi_irq(void) 550void __init sun4d_init_sbi_irq(void)
543{ 551{
544 struct sbus_bus *sbus; 552 struct device_node *dp;
545 unsigned mask;
546 553
547 nsbi = 0; 554 nsbi = 0;
548 for_each_sbus(sbus) 555 for_each_node_by_name(dp, "sbi")
549 nsbi++; 556 nsbi++;
550 sbus_actions = kzalloc (nsbi * 8 * 4 * sizeof(struct sbus_action), GFP_ATOMIC); 557 sbus_actions = kzalloc (nsbi * 8 * 4 * sizeof(struct sbus_action), GFP_ATOMIC);
551 if (!sbus_actions) { 558 if (!sbus_actions) {
552 prom_printf("SUN4D: Cannot allocate sbus_actions, halting.\n"); 559 prom_printf("SUN4D: Cannot allocate sbus_actions, halting.\n");
553 prom_halt(); 560 prom_halt();
554 } 561 }
555 for_each_sbus(sbus) { 562 for_each_node_by_name(dp, "sbi") {
563 int devid = of_getintprop_default(dp, "device-id", 0);
564 int board = of_getintprop_default(dp, "board#", 0);
565 unsigned int mask;
566
556#ifdef CONFIG_SMP 567#ifdef CONFIG_SMP
557 extern unsigned char boot_cpu_id; 568 {
569 extern unsigned char boot_cpu_id;
558 570
559 set_sbi_tid(sbus->devid, boot_cpu_id << 3); 571 set_sbi_tid(devid, boot_cpu_id << 3);
560 sbus_tid[sbus->board] = boot_cpu_id; 572 sbus_tid[board] = boot_cpu_id;
573 }
561#endif 574#endif
562 /* Get rid of pending irqs from PROM */ 575 /* Get rid of pending irqs from PROM */
563 mask = acquire_sbi(sbus->devid, 0xffffffff); 576 mask = acquire_sbi(devid, 0xffffffff);
564 if (mask) { 577 if (mask) {
565 printk ("Clearing pending IRQs %08x on SBI %d\n", mask, sbus->board); 578 printk ("Clearing pending IRQs %08x on SBI %d\n", mask, board);
566 release_sbi(sbus->devid, mask); 579 release_sbi(devid, mask);
567 } 580 }
568 } 581 }
569} 582}