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-02-15 22:42:39 +0530
commit2879e357517574aebffae2448ae64a4da285590b (patch)
tree851d5607c5aceeb8e39d18328a54eff2d064733a
parentb9ab7b924cb36d29ab0d088707eca248bf5ffc53 (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))