1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * processor_thermal.c - Passive cooling submodule of the 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 */ 11 12 #include <linux/kernel.h> 13 #include <linux/module.h> 14 #include <linux/init.h> 15 #include <linux/cpufreq.h> 16 #include <linux/acpi.h> 17 #include <acpi/processor.h> 18 #include <linux/uaccess.h> 19 20 #include "internal.h" 21 22 #ifdef CONFIG_CPU_FREQ 23 24 /* If a passive cooling situation is detected, primarily CPUfreq is used, as it 25 * offers (in most cases) voltage scaling in addition to frequency scaling, and 26 * thus a cubic (instead of linear) reduction of energy. Also, we allow for 27 * _any_ cpufreq driver and not only the acpi-cpufreq driver. 28 */ 29 30 #define CPUFREQ_THERMAL_MIN_STEP 0 31 32 static int cpufreq_thermal_max_step __read_mostly = 3; 33 34 /* 35 * Minimum throttle percentage for processor_thermal cooling device. 36 * The processor_thermal driver uses it to calculate the percentage amount by 37 * which cpu frequency must be reduced for each cooling state. This is also used 38 * to calculate the maximum number of throttling steps or cooling states. 39 */ 40 static int cpufreq_thermal_reduction_pctg __read_mostly = 20; 41 42 static DEFINE_PER_CPU(unsigned int, cpufreq_thermal_reduction_step); 43 44 #define reduction_step(cpu) \ 45 per_cpu(cpufreq_thermal_reduction_step, phys_package_first_cpu(cpu)) 46 47 /* 48 * Emulate "per package data" using per cpu data (which should really be 49 * provided elsewhere) 50 * 51 * Note we can lose a CPU on cpu hotunplug, in this case we forget the state 52 * temporarily. Fortunately that's not a big issue here (I hope) 53 */ 54 static int phys_package_first_cpu(int cpu) 55 { 56 int i; 57 int id = topology_physical_package_id(cpu); 58 59 for_each_online_cpu(i) 60 if (topology_physical_package_id(i) == id) 61 return i; 62 return 0; 63 } 64 65 static bool cpu_has_cpufreq(unsigned int cpu) 66 { 67 if (!acpi_processor_cpufreq_init) 68 return 0; 69 70 struct cpufreq_policy *policy __free(put_cpufreq_policy) = cpufreq_cpu_get(cpu); 71 72 return policy != NULL; 73 } 74 75 static int cpufreq_get_max_state(unsigned int cpu) 76 { 77 if (!cpu_has_cpufreq(cpu)) 78 return 0; 79 80 return cpufreq_thermal_max_step; 81 } 82 83 static int cpufreq_get_cur_state(unsigned int cpu) 84 { 85 if (!cpu_has_cpufreq(cpu)) 86 return 0; 87 88 return reduction_step(cpu); 89 } 90 91 static bool cpufreq_update_thermal_limit(unsigned int cpu, struct acpi_processor *pr) 92 { 93 unsigned long max_freq; 94 int ret; 95 96 struct cpufreq_policy *policy __free(put_cpufreq_policy) = cpufreq_cpu_get(cpu); 97 if (!policy) 98 return false; 99 100 max_freq = (policy->cpuinfo.max_freq * 101 (100 - reduction_step(cpu) * cpufreq_thermal_reduction_pctg)) / 100; 102 103 ret = freq_qos_update_request(&pr->thermal_req, max_freq); 104 if (ret < 0) { 105 pr_warn("Failed to update thermal freq constraint: CPU%d (%d)\n", 106 pr->id, ret); 107 } 108 109 return true; 110 } 111 112 static int cpufreq_set_cur_state(unsigned int cpu, int state) 113 { 114 struct acpi_processor *pr; 115 int i; 116 117 if (!cpu_has_cpufreq(cpu)) 118 return 0; 119 120 reduction_step(cpu) = state; 121 122 /* 123 * Update all the CPUs in the same package because they all 124 * contribute to the temperature and often share the same 125 * frequency. 126 */ 127 for_each_online_cpu(i) { 128 if (topology_physical_package_id(i) != 129 topology_physical_package_id(cpu)) 130 continue; 131 132 pr = per_cpu(processors, i); 133 134 if (unlikely(!freq_qos_request_active(&pr->thermal_req))) 135 continue; 136 137 if (!cpufreq_update_thermal_limit(i, pr)) 138 return -EINVAL; 139 } 140 return 0; 141 } 142 143 static void acpi_thermal_cpufreq_config(void) 144 { 145 int cpufreq_pctg = acpi_arch_thermal_cpufreq_pctg(); 146 147 if (!cpufreq_pctg) 148 return; 149 150 cpufreq_thermal_reduction_pctg = cpufreq_pctg; 151 152 /* 153 * Derive the MAX_STEP from minimum throttle percentage so that the reduction 154 * percentage doesn't end up becoming negative. Also, cap the MAX_STEP so that 155 * the CPU performance doesn't become 0. 156 */ 157 cpufreq_thermal_max_step = (100 / cpufreq_pctg) - 2; 158 } 159 160 void acpi_thermal_cpufreq_init(struct cpufreq_policy *policy) 161 { 162 unsigned int cpu; 163 164 acpi_thermal_cpufreq_config(); 165 166 for_each_cpu(cpu, policy->related_cpus) { 167 struct acpi_processor *pr = per_cpu(processors, cpu); 168 int ret; 169 170 if (!pr) 171 continue; 172 173 ret = freq_qos_add_request(&policy->constraints, 174 &pr->thermal_req, 175 FREQ_QOS_MAX, INT_MAX); 176 if (ret < 0) { 177 pr_err("Failed to add freq constraint for CPU%d (%d)\n", 178 cpu, ret); 179 continue; 180 } 181 182 thermal_cooling_device_update(pr->cdev); 183 } 184 } 185 186 void acpi_thermal_cpufreq_exit(struct cpufreq_policy *policy) 187 { 188 unsigned int cpu; 189 190 for_each_cpu(cpu, policy->related_cpus) { 191 struct acpi_processor *pr = per_cpu(processors, cpu); 192 193 if (!pr) 194 continue; 195 196 freq_qos_remove_request(&pr->thermal_req); 197 198 thermal_cooling_device_update(pr->cdev); 199 } 200 } 201 #else /* ! CONFIG_CPU_FREQ */ 202 static int cpufreq_get_max_state(unsigned int cpu) 203 { 204 return 0; 205 } 206 207 static int cpufreq_get_cur_state(unsigned int cpu) 208 { 209 return 0; 210 } 211 212 static int cpufreq_set_cur_state(unsigned int cpu, int state) 213 { 214 return 0; 215 } 216 217 #endif 218 219 /* thermal cooling device callbacks */ 220 static int acpi_processor_max_state(struct acpi_processor *pr) 221 { 222 int max_state = 0; 223 224 /* 225 * There exists four states according to 226 * cpufreq_thermal_reduction_step. 0, 1, 2, 3 227 */ 228 max_state += cpufreq_get_max_state(pr->id); 229 if (pr->flags.throttling) 230 max_state += (pr->throttling.state_count -1); 231 232 return max_state; 233 } 234 static int 235 processor_get_max_state(struct thermal_cooling_device *cdev, 236 unsigned long *state) 237 { 238 struct acpi_device *device = cdev->devdata; 239 struct acpi_processor *pr; 240 241 if (!device) 242 return -EINVAL; 243 244 pr = acpi_driver_data(device); 245 if (!pr) 246 return -EINVAL; 247 248 *state = acpi_processor_max_state(pr); 249 return 0; 250 } 251 252 static int 253 processor_get_cur_state(struct thermal_cooling_device *cdev, 254 unsigned long *cur_state) 255 { 256 struct acpi_device *device = cdev->devdata; 257 struct acpi_processor *pr; 258 259 if (!device) 260 return -EINVAL; 261 262 pr = acpi_driver_data(device); 263 if (!pr) 264 return -EINVAL; 265 266 *cur_state = cpufreq_get_cur_state(pr->id); 267 if (pr->flags.throttling) 268 *cur_state += pr->throttling.state; 269 return 0; 270 } 271 272 static int 273 processor_set_cur_state(struct thermal_cooling_device *cdev, 274 unsigned long state) 275 { 276 struct acpi_device *device = cdev->devdata; 277 struct acpi_processor *pr; 278 int result = 0; 279 int max_pstate; 280 281 if (!device) 282 return -EINVAL; 283 284 pr = acpi_driver_data(device); 285 if (!pr) 286 return -EINVAL; 287 288 max_pstate = cpufreq_get_max_state(pr->id); 289 290 if (state > acpi_processor_max_state(pr)) 291 return -EINVAL; 292 293 if (state <= max_pstate) { 294 if (pr->flags.throttling && pr->throttling.state) 295 result = acpi_processor_set_throttling(pr, 0, false); 296 cpufreq_set_cur_state(pr->id, state); 297 } else { 298 cpufreq_set_cur_state(pr->id, max_pstate); 299 result = acpi_processor_set_throttling(pr, 300 state - max_pstate, false); 301 } 302 return result; 303 } 304 305 const struct thermal_cooling_device_ops processor_cooling_ops = { 306 .get_max_state = processor_get_max_state, 307 .get_cur_state = processor_get_cur_state, 308 .set_cur_state = processor_set_cur_state, 309 }; 310 311 int acpi_processor_thermal_init(struct acpi_processor *pr, 312 struct acpi_device *device) 313 { 314 int result = 0; 315 316 pr->cdev = thermal_cooling_device_register("Processor", device, 317 &processor_cooling_ops); 318 if (IS_ERR(pr->cdev)) { 319 result = PTR_ERR(pr->cdev); 320 return result; 321 } 322 323 dev_dbg(&device->dev, "registered as cooling_device%d\n", 324 pr->cdev->id); 325 326 result = sysfs_create_link(&device->dev.kobj, 327 &pr->cdev->device.kobj, 328 "thermal_cooling"); 329 if (result) { 330 dev_err(&device->dev, 331 "Failed to create sysfs link 'thermal_cooling'\n"); 332 goto err_thermal_unregister; 333 } 334 335 result = sysfs_create_link(&pr->cdev->device.kobj, 336 &device->dev.kobj, 337 "device"); 338 if (result) { 339 dev_err(&pr->cdev->device, 340 "Failed to create sysfs link 'device'\n"); 341 goto err_remove_sysfs_thermal; 342 } 343 344 return 0; 345 346 err_remove_sysfs_thermal: 347 sysfs_remove_link(&device->dev.kobj, "thermal_cooling"); 348 err_thermal_unregister: 349 thermal_cooling_device_unregister(pr->cdev); 350 351 return result; 352 } 353 354 void acpi_processor_thermal_exit(struct acpi_processor *pr, 355 struct acpi_device *device) 356 { 357 if (pr->cdev) { 358 sysfs_remove_link(&device->dev.kobj, "thermal_cooling"); 359 sysfs_remove_link(&pr->cdev->device.kobj, "device"); 360 thermal_cooling_device_unregister(pr->cdev); 361 pr->cdev = NULL; 362 } 363 } 364