diff options
Diffstat (limited to 'arch/arm/kernel/smp.c')
-rw-r--r-- | arch/arm/kernel/smp.c | 49 |
1 files changed, 38 insertions, 11 deletions
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 | */ | ||
288 | static 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 | */ | ||
346 | void __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 | |||
353 | void __init smp_cpus_done(unsigned int max_cpus) | 353 | void __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 | ||
375 | void __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 | |||
375 | void arch_send_call_function_ipi_mask(const struct cpumask *mask) | 402 | void 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); |