| /* |
| * arch/arm64/kernel/topology.c |
| * |
| * Copyright (C) 2011,2013,2014 Linaro Limited. |
| * |
| * Based on the arm32 version written by Vincent Guittot in turn based on |
| * arch/sh/kernel/topology.c |
| * |
| * This file is subject to the terms and conditions of the GNU General Public |
| * License. See the file "COPYING" in the main directory of this archive |
| * for more details. |
| */ |
| |
| #include <linux/cpu.h> |
| #include <linux/cpumask.h> |
| #include <linux/init.h> |
| #include <linux/percpu.h> |
| #include <linux/node.h> |
| #include <linux/nodemask.h> |
| #include <linux/sched.h> |
| |
| #include <asm/topology.h> |
| |
| /* |
| * cpu topology table |
| */ |
| struct cpu_topology cpu_topology[NR_CPUS]; |
| EXPORT_SYMBOL_GPL(cpu_topology); |
| |
| const struct cpumask *cpu_coregroup_mask(int cpu) |
| { |
| return &cpu_topology[cpu].core_sibling; |
| } |
| |
| static void update_siblings_masks(unsigned int cpuid) |
| { |
| struct cpu_topology *cpu_topo, *cpuid_topo = &cpu_topology[cpuid]; |
| int cpu; |
| |
| if (cpuid_topo->cluster_id == -1) { |
| /* |
| * DT does not contain topology information for this cpu |
| * reset it to default behaviour |
| */ |
| pr_debug("CPU%u: No topology information configured\n", cpuid); |
| cpuid_topo->core_id = 0; |
| cpumask_set_cpu(cpuid, &cpuid_topo->core_sibling); |
| cpumask_set_cpu(cpuid, &cpuid_topo->thread_sibling); |
| return; |
| } |
| |
| /* update core and thread sibling masks */ |
| for_each_possible_cpu(cpu) { |
| cpu_topo = &cpu_topology[cpu]; |
| |
| if (cpuid_topo->cluster_id != cpu_topo->cluster_id) |
| continue; |
| |
| cpumask_set_cpu(cpuid, &cpu_topo->core_sibling); |
| if (cpu != cpuid) |
| cpumask_set_cpu(cpu, &cpuid_topo->core_sibling); |
| |
| if (cpuid_topo->core_id != cpu_topo->core_id) |
| continue; |
| |
| cpumask_set_cpu(cpuid, &cpu_topo->thread_sibling); |
| if (cpu != cpuid) |
| cpumask_set_cpu(cpu, &cpuid_topo->thread_sibling); |
| } |
| } |
| |
| void store_cpu_topology(unsigned int cpuid) |
| { |
| update_siblings_masks(cpuid); |
| } |
| |
| /* |
| * init_cpu_topology is called at boot when only one cpu is running |
| * which prevent simultaneous write access to cpu_topology array |
| */ |
| void __init init_cpu_topology(void) |
| { |
| unsigned int cpu; |
| |
| /* init core mask and power*/ |
| for_each_possible_cpu(cpu) { |
| struct cpu_topology *cpu_topo = &cpu_topology[cpu]; |
| |
| cpu_topo->thread_id = -1; |
| cpu_topo->core_id = -1; |
| cpu_topo->cluster_id = -1; |
| cpumask_clear(&cpu_topo->core_sibling); |
| cpumask_clear(&cpu_topo->thread_sibling); |
| } |
| } |