diff options
Diffstat (limited to 'arch/arm/kernel/smp.c')
-rw-r--r-- | arch/arm/kernel/smp.c | 34 |
1 files changed, 17 insertions, 17 deletions
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index 550d63cef68e..c5fb5469054b 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c | |||
@@ -45,6 +45,7 @@ | |||
45 | #include <asm/smp_plat.h> | 45 | #include <asm/smp_plat.h> |
46 | #include <asm/virt.h> | 46 | #include <asm/virt.h> |
47 | #include <asm/mach/arch.h> | 47 | #include <asm/mach/arch.h> |
48 | #include <asm/mpu.h> | ||
48 | 49 | ||
49 | /* | 50 | /* |
50 | * as from 2.5, kernels no longer have an init_tasks structure | 51 | * as from 2.5, kernels no longer have an init_tasks structure |
@@ -78,6 +79,13 @@ void __init smp_set_ops(struct smp_operations *ops) | |||
78 | smp_ops = *ops; | 79 | smp_ops = *ops; |
79 | }; | 80 | }; |
80 | 81 | ||
82 | static unsigned long get_arch_pgd(pgd_t *pgd) | ||
83 | { | ||
84 | phys_addr_t pgdir = virt_to_phys(pgd); | ||
85 | BUG_ON(pgdir & ARCH_PGD_MASK); | ||
86 | return pgdir >> ARCH_PGD_SHIFT; | ||
87 | } | ||
88 | |||
81 | int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *idle) | 89 | int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *idle) |
82 | { | 90 | { |
83 | int ret; | 91 | int ret; |
@@ -87,8 +95,14 @@ int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *idle) | |||
87 | * its stack and the page tables. | 95 | * its stack and the page tables. |
88 | */ | 96 | */ |
89 | secondary_data.stack = task_stack_page(idle) + THREAD_START_SP; | 97 | secondary_data.stack = task_stack_page(idle) + THREAD_START_SP; |
90 | secondary_data.pgdir = virt_to_phys(idmap_pgd); | 98 | #ifdef CONFIG_ARM_MPU |
91 | secondary_data.swapper_pg_dir = virt_to_phys(swapper_pg_dir); | 99 | secondary_data.mpu_rgn_szr = mpu_rgn_info.rgns[MPU_RAM_REGION].drsr; |
100 | #endif | ||
101 | |||
102 | #ifdef CONFIG_MMU | ||
103 | secondary_data.pgdir = get_arch_pgd(idmap_pgd); | ||
104 | secondary_data.swapper_pg_dir = get_arch_pgd(swapper_pg_dir); | ||
105 | #endif | ||
92 | __cpuc_flush_dcache_area(&secondary_data, sizeof(secondary_data)); | 106 | __cpuc_flush_dcache_area(&secondary_data, sizeof(secondary_data)); |
93 | outer_clean_range(__pa(&secondary_data), __pa(&secondary_data + 1)); | 107 | outer_clean_range(__pa(&secondary_data), __pa(&secondary_data + 1)); |
94 | 108 | ||
@@ -112,9 +126,8 @@ int __cpuinit __cpu_up(unsigned int cpu, struct task_struct *idle) | |||
112 | pr_err("CPU%u: failed to boot: %d\n", cpu, ret); | 126 | pr_err("CPU%u: failed to boot: %d\n", cpu, ret); |
113 | } | 127 | } |
114 | 128 | ||
115 | secondary_data.stack = NULL; | ||
116 | secondary_data.pgdir = 0; | ||
117 | 129 | ||
130 | memset(&secondary_data, 0, sizeof(secondary_data)); | ||
118 | return ret; | 131 | return ret; |
119 | } | 132 | } |
120 | 133 | ||
@@ -651,17 +664,6 @@ void smp_send_reschedule(int cpu) | |||
651 | smp_cross_call(cpumask_of(cpu), IPI_RESCHEDULE); | 664 | smp_cross_call(cpumask_of(cpu), IPI_RESCHEDULE); |
652 | } | 665 | } |
653 | 666 | ||
654 | #ifdef CONFIG_HOTPLUG_CPU | ||
655 | static void smp_kill_cpus(cpumask_t *mask) | ||
656 | { | ||
657 | unsigned int cpu; | ||
658 | for_each_cpu(cpu, mask) | ||
659 | platform_cpu_kill(cpu); | ||
660 | } | ||
661 | #else | ||
662 | static void smp_kill_cpus(cpumask_t *mask) { } | ||
663 | #endif | ||
664 | |||
665 | void smp_send_stop(void) | 667 | void smp_send_stop(void) |
666 | { | 668 | { |
667 | unsigned long timeout; | 669 | unsigned long timeout; |
@@ -679,8 +681,6 @@ void smp_send_stop(void) | |||
679 | 681 | ||
680 | if (num_online_cpus() > 1) | 682 | if (num_online_cpus() > 1) |
681 | pr_warning("SMP: failed to stop secondary CPUs\n"); | 683 | pr_warning("SMP: failed to stop secondary CPUs\n"); |
682 | |||
683 | smp_kill_cpus(&mask); | ||
684 | } | 684 | } |
685 | 685 | ||
686 | /* | 686 | /* |