xref: /openbmc/linux/arch/parisc/kernel/topology.c (revision 09de5cd2)
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 static int dualcores_found;
24 
25 /*
26  * store_cpu_topology is called at boot when only one cpu is running
27  * and with the mutex cpu_hotplug.lock locked, when several cpus have booted,
28  * which prevents simultaneous write access to cpu_topology array
29  */
30 void store_cpu_topology(unsigned int cpuid)
31 {
32 	struct cpu_topology *cpuid_topo = &cpu_topology[cpuid];
33 	struct cpuinfo_parisc *p;
34 	int max_socket = -1;
35 	unsigned long cpu;
36 
37 	/* If the cpu topology has been already set, just return */
38 	if (cpuid_topo->core_id != -1)
39 		return;
40 
41 #ifdef CONFIG_HOTPLUG_CPU
42 	per_cpu(cpu_devices, cpuid).hotpluggable = 1;
43 #endif
44 	if (register_cpu(&per_cpu(cpu_devices, cpuid), cpuid))
45 		pr_warn("Failed to register CPU%d device", cpuid);
46 
47 	/* create cpu topology mapping */
48 	cpuid_topo->thread_id = -1;
49 	cpuid_topo->core_id = 0;
50 
51 	p = &per_cpu(cpu_data, cpuid);
52 	for_each_online_cpu(cpu) {
53 		const struct cpuinfo_parisc *cpuinfo = &per_cpu(cpu_data, cpu);
54 
55 		if (cpu == cpuid) /* ignore current cpu */
56 			continue;
57 
58 		if (cpuinfo->cpu_loc == p->cpu_loc) {
59 			cpuid_topo->core_id = cpu_topology[cpu].core_id;
60 			if (p->cpu_loc) {
61 				cpuid_topo->core_id++;
62 				cpuid_topo->package_id = cpu_topology[cpu].package_id;
63 				dualcores_found = 1;
64 				continue;
65 			}
66 		}
67 
68 		if (cpuid_topo->package_id == -1)
69 			max_socket = max(max_socket, cpu_topology[cpu].package_id);
70 	}
71 
72 	if (cpuid_topo->package_id == -1)
73 		cpuid_topo->package_id = max_socket + 1;
74 
75 	update_siblings_masks(cpuid);
76 
77 	pr_info("CPU%u: cpu core %d of socket %d\n",
78 		cpuid,
79 		cpu_topology[cpuid].core_id,
80 		cpu_topology[cpuid].package_id);
81 }
82 
83 static struct sched_domain_topology_level parisc_mc_topology[] = {
84 #ifdef CONFIG_SCHED_MC
85 	{ cpu_coregroup_mask, cpu_core_flags, SD_INIT_NAME(MC) },
86 #endif
87 
88 	{ cpu_cpu_mask, SD_INIT_NAME(DIE) },
89 	{ NULL, },
90 };
91 
92 /*
93  * init_cpu_topology is called at boot when only one cpu is running
94  * which prevent simultaneous write access to cpu_topology array
95  */
96 void __init init_cpu_topology(void)
97 {
98 	/* Set scheduler topology descriptor */
99 	if (dualcores_found)
100 		set_sched_topology(parisc_mc_topology);
101 }
102