aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/include/asm/smp.h9
-rw-r--r--arch/arm/kernel/smp.c49
-rw-r--r--arch/arm/mach-omap2/omap-smp.c33
-rw-r--r--arch/arm/mach-realview/platsmp.c41
-rw-r--r--arch/arm/mach-s5pv310/platsmp.c35
-rw-r--r--arch/arm/mach-tegra/platsmp.c18
-rw-r--r--arch/arm/mach-ux500/platsmp.c24
-rw-r--r--arch/arm/mach-vexpress/platsmp.c43
8 files changed, 83 insertions, 169 deletions
diff --git a/arch/arm/include/asm/smp.h b/arch/arm/include/asm/smp.h
index f93d0a637016..96ed521f2408 100644
--- a/arch/arm/include/asm/smp.h
+++ b/arch/arm/include/asm/smp.h
@@ -45,10 +45,6 @@ asmlinkage void do_IPI(int ipinr, struct pt_regs *regs);
45 */ 45 */
46extern void smp_init_cpus(void); 46extern void smp_init_cpus(void);
47 47
48/*
49 * Move global data into per-processor storage.
50 */
51extern void smp_store_cpu_info(unsigned int cpuid);
52 48
53/* 49/*
54 * Raise an IPI cross call on CPUs in callmap. 50 * Raise an IPI cross call on CPUs in callmap.
@@ -73,6 +69,11 @@ asmlinkage void secondary_start_kernel(void);
73extern void platform_secondary_init(unsigned int cpu); 69extern void platform_secondary_init(unsigned int cpu);
74 70
75/* 71/*
72 * Initialize cpu_possible map, and enable coherency
73 */
74extern void platform_smp_prepare_cpus(unsigned int);
75
76/*
76 * Initial data for bringing up a secondary CPU. 77 * Initial data for bringing up a secondary CPU.
77 */ 78 */
78struct secondary_data { 79struct secondary_data {
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 64f2d198c764..c66f2d3f65d3 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -282,6 +282,17 @@ void __ref cpu_die(void)
282#endif /* CONFIG_HOTPLUG_CPU */ 282#endif /* CONFIG_HOTPLUG_CPU */
283 283
284/* 284/*
285 * Called by both boot and secondaries to move global data into
286 * per-processor storage.
287 */
288static void __cpuinit smp_store_cpu_info(unsigned int cpuid)
289{
290 struct cpuinfo_arm *cpu_info = &per_cpu(cpu_data, cpuid);
291
292 cpu_info->loops_per_jiffy = loops_per_jiffy;
293}
294
295/*
285 * This is the secondary CPU boot entry. We're using this CPUs 296 * This is the secondary CPU boot entry. We're using this CPUs
286 * idle thread stack, but a set of temporary page tables. 297 * idle thread stack, but a set of temporary page tables.
287 */ 298 */
@@ -339,17 +350,6 @@ asmlinkage void __cpuinit secondary_start_kernel(void)
339 cpu_idle(); 350 cpu_idle();
340} 351}
341 352
342/*
343 * Called by both boot and secondaries to move global data into
344 * per-processor storage.
345 */
346void __cpuinit smp_store_cpu_info(unsigned int cpuid)
347{
348 struct cpuinfo_arm *cpu_info = &per_cpu(cpu_data, cpuid);
349
350 cpu_info->loops_per_jiffy = loops_per_jiffy;
351}
352
353void __init smp_cpus_done(unsigned int max_cpus) 353void __init smp_cpus_done(unsigned int max_cpus)
354{ 354{
355 int cpu; 355 int cpu;
@@ -372,6 +372,33 @@ void __init smp_prepare_boot_cpu(void)
372 per_cpu(cpu_data, cpu).idle = current; 372 per_cpu(cpu_data, cpu).idle = current;
373} 373}
374 374
375void __init smp_prepare_cpus(unsigned int max_cpus)
376{
377 unsigned int ncores = num_possible_cpus();
378
379 smp_store_cpu_info(smp_processor_id());
380
381 /*
382 * are we trying to boot more cores than exist?
383 */
384 if (max_cpus > ncores)
385 max_cpus = ncores;
386
387 if (max_cpus > 1) {
388 /*
389 * Enable the local timer or broadcast device for the
390 * boot CPU, but only if we have more than one CPU.
391 */
392 percpu_timer_setup();
393
394 /*
395 * Initialise the SCU if there are more than one CPU
396 * and let them know where to start.
397 */
398 platform_smp_prepare_cpus(max_cpus);
399 }
400}
401
375void arch_send_call_function_ipi_mask(const struct cpumask *mask) 402void arch_send_call_function_ipi_mask(const struct cpumask *mask)
376{ 403{
377 smp_cross_call(mask, IPI_CALL_FUNC); 404 smp_cross_call(mask, IPI_CALL_FUNC);
diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c
index 405a8fc53308..3c3d6796c97c 100644
--- a/arch/arm/mach-omap2/omap-smp.c
+++ b/arch/arm/mach-omap2/omap-smp.c
@@ -21,7 +21,6 @@
21#include <linux/io.h> 21#include <linux/io.h>
22 22
23#include <asm/cacheflush.h> 23#include <asm/cacheflush.h>
24#include <asm/localtimer.h>
25#include <asm/smp_scu.h> 24#include <asm/smp_scu.h>
26#include <mach/hardware.h> 25#include <mach/hardware.h>
27#include <mach/omap4-common.h> 26#include <mach/omap4-common.h>
@@ -123,20 +122,10 @@ void __init smp_init_cpus(void)
123 set_cpu_possible(i, true); 122 set_cpu_possible(i, true);
124} 123}
125 124
126void __init smp_prepare_cpus(unsigned int max_cpus) 125void __init platform_smp_prepare_cpus(unsigned int max_cpus)
127{ 126{
128 unsigned int ncores = num_possible_cpus();
129 unsigned int cpu = smp_processor_id();
130 int i; 127 int i;
131 128
132 smp_store_cpu_info(cpu);
133
134 /*
135 * are we trying to boot more cores than exist?
136 */
137 if (max_cpus > ncores)
138 max_cpus = ncores;
139
140 /* 129 /*
141 * Initialise the present map, which describes the set of CPUs 130 * Initialise the present map, which describes the set of CPUs
142 * actually populated at the present time. 131 * actually populated at the present time.
@@ -144,18 +133,10 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
144 for (i = 0; i < max_cpus; i++) 133 for (i = 0; i < max_cpus; i++)
145 set_cpu_present(i, true); 134 set_cpu_present(i, true);
146 135
147 if (max_cpus > 1) { 136 /*
148 /* 137 * Initialise the SCU and wake up the secondary core using
149 * Enable the local timer or broadcast device for the 138 * wakeup_secondary().
150 * boot CPU, but only if we have more than one CPU. 139 */
151 */ 140 scu_enable(scu_base);
152 percpu_timer_setup(); 141 wakeup_secondary();
153
154 /*
155 * Initialise the SCU and wake up the secondary core using
156 * wakeup_secondary().
157 */
158 scu_enable(scu_base);
159 wakeup_secondary();
160 }
161} 142}
diff --git a/arch/arm/mach-realview/platsmp.c b/arch/arm/mach-realview/platsmp.c
index ef3cc86f5140..380562cd6580 100644
--- a/arch/arm/mach-realview/platsmp.c
+++ b/arch/arm/mach-realview/platsmp.c
@@ -19,7 +19,6 @@
19#include <asm/cacheflush.h> 19#include <asm/cacheflush.h>
20#include <mach/hardware.h> 20#include <mach/hardware.h>
21#include <asm/mach-types.h> 21#include <asm/mach-types.h>
22#include <asm/localtimer.h>
23#include <asm/unified.h> 22#include <asm/unified.h>
24 23
25#include <mach/board-eb.h> 24#include <mach/board-eb.h>
@@ -147,20 +146,10 @@ void __init smp_init_cpus(void)
147 set_cpu_possible(i, true); 146 set_cpu_possible(i, true);
148} 147}
149 148
150void __init smp_prepare_cpus(unsigned int max_cpus) 149void __init platform_smp_prepare_cpus(unsigned int max_cpus)
151{ 150{
152 unsigned int ncores = num_possible_cpus();
153 unsigned int cpu = smp_processor_id();
154 int i; 151 int i;
155 152
156 smp_store_cpu_info(cpu);
157
158 /*
159 * are we trying to boot more cores than exist?
160 */
161 if (max_cpus > ncores)
162 max_cpus = ncores;
163
164 /* 153 /*
165 * Initialise the present map, which describes the set of CPUs 154 * Initialise the present map, which describes the set of CPUs
166 * actually populated at the present time. 155 * actually populated at the present time.
@@ -168,22 +157,14 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
168 for (i = 0; i < max_cpus; i++) 157 for (i = 0; i < max_cpus; i++)
169 set_cpu_present(i, true); 158 set_cpu_present(i, true);
170 159
171 if (max_cpus > 1) { 160 scu_enable(scu_base_addr());
172 /* 161
173 * Enable the local timer or broadcast device for the 162 /*
174 * boot CPU, but only if we have more than one CPU. 163 * Write the address of secondary startup into the
175 */ 164 * system-wide flags register. The BootMonitor waits
176 percpu_timer_setup(); 165 * until it receives a soft interrupt, and then the
177 166 * secondary CPU branches to this address.
178 scu_enable(scu_base_addr()); 167 */
179 168 __raw_writel(BSYM(virt_to_phys(realview_secondary_startup)),
180 /* 169 __io_address(REALVIEW_SYS_FLAGSSET));
181 * Write the address of secondary startup into the
182 * system-wide flags register. The BootMonitor waits
183 * until it receives a soft interrupt, and then the
184 * secondary CPU branches to this address.
185 */
186 __raw_writel(BSYM(virt_to_phys(realview_secondary_startup)),
187 __io_address(REALVIEW_SYS_FLAGSSET));
188 }
189} 170}
diff --git a/arch/arm/mach-s5pv310/platsmp.c b/arch/arm/mach-s5pv310/platsmp.c
index 560ada83b0b1..51c44d4c9890 100644
--- a/arch/arm/mach-s5pv310/platsmp.c
+++ b/arch/arm/mach-s5pv310/platsmp.c
@@ -22,7 +22,6 @@
22#include <linux/io.h> 22#include <linux/io.h>
23 23
24#include <asm/cacheflush.h> 24#include <asm/cacheflush.h>
25#include <asm/localtimer.h>
26#include <asm/smp_scu.h> 25#include <asm/smp_scu.h>
27#include <asm/unified.h> 26#include <asm/unified.h>
28 27
@@ -142,18 +141,10 @@ void __init smp_init_cpus(void)
142 set_cpu_possible(i, true); 141 set_cpu_possible(i, true);
143} 142}
144 143
145void __init smp_prepare_cpus(unsigned int max_cpus) 144void __init platform_smp_prepare_cpus(unsigned int max_cpus)
146{ 145{
147 unsigned int ncores = num_possible_cpus();
148 unsigned int cpu = smp_processor_id();
149 int i; 146 int i;
150 147
151 smp_store_cpu_info(cpu);
152
153 /* are we trying to boot more cores than exist? */
154 if (max_cpus > ncores)
155 max_cpus = ncores;
156
157 /* 148 /*
158 * Initialise the present map, which describes the set of CPUs 149 * Initialise the present map, which describes the set of CPUs
159 * actually populated at the present time. 150 * actually populated at the present time.
@@ -161,25 +152,13 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
161 for (i = 0; i < max_cpus; i++) 152 for (i = 0; i < max_cpus; i++)
162 set_cpu_present(i, true); 153 set_cpu_present(i, true);
163 154
155 scu_enable(scu_base_addr());
156
164 /* 157 /*
165 * Initialise the SCU if there are more than one CPU and let 158 * Write the address of secondary startup into the
166 * them know where to start. 159 * system-wide flags register. The boot monitor waits
160 * until it receives a soft interrupt, and then the
161 * secondary CPU branches to this address.
167 */ 162 */
168 if (max_cpus > 1) {
169 /*
170 * Enable the local timer or broadcast device for the
171 * boot CPU, but only if we have more than one CPU.
172 */
173 percpu_timer_setup();
174
175 scu_enable(scu_base_addr());
176
177 /*
178 * Write the address of secondary startup into the
179 * system-wide flags register. The boot monitor waits
180 * until it receives a soft interrupt, and then the
181 * secondary CPU branches to this address.
182 */
183 __raw_writel(BSYM(virt_to_phys(s5pv310_secondary_startup)), S5P_VA_SYSRAM); 163 __raw_writel(BSYM(virt_to_phys(s5pv310_secondary_startup)), S5P_VA_SYSRAM);
184 }
185} 164}
diff --git a/arch/arm/mach-tegra/platsmp.c b/arch/arm/mach-tegra/platsmp.c
index 66d0634e7a96..b66a0c2d990d 100644
--- a/arch/arm/mach-tegra/platsmp.c
+++ b/arch/arm/mach-tegra/platsmp.c
@@ -22,7 +22,6 @@
22#include <asm/cacheflush.h> 22#include <asm/cacheflush.h>
23#include <mach/hardware.h> 23#include <mach/hardware.h>
24#include <asm/mach-types.h> 24#include <asm/mach-types.h>
25#include <asm/localtimer.h>
26#include <asm/smp_scu.h> 25#include <asm/smp_scu.h>
27 26
28#include <mach/iomap.h> 27#include <mach/iomap.h>
@@ -127,20 +126,10 @@ void __init smp_init_cpus(void)
127 cpu_set(i, cpu_possible_map); 126 cpu_set(i, cpu_possible_map);
128} 127}
129 128
130void __init smp_prepare_cpus(unsigned int max_cpus) 129void __init platform_smp_prepare_cpus(unsigned int max_cpus)
131{ 130{
132 unsigned int ncores = scu_get_core_count(scu_base);
133 unsigned int cpu = smp_processor_id();
134 int i; 131 int i;
135 132
136 smp_store_cpu_info(cpu);
137
138 /*
139 * are we trying to boot more cores than exist?
140 */
141 if (max_cpus > ncores)
142 max_cpus = ncores;
143
144 /* 133 /*
145 * Initialise the present map, which describes the set of CPUs 134 * Initialise the present map, which describes the set of CPUs
146 * actually populated at the present time. 135 * actually populated at the present time.
@@ -148,8 +137,5 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
148 for (i = 0; i < max_cpus; i++) 137 for (i = 0; i < max_cpus; i++)
149 set_cpu_present(i, true); 138 set_cpu_present(i, true);
150 139
151 if (max_cpus > 1) { 140 scu_enable(scu_base);
152 percpu_timer_setup();
153 scu_enable(scu_base);
154 }
155} 141}
diff --git a/arch/arm/mach-ux500/platsmp.c b/arch/arm/mach-ux500/platsmp.c
index fd40fa175913..458a288981cb 100644
--- a/arch/arm/mach-ux500/platsmp.c
+++ b/arch/arm/mach-ux500/platsmp.c
@@ -18,7 +18,6 @@
18#include <linux/io.h> 18#include <linux/io.h>
19 19
20#include <asm/cacheflush.h> 20#include <asm/cacheflush.h>
21#include <asm/localtimer.h>
22#include <asm/smp_scu.h> 21#include <asm/smp_scu.h>
23#include <mach/hardware.h> 22#include <mach/hardware.h>
24 23
@@ -138,20 +137,10 @@ void __init smp_init_cpus(void)
138 set_cpu_possible(i, true); 137 set_cpu_possible(i, true);
139} 138}
140 139
141void __init smp_prepare_cpus(unsigned int max_cpus) 140void __init platform_smp_prepare_cpus(unsigned int max_cpus)
142{ 141{
143 unsigned int ncores = num_possible_cpus();
144 unsigned int cpu = smp_processor_id();
145 int i; 142 int i;
146 143
147 smp_store_cpu_info(cpu);
148
149 /*
150 * are we trying to boot more cores than exist?
151 */
152 if (max_cpus > ncores)
153 max_cpus = ncores;
154
155 /* 144 /*
156 * Initialise the present map, which describes the set of CPUs 145 * Initialise the present map, which describes the set of CPUs
157 * actually populated at the present time. 146 * actually populated at the present time.
@@ -159,13 +148,6 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
159 for (i = 0; i < max_cpus; i++) 148 for (i = 0; i < max_cpus; i++)
160 set_cpu_present(i, true); 149 set_cpu_present(i, true);
161 150
162 if (max_cpus > 1) { 151 scu_enable(__io_address(UX500_SCU_BASE));
163 /* 152 wakeup_secondary();
164 * Enable the local timer or broadcast device for the
165 * boot CPU, but only if we have more than one CPU.
166 */
167 percpu_timer_setup();
168 scu_enable(__io_address(UX500_SCU_BASE));
169 wakeup_secondary();
170 }
171} 153}
diff --git a/arch/arm/mach-vexpress/platsmp.c b/arch/arm/mach-vexpress/platsmp.c
index b5a758683668..a0341d14ff2a 100644
--- a/arch/arm/mach-vexpress/platsmp.c
+++ b/arch/arm/mach-vexpress/platsmp.c
@@ -17,7 +17,6 @@
17#include <linux/io.h> 17#include <linux/io.h>
18 18
19#include <asm/cacheflush.h> 19#include <asm/cacheflush.h>
20#include <asm/localtimer.h>
21#include <asm/smp_scu.h> 20#include <asm/smp_scu.h>
22#include <asm/unified.h> 21#include <asm/unified.h>
23 22
@@ -136,20 +135,10 @@ void __init smp_init_cpus(void)
136 set_cpu_possible(i, true); 135 set_cpu_possible(i, true);
137} 136}
138 137
139void __init smp_prepare_cpus(unsigned int max_cpus) 138void __init platform_smp_prepare_cpus(unsigned int max_cpus)
140{ 139{
141 unsigned int ncores = num_possible_cpus();
142 unsigned int cpu = smp_processor_id();
143 int i; 140 int i;
144 141
145 smp_store_cpu_info(cpu);
146
147 /*
148 * are we trying to boot more cores than exist?
149 */
150 if (max_cpus > ncores)
151 max_cpus = ncores;
152
153 /* 142 /*
154 * Initialise the present map, which describes the set of CPUs 143 * Initialise the present map, which describes the set of CPUs
155 * actually populated at the present time. 144 * actually populated at the present time.
@@ -157,27 +146,15 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
157 for (i = 0; i < max_cpus; i++) 146 for (i = 0; i < max_cpus; i++)
158 set_cpu_present(i, true); 147 set_cpu_present(i, true);
159 148
149 scu_enable(scu_base_addr());
150
160 /* 151 /*
161 * Initialise the SCU if there are more than one CPU and let 152 * Write the address of secondary startup into the
162 * them know where to start. 153 * system-wide flags register. The boot monitor waits
154 * until it receives a soft interrupt, and then the
155 * secondary CPU branches to this address.
163 */ 156 */
164 if (max_cpus > 1) { 157 writel(~0, MMIO_P2V(V2M_SYS_FLAGSCLR));
165 /* 158 writel(BSYM(virt_to_phys(vexpress_secondary_startup)),
166 * Enable the local timer or broadcast device for the 159 MMIO_P2V(V2M_SYS_FLAGSSET));
167 * boot CPU, but only if we have more than one CPU.
168 */
169 percpu_timer_setup();
170
171 scu_enable(scu_base_addr());
172
173 /*
174 * Write the address of secondary startup into the
175 * system-wide flags register. The boot monitor waits
176 * until it receives a soft interrupt, and then the
177 * secondary CPU branches to this address.
178 */
179 writel(~0, MMIO_P2V(V2M_SYS_FLAGSCLR));
180 writel(BSYM(virt_to_phys(vexpress_secondary_startup)),
181 MMIO_P2V(V2M_SYS_FLAGSSET));
182 }
183} 160}