blob: ff662b23af5f60b53ccda3c65628c63536730eaf [file] [log] [blame]
Mark Brownf6e763b2014-03-04 07:51:17 +00001/*
2 * arch/arm64/kernel/topology.c
3 *
4 * Copyright (C) 2011,2013,2014 Linaro Limited.
5 *
6 * Based on the arm32 version written by Vincent Guittot in turn based on
7 * arch/sh/kernel/topology.c
8 *
9 * This file is subject to the terms and conditions of the GNU General Public
10 * License. See the file "COPYING" in the main directory of this archive
11 * for more details.
12 */
13
14#include <linux/cpu.h>
15#include <linux/cpumask.h>
16#include <linux/init.h>
17#include <linux/percpu.h>
18#include <linux/node.h>
19#include <linux/nodemask.h>
20#include <linux/sched.h>
21
22#include <asm/topology.h>
23
24/*
25 * cpu topology table
26 */
27struct cpu_topology cpu_topology[NR_CPUS];
28EXPORT_SYMBOL_GPL(cpu_topology);
29
30const struct cpumask *cpu_coregroup_mask(int cpu)
31{
32 return &cpu_topology[cpu].core_sibling;
33}
34
35static void update_siblings_masks(unsigned int cpuid)
36{
37 struct cpu_topology *cpu_topo, *cpuid_topo = &cpu_topology[cpuid];
38 int cpu;
39
40 if (cpuid_topo->cluster_id == -1) {
41 /*
42 * DT does not contain topology information for this cpu
43 * reset it to default behaviour
44 */
45 pr_debug("CPU%u: No topology information configured\n", cpuid);
Mark Brownf6e763b2014-03-04 07:51:17 +000046 return;
47 }
48
49 /* update core and thread sibling masks */
50 for_each_possible_cpu(cpu) {
51 cpu_topo = &cpu_topology[cpu];
52
53 if (cpuid_topo->cluster_id != cpu_topo->cluster_id)
54 continue;
55
56 cpumask_set_cpu(cpuid, &cpu_topo->core_sibling);
57 if (cpu != cpuid)
58 cpumask_set_cpu(cpu, &cpuid_topo->core_sibling);
59
60 if (cpuid_topo->core_id != cpu_topo->core_id)
61 continue;
62
63 cpumask_set_cpu(cpuid, &cpu_topo->thread_sibling);
64 if (cpu != cpuid)
65 cpumask_set_cpu(cpu, &cpuid_topo->thread_sibling);
66 }
67}
68
69void store_cpu_topology(unsigned int cpuid)
70{
71 update_siblings_masks(cpuid);
72}
73
74/*
75 * init_cpu_topology is called at boot when only one cpu is running
76 * which prevent simultaneous write access to cpu_topology array
77 */
78void __init init_cpu_topology(void)
79{
80 unsigned int cpu;
81
82 /* init core mask and power*/
83 for_each_possible_cpu(cpu) {
84 struct cpu_topology *cpu_topo = &cpu_topology[cpu];
85
86 cpu_topo->thread_id = -1;
Mark Brownc31bf042014-05-02 21:38:28 +010087 cpu_topo->core_id = 0;
Mark Brownf6e763b2014-03-04 07:51:17 +000088 cpu_topo->cluster_id = -1;
Mark Brownc31bf042014-05-02 21:38:28 +010089
Mark Brownf6e763b2014-03-04 07:51:17 +000090 cpumask_clear(&cpu_topo->core_sibling);
Mark Brownc31bf042014-05-02 21:38:28 +010091 cpumask_set_cpu(cpu, &cpu_topo->core_sibling);
Mark Brownf6e763b2014-03-04 07:51:17 +000092 cpumask_clear(&cpu_topo->thread_sibling);
Mark Brownc31bf042014-05-02 21:38:28 +010093 cpumask_set_cpu(cpu, &cpu_topo->thread_sibling);
Mark Brownf6e763b2014-03-04 07:51:17 +000094 }
95}