xref: /openbmc/linux/arch/parisc/kernel/topology.c (revision 6ba68836)
11da177e4SLinus Torvalds /*
2bf7b4c1bSHelge Deller  * arch/parisc/kernel/topology.c
31da177e4SLinus Torvalds  *
4bf7b4c1bSHelge Deller  * Copyright (C) 2017 Helge Deller <deller@gmx.de>
51da177e4SLinus Torvalds  *
6bf7b4c1bSHelge Deller  * based on arch/arm/kernel/topology.c
71da177e4SLinus Torvalds  *
8bf7b4c1bSHelge Deller  * This file is subject to the terms and conditions of the GNU General Public
9bf7b4c1bSHelge Deller  * License.  See the file "COPYING" in the main directory of this archive
10bf7b4c1bSHelge Deller  * for more details.
111da177e4SLinus Torvalds  */
121da177e4SLinus Torvalds 
13bf7b4c1bSHelge Deller #include <linux/percpu.h>
14bf7b4c1bSHelge Deller #include <linux/sched.h>
15bf7b4c1bSHelge Deller #include <linux/sched/topology.h>
1662773112SHelge Deller #include <linux/cpu.h>
171da177e4SLinus Torvalds 
18bf7b4c1bSHelge Deller #include <asm/topology.h>
1995370b40SHelge Deller #include <asm/sections.h>
201da177e4SLinus Torvalds 
2162773112SHelge Deller static DEFINE_PER_CPU(struct cpu, cpu_devices);
22bf7b4c1bSHelge Deller 
23bf7b4c1bSHelge Deller /*
24bf7b4c1bSHelge Deller  * store_cpu_topology is called at boot when only one cpu is running
25bf7b4c1bSHelge Deller  * and with the mutex cpu_hotplug.lock locked, when several cpus have booted,
26bf7b4c1bSHelge Deller  * which prevents simultaneous write access to cpu_topology array
27bf7b4c1bSHelge Deller  */
store_cpu_topology(unsigned int cpuid)2895370b40SHelge Deller void store_cpu_topology(unsigned int cpuid)
29bf7b4c1bSHelge Deller {
3062773112SHelge Deller 	struct cpu_topology *cpuid_topo = &cpu_topology[cpuid];
31bf7b4c1bSHelge Deller 	struct cpuinfo_parisc *p;
32bf7b4c1bSHelge Deller 	int max_socket = -1;
33bf7b4c1bSHelge Deller 	unsigned long cpu;
34bf7b4c1bSHelge Deller 
35bf7b4c1bSHelge Deller 	/* If the cpu topology has been already set, just return */
36bf7b4c1bSHelge Deller 	if (cpuid_topo->core_id != -1)
37bf7b4c1bSHelge Deller 		return;
38bf7b4c1bSHelge Deller 
3962773112SHelge Deller #ifdef CONFIG_HOTPLUG_CPU
4062773112SHelge Deller 	per_cpu(cpu_devices, cpuid).hotpluggable = 1;
4162773112SHelge Deller #endif
4262773112SHelge Deller 	if (register_cpu(&per_cpu(cpu_devices, cpuid), cpuid))
4362773112SHelge Deller 		pr_warn("Failed to register CPU%d device", cpuid);
4462773112SHelge Deller 
45bf7b4c1bSHelge Deller 	/* create cpu topology mapping */
46bf7b4c1bSHelge Deller 	cpuid_topo->thread_id = -1;
47bf7b4c1bSHelge Deller 	cpuid_topo->core_id = 0;
48bf7b4c1bSHelge Deller 
49bf7b4c1bSHelge Deller 	p = &per_cpu(cpu_data, cpuid);
50bf7b4c1bSHelge Deller 	for_each_online_cpu(cpu) {
51bf7b4c1bSHelge Deller 		const struct cpuinfo_parisc *cpuinfo = &per_cpu(cpu_data, cpu);
52bf7b4c1bSHelge Deller 
53bf7b4c1bSHelge Deller 		if (cpu == cpuid) /* ignore current cpu */
54bf7b4c1bSHelge Deller 			continue;
55bf7b4c1bSHelge Deller 
56bf7b4c1bSHelge Deller 		if (cpuinfo->cpu_loc == p->cpu_loc) {
57bf7b4c1bSHelge Deller 			cpuid_topo->core_id = cpu_topology[cpu].core_id;
58bf7b4c1bSHelge Deller 			if (p->cpu_loc) {
59bf7b4c1bSHelge Deller 				cpuid_topo->core_id++;
6062773112SHelge Deller 				cpuid_topo->package_id = cpu_topology[cpu].package_id;
61bf7b4c1bSHelge Deller 				continue;
62bf7b4c1bSHelge Deller 			}
63bf7b4c1bSHelge Deller 		}
64bf7b4c1bSHelge Deller 
6562773112SHelge Deller 		if (cpuid_topo->package_id == -1)
6662773112SHelge Deller 			max_socket = max(max_socket, cpu_topology[cpu].package_id);
67bf7b4c1bSHelge Deller 	}
68bf7b4c1bSHelge Deller 
6962773112SHelge Deller 	if (cpuid_topo->package_id == -1)
7062773112SHelge Deller 		cpuid_topo->package_id = max_socket + 1;
71bf7b4c1bSHelge Deller 
72bf7b4c1bSHelge Deller 	update_siblings_masks(cpuid);
73bf7b4c1bSHelge Deller 
7446162ac2SHelge Deller 	pr_info("CPU%u: cpu core %d of socket %d\n",
7546162ac2SHelge Deller 		cpuid,
76bf7b4c1bSHelge Deller 		cpu_topology[cpuid].core_id,
7762773112SHelge Deller 		cpu_topology[cpuid].package_id);
78bf7b4c1bSHelge Deller }
79bf7b4c1bSHelge Deller 
80bf7b4c1bSHelge Deller /*
81bf7b4c1bSHelge Deller  * init_cpu_topology is called at boot when only one cpu is running
82bf7b4c1bSHelge Deller  * which prevent simultaneous write access to cpu_topology array
83bf7b4c1bSHelge Deller  */
init_cpu_topology(void)84bf7b4c1bSHelge Deller void __init init_cpu_topology(void)
85bf7b4c1bSHelge Deller {
86*6ba68836SMikulas Patocka 	reset_cpu_topology();
87bf7b4c1bSHelge Deller }
88