xref: /openbmc/linux/arch/parisc/kernel/topology.c (revision 85250a24)
1 /*
2  * arch/parisc/kernel/topology.c
3  *
4  * Copyright (C) 2017 Helge Deller <deller@gmx.de>
5  *
6  * based on arch/arm/kernel/topology.c
7  *
8  * This file is subject to the terms and conditions of the GNU General Public
9  * License.  See the file "COPYING" in the main directory of this archive
10  * for more details.
11  */
12 
13 #include <linux/percpu.h>
14 #include <linux/sched.h>
15 #include <linux/sched/topology.h>
16 #include <linux/cpu.h>
17 
18 #include <asm/topology.h>
19 #include <asm/sections.h>
20 
21 static DEFINE_PER_CPU(struct cpu, cpu_devices);
22 
23 /*
24  * store_cpu_topology is called at boot when only one cpu is running
25  * and with the mutex cpu_hotplug.lock locked, when several cpus have booted,
26  * which prevents simultaneous write access to cpu_topology array
27  */
28 void store_cpu_topology(unsigned int cpuid)
29 {
30 	struct cpu_topology *cpuid_topo = &cpu_topology[cpuid];
31 	struct cpuinfo_parisc *p;
32 	int max_socket = -1;
33 	unsigned long cpu;
34 
35 	/* If the cpu topology has been already set, just return */
36 	if (cpuid_topo->core_id != -1)
37 		return;
38 
39 #ifdef CONFIG_HOTPLUG_CPU
40 	per_cpu(cpu_devices, cpuid).hotpluggable = 1;
41 #endif
42 	if (register_cpu(&per_cpu(cpu_devices, cpuid), cpuid))
43 		pr_warn("Failed to register CPU%d device", cpuid);
44 
45 	/* create cpu topology mapping */
46 	cpuid_topo->thread_id = -1;
47 	cpuid_topo->core_id = 0;
48 
49 	p = &per_cpu(cpu_data, cpuid);
50 	for_each_online_cpu(cpu) {
51 		const struct cpuinfo_parisc *cpuinfo = &per_cpu(cpu_data, cpu);
52 
53 		if (cpu == cpuid) /* ignore current cpu */
54 			continue;
55 
56 		if (cpuinfo->cpu_loc == p->cpu_loc) {
57 			cpuid_topo->core_id = cpu_topology[cpu].core_id;
58 			if (p->cpu_loc) {
59 				cpuid_topo->core_id++;
60 				cpuid_topo->package_id = cpu_topology[cpu].package_id;
61 				continue;
62 			}
63 		}
64 
65 		if (cpuid_topo->package_id == -1)
66 			max_socket = max(max_socket, cpu_topology[cpu].package_id);
67 	}
68 
69 	if (cpuid_topo->package_id == -1)
70 		cpuid_topo->package_id = max_socket + 1;
71 
72 	update_siblings_masks(cpuid);
73 
74 	pr_info("CPU%u: cpu core %d of socket %d\n",
75 		cpuid,
76 		cpu_topology[cpuid].core_id,
77 		cpu_topology[cpuid].package_id);
78 }
79 
80 /*
81  * init_cpu_topology is called at boot when only one cpu is running
82  * which prevent simultaneous write access to cpu_topology array
83  */
84 void __init init_cpu_topology(void)
85 {
86 	reset_cpu_topology();
87 }
88