aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSudeep KarkadaNagesha <sudeep.karkadanagesha@arm.com>2012-09-24 14:07:20 +0100
committerViresh Kumar <viresh.kumar@linaro.org>2013-03-12 14:54:45 +0530
commit161bebe64ce4264105c09e022deeab0b94b06ead (patch)
tree1ee49fb1b1bfe289f79bf78931f7c9b69a5aba0d
parentae50cc6c24965ee5239dfbbc6efa2f6370288f80 (diff)
sched: fix arch_get_fast_and_slow_cpus to get logical cpumask correctly
The patch "sched: Use device-tree to provide fast/slow CPU list for HMP" depends on the ordering of CPU's in the device tree. It breaks to determine the logical mask correctly if the logical mask of the CPUs differ from physical ordering in the device tree. This patch fix the logic by depending on the mpidr in the device tree and mapping that mpidr to the logical cpu. Signed-off-by: Sudeep KarkadaNagesha <sudeep.karkadanagesha@arm.com> Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
-rw-r--r--arch/arm/kernel/topology.c20
1 files changed, 16 insertions, 4 deletions
diff --git a/arch/arm/kernel/topology.c b/arch/arm/kernel/topology.c
index f487129ab7f..677325f4355 100644
--- a/arch/arm/kernel/topology.c
+++ b/arch/arm/kernel/topology.c
@@ -22,6 +22,7 @@
#include <linux/slab.h>
#include <asm/cputype.h>
+#include <asm/smp_plat.h>
#include <asm/topology.h>
/*
@@ -308,7 +309,7 @@ void __init arch_get_fast_and_slow_cpus(struct cpumask *fast,
struct cpumask *slow)
{
struct device_node *cn = NULL;
- int cpu = 0;
+ int cpu;
cpumask_clear(fast);
cpumask_clear(slow);
@@ -330,15 +331,26 @@ void __init arch_get_fast_and_slow_cpus(struct cpumask *fast,
*/
while ((cn = of_find_node_by_type(cn, "cpu"))) {
- if (cpu >= num_possible_cpus())
+ const u32 *mpidr;
+ int len;
+
+ mpidr = of_get_property(cn, "reg", &len);
+ if (!mpidr || len != 4) {
+ pr_err("* %s missing reg property\n", cn->full_name);
+ continue;
+ }
+
+ cpu = get_logical_index(be32_to_cpup(mpidr));
+ if (cpu == -EINVAL) {
+ pr_err("couldn't get logical index for mpidr %x\n",
+ be32_to_cpup(mpidr));
break;
+ }
if (is_little_cpu(cn))
cpumask_set_cpu(cpu, slow);
else
cpumask_set_cpu(cpu, fast);
-
- cpu++;
}
if (!cpumask_empty(fast) && !cpumask_empty(slow))