diff options
author | Daniel Vetter <daniel.vetter@ffwll.ch> | 2013-03-19 09:47:30 +0100 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2013-03-19 09:47:30 +0100 |
commit | 0d4a42f6bd298e826620585e766a154ab460617a (patch) | |
tree | 406d8f7778691d858dbe3e48e4bbb10e99c0a58a /arch/arm64/kernel/smp.c | |
parent | d62b4892f3d9f7dd2002e5309be10719d6805b0f (diff) | |
parent | a937536b868b8369b98967929045f1df54234323 (diff) |
Merge tag 'v3.9-rc3' into drm-intel-next-queued
Backmerge so that I can merge Imre Deak's coalesced sg entries fixes,
which depend upon the new for_each_sg_page introduce in
commit a321e91b6d73ed011ffceed384c40d2785cf723b
Author: Imre Deak <imre.deak@intel.com>
Date: Wed Feb 27 17:02:56 2013 -0800
lib/scatterlist: add simple page iterator
The merge itself is just two trivial conflicts:
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'arch/arm64/kernel/smp.c')
-rw-r--r-- | arch/arm64/kernel/smp.c | 69 |
1 files changed, 47 insertions, 22 deletions
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c index 538300f2273d..bdd34597254b 100644 --- a/arch/arm64/kernel/smp.c +++ b/arch/arm64/kernel/smp.c @@ -233,7 +233,28 @@ void __init smp_prepare_boot_cpu(void) } static void (*smp_cross_call)(const struct cpumask *, unsigned int); -static phys_addr_t cpu_release_addr[NR_CPUS]; + +static const struct smp_enable_ops *enable_ops[] __initconst = { + &smp_spin_table_ops, + &smp_psci_ops, + NULL, +}; + +static const struct smp_enable_ops *smp_enable_ops[NR_CPUS]; + +static const struct smp_enable_ops * __init smp_get_enable_ops(const char *name) +{ + const struct smp_enable_ops *ops = enable_ops[0]; + + while (ops) { + if (!strcmp(name, ops->name)) + return ops; + + ops++; + } + + return NULL; +} /* * Enumerate the possible CPU set from the device tree. @@ -252,22 +273,22 @@ void __init smp_init_cpus(void) * We currently support only the "spin-table" enable-method. */ enable_method = of_get_property(dn, "enable-method", NULL); - if (!enable_method || strcmp(enable_method, "spin-table")) { - pr_err("CPU %d: missing or invalid enable-method property: %s\n", - cpu, enable_method); + if (!enable_method) { + pr_err("CPU %d: missing enable-method property\n", cpu); goto next; } - /* - * Determine the address from which the CPU is polling. - */ - if (of_property_read_u64(dn, "cpu-release-addr", - &cpu_release_addr[cpu])) { - pr_err("CPU %d: missing or invalid cpu-release-addr property\n", - cpu); + smp_enable_ops[cpu] = smp_get_enable_ops(enable_method); + + if (!smp_enable_ops[cpu]) { + pr_err("CPU %d: invalid enable-method property: %s\n", + cpu, enable_method); goto next; } + if (smp_enable_ops[cpu]->init_cpu(dn, cpu)) + goto next; + set_cpu_possible(cpu, true); next: cpu++; @@ -281,8 +302,7 @@ next: void __init smp_prepare_cpus(unsigned int max_cpus) { - int cpu; - void **release_addr; + int cpu, err; unsigned int ncores = num_possible_cpus(); /* @@ -291,30 +311,35 @@ void __init smp_prepare_cpus(unsigned int max_cpus) if (max_cpus > ncores) max_cpus = ncores; + /* Don't bother if we're effectively UP */ + if (max_cpus <= 1) + return; + /* * Initialise the present map (which describes the set of CPUs * actually populated at the present time) and release the * secondaries from the bootloader. + * + * Make sure we online at most (max_cpus - 1) additional CPUs. */ + max_cpus--; for_each_possible_cpu(cpu) { if (max_cpus == 0) break; - if (!cpu_release_addr[cpu]) + if (cpu == smp_processor_id()) + continue; + + if (!smp_enable_ops[cpu]) continue; - release_addr = __va(cpu_release_addr[cpu]); - release_addr[0] = (void *)__pa(secondary_holding_pen); - __flush_dcache_area(release_addr, sizeof(release_addr[0])); + err = smp_enable_ops[cpu]->prepare_cpu(cpu); + if (err) + continue; set_cpu_present(cpu, true); max_cpus--; } - - /* - * Send an event to wake up the secondaries. - */ - sev(); } |