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