summaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel/smp.c
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2010-12-03 11:09:48 +0000
committerRussell King <rmk+kernel@arm.linux.org.uk>2010-12-20 15:09:08 +0000
commit05c74a6cbcfb416286a947668ba32f63d99fe74a (patch)
tree96f4dd3d5cbc67b14b93e9630f4f02becaa1a66a /arch/arm/kernel/smp.c
parentaec66ba1f75c2030cf66f5a21d1c81aa83aa5d95 (diff)
ARM: SMP: consolidate the common parts of smp_prepare_cpus()
There is a certain amount of smp_prepare_cpus() which doesn't belong in the platform support code - that is, code which is invariant to the SMP implementation. Move this code into arch/arm/kernel/smp.c, and add a platform_ prefix to the original function. Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/kernel/smp.c')
-rw-r--r--arch/arm/kernel/smp.c49
1 files changed, 38 insertions, 11 deletions
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 64f2d198c76..c66f2d3f65d 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -282,6 +282,17 @@ void __ref cpu_die(void)
#endif /* CONFIG_HOTPLUG_CPU */
/*
+ * Called by both boot and secondaries to move global data into
+ * per-processor storage.
+ */
+static void __cpuinit smp_store_cpu_info(unsigned int cpuid)
+{
+ struct cpuinfo_arm *cpu_info = &per_cpu(cpu_data, cpuid);
+
+ cpu_info->loops_per_jiffy = loops_per_jiffy;
+}
+
+/*
* This is the secondary CPU boot entry. We're using this CPUs
* idle thread stack, but a set of temporary page tables.
*/
@@ -339,17 +350,6 @@ asmlinkage void __cpuinit secondary_start_kernel(void)
cpu_idle();
}
-/*
- * Called by both boot and secondaries to move global data into
- * per-processor storage.
- */
-void __cpuinit smp_store_cpu_info(unsigned int cpuid)
-{
- struct cpuinfo_arm *cpu_info = &per_cpu(cpu_data, cpuid);
-
- cpu_info->loops_per_jiffy = loops_per_jiffy;
-}
-
void __init smp_cpus_done(unsigned int max_cpus)
{
int cpu;
@@ -372,6 +372,33 @@ void __init smp_prepare_boot_cpu(void)
per_cpu(cpu_data, cpu).idle = current;
}
+void __init smp_prepare_cpus(unsigned int max_cpus)
+{
+ unsigned int ncores = num_possible_cpus();
+
+ smp_store_cpu_info(smp_processor_id());
+
+ /*
+ * are we trying to boot more cores than exist?
+ */
+ if (max_cpus > ncores)
+ max_cpus = ncores;
+
+ if (max_cpus > 1) {
+ /*
+ * Enable the local timer or broadcast device for the
+ * boot CPU, but only if we have more than one CPU.
+ */
+ percpu_timer_setup();
+
+ /*
+ * Initialise the SCU if there are more than one CPU
+ * and let them know where to start.
+ */
+ platform_smp_prepare_cpus(max_cpus);
+ }
+}
+
void arch_send_call_function_ipi_mask(const struct cpumask *mask)
{
smp_cross_call(mask, IPI_CALL_FUNC);