aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/smp.c
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2010-08-06 13:13:54 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2010-08-06 13:13:54 -0400
commit11e4afb49b7fa1fc8e1ffd850c1806dd86a08204 (patch)
tree9e57efcb106ae912f7bec718feb3f8ec607559bb /arch/powerpc/kernel/smp.c
parent162500b3a3ff39d941d29db49b41a16667ae44f0 (diff)
parent9b2a606d3898fcb2eedb6faded3bb37549590ac4 (diff)
Merge branches 'gemini' and 'misc' into devel
Diffstat (limited to 'arch/powerpc/kernel/smp.c')
-rw-r--r--arch/powerpc/kernel/smp.c73
1 files changed, 48 insertions, 25 deletions
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index c2ee14498077..5c196d1086d9 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -59,8 +59,8 @@
59 59
60struct thread_info *secondary_ti; 60struct thread_info *secondary_ti;
61 61
62DEFINE_PER_CPU(cpumask_t, cpu_sibling_map) = CPU_MASK_NONE; 62DEFINE_PER_CPU(cpumask_var_t, cpu_sibling_map);
63DEFINE_PER_CPU(cpumask_t, cpu_core_map) = CPU_MASK_NONE; 63DEFINE_PER_CPU(cpumask_var_t, cpu_core_map);
64 64
65EXPORT_PER_CPU_SYMBOL(cpu_sibling_map); 65EXPORT_PER_CPU_SYMBOL(cpu_sibling_map);
66EXPORT_PER_CPU_SYMBOL(cpu_core_map); 66EXPORT_PER_CPU_SYMBOL(cpu_core_map);
@@ -271,6 +271,16 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
271 smp_store_cpu_info(boot_cpuid); 271 smp_store_cpu_info(boot_cpuid);
272 cpu_callin_map[boot_cpuid] = 1; 272 cpu_callin_map[boot_cpuid] = 1;
273 273
274 for_each_possible_cpu(cpu) {
275 zalloc_cpumask_var_node(&per_cpu(cpu_sibling_map, cpu),
276 GFP_KERNEL, cpu_to_node(cpu));
277 zalloc_cpumask_var_node(&per_cpu(cpu_core_map, cpu),
278 GFP_KERNEL, cpu_to_node(cpu));
279 }
280
281 cpumask_set_cpu(boot_cpuid, cpu_sibling_mask(boot_cpuid));
282 cpumask_set_cpu(boot_cpuid, cpu_core_mask(boot_cpuid));
283
274 if (smp_ops) 284 if (smp_ops)
275 if (smp_ops->probe) 285 if (smp_ops->probe)
276 max_cpus = smp_ops->probe(); 286 max_cpus = smp_ops->probe();
@@ -289,10 +299,6 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
289void __devinit smp_prepare_boot_cpu(void) 299void __devinit smp_prepare_boot_cpu(void)
290{ 300{
291 BUG_ON(smp_processor_id() != boot_cpuid); 301 BUG_ON(smp_processor_id() != boot_cpuid);
292
293 set_cpu_online(boot_cpuid, true);
294 cpu_set(boot_cpuid, per_cpu(cpu_sibling_map, boot_cpuid));
295 cpu_set(boot_cpuid, per_cpu(cpu_core_map, boot_cpuid));
296#ifdef CONFIG_PPC64 302#ifdef CONFIG_PPC64
297 paca[boot_cpuid].__current = current; 303 paca[boot_cpuid].__current = current;
298#endif 304#endif
@@ -313,7 +319,7 @@ int generic_cpu_disable(void)
313 set_cpu_online(cpu, false); 319 set_cpu_online(cpu, false);
314#ifdef CONFIG_PPC64 320#ifdef CONFIG_PPC64
315 vdso_data->processorCount--; 321 vdso_data->processorCount--;
316 fixup_irqs(cpu_online_map); 322 fixup_irqs(cpu_online_mask);
317#endif 323#endif
318 return 0; 324 return 0;
319} 325}
@@ -333,7 +339,7 @@ int generic_cpu_enable(unsigned int cpu)
333 cpu_relax(); 339 cpu_relax();
334 340
335#ifdef CONFIG_PPC64 341#ifdef CONFIG_PPC64
336 fixup_irqs(cpu_online_map); 342 fixup_irqs(cpu_online_mask);
337 /* counter the irq disable in fixup_irqs */ 343 /* counter the irq disable in fixup_irqs */
338 local_irq_enable(); 344 local_irq_enable();
339#endif 345#endif
@@ -462,7 +468,7 @@ out:
462 return id; 468 return id;
463} 469}
464 470
465/* Must be called when no change can occur to cpu_present_map, 471/* Must be called when no change can occur to cpu_present_mask,
466 * i.e. during cpu online or offline. 472 * i.e. during cpu online or offline.
467 */ 473 */
468static struct device_node *cpu_to_l2cache(int cpu) 474static struct device_node *cpu_to_l2cache(int cpu)
@@ -495,6 +501,14 @@ int __devinit start_secondary(void *unused)
495 current->active_mm = &init_mm; 501 current->active_mm = &init_mm;
496 502
497 smp_store_cpu_info(cpu); 503 smp_store_cpu_info(cpu);
504
505#if defined(CONFIG_BOOKE) || defined(CONFIG_40x)
506 /* Clear any pending timer interrupts */
507 mtspr(SPRN_TSR, TSR_ENW | TSR_WIS | TSR_DIS | TSR_FIS);
508
509 /* Enable decrementer interrupt */
510 mtspr(SPRN_TCR, TCR_DIE);
511#endif
498 set_dec(tb_ticks_per_jiffy); 512 set_dec(tb_ticks_per_jiffy);
499 preempt_disable(); 513 preempt_disable();
500 cpu_callin_map[cpu] = 1; 514 cpu_callin_map[cpu] = 1;
@@ -517,15 +531,15 @@ int __devinit start_secondary(void *unused)
517 for (i = 0; i < threads_per_core; i++) { 531 for (i = 0; i < threads_per_core; i++) {
518 if (cpu_is_offline(base + i)) 532 if (cpu_is_offline(base + i))
519 continue; 533 continue;
520 cpu_set(cpu, per_cpu(cpu_sibling_map, base + i)); 534 cpumask_set_cpu(cpu, cpu_sibling_mask(base + i));
521 cpu_set(base + i, per_cpu(cpu_sibling_map, cpu)); 535 cpumask_set_cpu(base + i, cpu_sibling_mask(cpu));
522 536
523 /* cpu_core_map should be a superset of 537 /* cpu_core_map should be a superset of
524 * cpu_sibling_map even if we don't have cache 538 * cpu_sibling_map even if we don't have cache
525 * information, so update the former here, too. 539 * information, so update the former here, too.
526 */ 540 */
527 cpu_set(cpu, per_cpu(cpu_core_map, base +i)); 541 cpumask_set_cpu(cpu, cpu_core_mask(base + i));
528 cpu_set(base + i, per_cpu(cpu_core_map, cpu)); 542 cpumask_set_cpu(base + i, cpu_core_mask(cpu));
529 } 543 }
530 l2_cache = cpu_to_l2cache(cpu); 544 l2_cache = cpu_to_l2cache(cpu);
531 for_each_online_cpu(i) { 545 for_each_online_cpu(i) {
@@ -533,8 +547,8 @@ int __devinit start_secondary(void *unused)
533 if (!np) 547 if (!np)
534 continue; 548 continue;
535 if (np == l2_cache) { 549 if (np == l2_cache) {
536 cpu_set(cpu, per_cpu(cpu_core_map, i)); 550 cpumask_set_cpu(cpu, cpu_core_mask(i));
537 cpu_set(i, per_cpu(cpu_core_map, cpu)); 551 cpumask_set_cpu(i, cpu_core_mask(cpu));
538 } 552 }
539 of_node_put(np); 553 of_node_put(np);
540 } 554 }
@@ -554,19 +568,22 @@ int setup_profiling_timer(unsigned int multiplier)
554 568
555void __init smp_cpus_done(unsigned int max_cpus) 569void __init smp_cpus_done(unsigned int max_cpus)
556{ 570{
557 cpumask_t old_mask; 571 cpumask_var_t old_mask;
558 572
559 /* We want the setup_cpu() here to be called from CPU 0, but our 573 /* We want the setup_cpu() here to be called from CPU 0, but our
560 * init thread may have been "borrowed" by another CPU in the meantime 574 * init thread may have been "borrowed" by another CPU in the meantime
561 * se we pin us down to CPU 0 for a short while 575 * se we pin us down to CPU 0 for a short while
562 */ 576 */
563 old_mask = current->cpus_allowed; 577 alloc_cpumask_var(&old_mask, GFP_NOWAIT);
564 set_cpus_allowed(current, cpumask_of_cpu(boot_cpuid)); 578 cpumask_copy(old_mask, &current->cpus_allowed);
579 set_cpus_allowed_ptr(current, cpumask_of(boot_cpuid));
565 580
566 if (smp_ops && smp_ops->setup_cpu) 581 if (smp_ops && smp_ops->setup_cpu)
567 smp_ops->setup_cpu(boot_cpuid); 582 smp_ops->setup_cpu(boot_cpuid);
568 583
569 set_cpus_allowed(current, old_mask); 584 set_cpus_allowed_ptr(current, old_mask);
585
586 free_cpumask_var(old_mask);
570 587
571 snapshot_timebases(); 588 snapshot_timebases();
572 589
@@ -591,10 +608,10 @@ int __cpu_disable(void)
591 /* Update sibling maps */ 608 /* Update sibling maps */
592 base = cpu_first_thread_in_core(cpu); 609 base = cpu_first_thread_in_core(cpu);
593 for (i = 0; i < threads_per_core; i++) { 610 for (i = 0; i < threads_per_core; i++) {
594 cpu_clear(cpu, per_cpu(cpu_sibling_map, base + i)); 611 cpumask_clear_cpu(cpu, cpu_sibling_mask(base + i));
595 cpu_clear(base + i, per_cpu(cpu_sibling_map, cpu)); 612 cpumask_clear_cpu(base + i, cpu_sibling_mask(cpu));
596 cpu_clear(cpu, per_cpu(cpu_core_map, base +i)); 613 cpumask_clear_cpu(cpu, cpu_core_mask(base + i));
597 cpu_clear(base + i, per_cpu(cpu_core_map, cpu)); 614 cpumask_clear_cpu(base + i, cpu_core_mask(cpu));
598 } 615 }
599 616
600 l2_cache = cpu_to_l2cache(cpu); 617 l2_cache = cpu_to_l2cache(cpu);
@@ -603,8 +620,8 @@ int __cpu_disable(void)
603 if (!np) 620 if (!np)
604 continue; 621 continue;
605 if (np == l2_cache) { 622 if (np == l2_cache) {
606 cpu_clear(cpu, per_cpu(cpu_core_map, i)); 623 cpumask_clear_cpu(cpu, cpu_core_mask(i));
607 cpu_clear(i, per_cpu(cpu_core_map, cpu)); 624 cpumask_clear_cpu(i, cpu_core_mask(cpu));
608 } 625 }
609 of_node_put(np); 626 of_node_put(np);
610 } 627 }
@@ -631,4 +648,10 @@ void cpu_hotplug_driver_unlock()
631{ 648{
632 mutex_unlock(&powerpc_cpu_hotplug_driver_mutex); 649 mutex_unlock(&powerpc_cpu_hotplug_driver_mutex);
633} 650}
651
652void cpu_die(void)
653{
654 if (ppc_md.cpu_die)
655 ppc_md.cpu_die();
656}
634#endif 657#endif