diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2010-08-06 13:13:54 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2010-08-06 13:13:54 -0400 |
commit | 11e4afb49b7fa1fc8e1ffd850c1806dd86a08204 (patch) | |
tree | 9e57efcb106ae912f7bec718feb3f8ec607559bb /arch/powerpc/kernel/smp.c | |
parent | 162500b3a3ff39d941d29db49b41a16667ae44f0 (diff) | |
parent | 9b2a606d3898fcb2eedb6faded3bb37549590ac4 (diff) |
Merge branches 'gemini' and 'misc' into devel
Diffstat (limited to 'arch/powerpc/kernel/smp.c')
-rw-r--r-- | arch/powerpc/kernel/smp.c | 73 |
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 | ||
60 | struct thread_info *secondary_ti; | 60 | struct thread_info *secondary_ti; |
61 | 61 | ||
62 | DEFINE_PER_CPU(cpumask_t, cpu_sibling_map) = CPU_MASK_NONE; | 62 | DEFINE_PER_CPU(cpumask_var_t, cpu_sibling_map); |
63 | DEFINE_PER_CPU(cpumask_t, cpu_core_map) = CPU_MASK_NONE; | 63 | DEFINE_PER_CPU(cpumask_var_t, cpu_core_map); |
64 | 64 | ||
65 | EXPORT_PER_CPU_SYMBOL(cpu_sibling_map); | 65 | EXPORT_PER_CPU_SYMBOL(cpu_sibling_map); |
66 | EXPORT_PER_CPU_SYMBOL(cpu_core_map); | 66 | EXPORT_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) | |||
289 | void __devinit smp_prepare_boot_cpu(void) | 299 | void __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 | */ |
468 | static struct device_node *cpu_to_l2cache(int cpu) | 474 | static 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 | ||
555 | void __init smp_cpus_done(unsigned int max_cpus) | 569 | void __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, ¤t->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 | |||
652 | void cpu_die(void) | ||
653 | { | ||
654 | if (ppc_md.cpu_die) | ||
655 | ppc_md.cpu_die(); | ||
656 | } | ||
634 | #endif | 657 | #endif |