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(cpu: &per_cpu(cpu_devices, cpuid), num: 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 | |