aboutsummaryrefslogtreecommitdiff
path: root/arch/arm/kernel/topology.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/kernel/topology.c')
-rw-r--r--arch/arm/kernel/topology.c47
1 files changed, 43 insertions, 4 deletions
diff --git a/arch/arm/kernel/topology.c b/arch/arm/kernel/topology.c
index f487129ab7fd..fa45fb43a627 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))
@@ -381,6 +393,33 @@ void __init arch_get_hmp_domains(struct list_head *hmp_domains_list)
/*
+ * cluster_to_logical_mask - return cpu logical mask of CPUs in a cluster
+ * @socket_id: cluster HW identifier
+ * @cluster_mask: the cpumask location to be initialized, modified by the
+ * function only if return value == 0
+ *
+ * Return:
+ *
+ * 0 on success
+ * -EINVAL if cluster_mask is NULL or there is no record matching socket_id
+ */
+int cluster_to_logical_mask(unsigned int socket_id, cpumask_t *cluster_mask)
+{
+ int cpu;
+
+ if (!cluster_mask)
+ return -EINVAL;
+
+ for_each_online_cpu(cpu)
+ if (socket_id == topology_physical_package_id(cpu)) {
+ cpumask_copy(cluster_mask, topology_core_cpumask(cpu));
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
+/*
* init_cpu_topology is called at boot when only one cpu is running
* which prevent simultaneous write access to cpu_topology array
*/