xref: /linux/drivers/acpi/processor_driver.c (revision 6fa6b5cb60490db2591bb93872b95f72315e5f53)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * processor_driver.c - ACPI Processor Driver
4  *
5  *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
6  *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
7  *  Copyright (C) 2004       Dominik Brodowski <linux@brodo.de>
8  *  Copyright (C) 2004  Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
9  *  			- Added processor hotplug support
10  *  Copyright (C) 2013, Intel Corporation
11  *                      Rafael J. Wysocki <rafael.j.wysocki@intel.com>
12  */
13 
14 #include <linux/kernel.h>
15 #include <linux/module.h>
16 #include <linux/init.h>
17 #include <linux/cpufreq.h>
18 #include <linux/cpu.h>
19 #include <linux/cpuidle.h>
20 #include <linux/slab.h>
21 #include <linux/acpi.h>
22 
23 #include <acpi/processor.h>
24 
25 #include "internal.h"
26 
27 #define ACPI_PROCESSOR_NOTIFY_PERFORMANCE 0x80
28 #define ACPI_PROCESSOR_NOTIFY_POWER	0x81
29 #define ACPI_PROCESSOR_NOTIFY_THROTTLING	0x82
30 #define ACPI_PROCESSOR_NOTIFY_HIGEST_PERF_CHANGED	0x85
31 
32 MODULE_AUTHOR("Paul Diefenbaugh");
33 MODULE_DESCRIPTION("ACPI Processor Driver");
34 MODULE_LICENSE("GPL");
35 
36 static int acpi_processor_stop(struct device *dev);
37 
38 static const struct acpi_device_id processor_device_ids[] = {
39 	{ACPI_PROCESSOR_OBJECT_HID, 0},
40 	{ACPI_PROCESSOR_DEVICE_HID, 0},
41 	{"", 0},
42 };
43 MODULE_DEVICE_TABLE(acpi, processor_device_ids);
44 
45 static struct device_driver acpi_processor_driver = {
46 	.name = "processor",
47 	.bus = &cpu_subsys,
48 	.acpi_match_table = processor_device_ids,
49 	.remove = acpi_processor_stop,
50 };
51 
52 static void acpi_processor_notify(acpi_handle handle, u32 event, void *data)
53 {
54 	struct acpi_device *device = data;
55 	struct acpi_processor *pr;
56 	int saved, ev_data = 0;
57 
58 	if (device->handle != handle)
59 		return;
60 
61 	pr = acpi_driver_data(device);
62 	if (!pr)
63 		return;
64 
65 	switch (event) {
66 	case ACPI_PROCESSOR_NOTIFY_PERFORMANCE:
67 		saved = pr->performance_platform_limit;
68 		acpi_processor_ppc_has_changed(pr, 1);
69 		ev_data = pr->performance_platform_limit;
70 		if (saved == ev_data)
71 			return;
72 
73 		break;
74 	case ACPI_PROCESSOR_NOTIFY_POWER:
75 		acpi_processor_power_state_has_changed(pr);
76 		break;
77 	case ACPI_PROCESSOR_NOTIFY_THROTTLING:
78 		acpi_processor_tstate_has_changed(pr);
79 		break;
80 	case ACPI_PROCESSOR_NOTIFY_HIGEST_PERF_CHANGED:
81 		cpufreq_update_limits(pr->id);
82 		break;
83 	default:
84 		acpi_handle_debug(handle, "Unsupported event [0x%x]\n", event);
85 		return;
86 	}
87 
88 	acpi_bus_generate_netlink_event("processor", dev_name(&device->dev),
89 					event, ev_data);
90 }
91 
92 static int __acpi_processor_start(struct acpi_device *device);
93 
94 static int acpi_soft_cpu_online(unsigned int cpu)
95 {
96 	struct acpi_processor *pr = per_cpu(processors, cpu);
97 	struct acpi_device *device;
98 
99 	if (!pr)
100 		return 0;
101 
102 	device = acpi_fetch_acpi_dev(pr->handle);
103 	if (!device)
104 		return 0;
105 
106 	/*
107 	 * CPU got physically hotplugged and onlined for the first time:
108 	 * Initialize missing things.
109 	 */
110 	if (!pr->flags.previously_online) {
111 		int ret;
112 
113 		ret = __acpi_processor_start(device);
114 		WARN(ret, "Failed to start CPU: %d\n", pr->id);
115 	} else {
116 		/* Normal CPU soft online event. */
117 		acpi_processor_ppc_has_changed(pr, 0);
118 		acpi_processor_hotplug(pr);
119 		acpi_processor_reevaluate_tstate(pr, false);
120 		acpi_processor_tstate_has_changed(pr);
121 	}
122 	return 0;
123 }
124 
125 static int acpi_soft_cpu_dead(unsigned int cpu)
126 {
127 	struct acpi_processor *pr = per_cpu(processors, cpu);
128 
129 	if (!pr || !acpi_fetch_acpi_dev(pr->handle))
130 		return 0;
131 
132 	acpi_processor_reevaluate_tstate(pr, true);
133 	return 0;
134 }
135 
136 #ifdef CONFIG_ACPI_CPU_FREQ_PSS
137 static void acpi_pss_perf_init(struct acpi_processor *pr)
138 {
139 	acpi_processor_ppc_has_changed(pr, 0);
140 
141 	acpi_processor_get_throttling_info(pr);
142 
143 	if (pr->flags.throttling)
144 		pr->flags.limit = 1;
145 }
146 #else
147 static inline void acpi_pss_perf_init(struct acpi_processor *pr) {}
148 #endif /* CONFIG_ACPI_CPU_FREQ_PSS */
149 
150 static int __acpi_processor_start(struct acpi_device *device)
151 {
152 	struct acpi_processor *pr = acpi_driver_data(device);
153 	acpi_status status;
154 	int result = 0;
155 
156 	if (!pr)
157 		return -ENODEV;
158 
159 	result = acpi_cppc_processor_probe(pr);
160 	if (result && !IS_ENABLED(CONFIG_ACPI_CPU_FREQ_PSS))
161 		dev_dbg(&device->dev, "CPPC data invalid or not present\n");
162 
163 	acpi_processor_power_init(pr);
164 
165 	acpi_pss_perf_init(pr);
166 
167 	result = acpi_processor_thermal_init(pr, device);
168 	if (result)
169 		goto err_power_exit;
170 
171 	status = acpi_install_notify_handler(device->handle, ACPI_DEVICE_NOTIFY,
172 					     acpi_processor_notify, device);
173 	if (!ACPI_SUCCESS(status)) {
174 		result = -ENODEV;
175 		goto err_thermal_exit;
176 	}
177 	pr->flags.previously_online = 1;
178 
179 	return 0;
180 
181 err_thermal_exit:
182 	acpi_processor_thermal_exit(pr, device);
183 err_power_exit:
184 	acpi_processor_power_exit(pr);
185 	return result;
186 }
187 
188 static int acpi_processor_stop(struct device *dev)
189 {
190 	struct acpi_device *device = ACPI_COMPANION(dev);
191 	struct acpi_processor *pr;
192 
193 	if (!device)
194 		return 0;
195 
196 	acpi_remove_notify_handler(device->handle, ACPI_DEVICE_NOTIFY,
197 				   acpi_processor_notify);
198 
199 	pr = acpi_driver_data(device);
200 	if (!pr)
201 		return 0;
202 	acpi_processor_power_exit(pr);
203 
204 	acpi_cppc_processor_exit(pr);
205 
206 	acpi_processor_thermal_exit(pr, device);
207 
208 	return 0;
209 }
210 
211 bool acpi_processor_cpufreq_init;
212 
213 static int acpi_processor_notifier(struct notifier_block *nb,
214 				   unsigned long event, void *data)
215 {
216 	struct cpufreq_policy *policy = data;
217 
218 	if (event == CPUFREQ_CREATE_POLICY) {
219 		acpi_thermal_cpufreq_init(policy);
220 		acpi_processor_ppc_init(policy);
221 	} else if (event == CPUFREQ_REMOVE_POLICY) {
222 		acpi_processor_ppc_exit(policy);
223 		acpi_thermal_cpufreq_exit(policy);
224 	}
225 
226 	return 0;
227 }
228 
229 static struct notifier_block acpi_processor_notifier_block = {
230 	.notifier_call = acpi_processor_notifier,
231 };
232 
233 void __weak acpi_processor_init_invariance_cppc(void)
234 { }
235 
236 /*
237  * We keep the driver loaded even when ACPI is not running.
238  * This is needed for the powernow-k8 driver, that works even without
239  * ACPI, but needs symbols from this driver
240  */
241 static enum cpuhp_state hp_online;
242 static int __init acpi_processor_driver_init(void)
243 {
244 	int result = 0;
245 
246 	if (acpi_disabled)
247 		return 0;
248 
249 	if (!cpufreq_register_notifier(&acpi_processor_notifier_block,
250 				       CPUFREQ_POLICY_NOTIFIER)) {
251 		acpi_processor_cpufreq_init = true;
252 		acpi_processor_ignore_ppc_init();
253 	}
254 
255 	acpi_processor_register_idle_driver();
256 
257 	result = driver_register(&acpi_processor_driver);
258 	if (result < 0)
259 		goto unregister_idle_drv;
260 
261 	result = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN,
262 				   "acpi/cpu-drv:online",
263 				   acpi_soft_cpu_online, NULL);
264 	if (result < 0)
265 		goto err;
266 	hp_online = result;
267 	cpuhp_setup_state_nocalls(CPUHP_ACPI_CPUDRV_DEAD, "acpi/cpu-drv:dead",
268 				  NULL, acpi_soft_cpu_dead);
269 
270 	acpi_processor_throttling_init();
271 
272 	/*
273 	 * Frequency invariance calculations on AMD platforms can't be run until
274 	 * after acpi_cppc_processor_probe() has been called for all online CPUs
275 	 */
276 	acpi_processor_init_invariance_cppc();
277 
278 	acpi_idle_rescan_dead_smt_siblings();
279 
280 	return 0;
281 
282 err:
283 	driver_unregister(&acpi_processor_driver);
284 
285 unregister_idle_drv:
286 	acpi_processor_unregister_idle_driver();
287 
288 	return result;
289 }
290 
291 static void __exit acpi_processor_driver_exit(void)
292 {
293 	if (acpi_disabled)
294 		return;
295 
296 	if (acpi_processor_cpufreq_init) {
297 		cpufreq_unregister_notifier(&acpi_processor_notifier_block,
298 					    CPUFREQ_POLICY_NOTIFIER);
299 		acpi_processor_cpufreq_init = false;
300 	}
301 
302 	cpuhp_remove_state_nocalls(hp_online);
303 	cpuhp_remove_state_nocalls(CPUHP_ACPI_CPUDRV_DEAD);
304 	driver_unregister(&acpi_processor_driver);
305 	acpi_processor_unregister_idle_driver();
306 }
307 
308 module_init(acpi_processor_driver_init);
309 module_exit(acpi_processor_driver_exit);
310 
311 MODULE_ALIAS("processor");
312