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 #define PREFIX "ACPI: " 21 22 #define ACPI_PROCESSOR_CLASS "processor" 23 24 #ifdef CONFIG_CPU_FREQ 25 26 /* If a passive cooling situation is detected, primarily CPUfreq is used, as it 27 * offers (in most cases) voltage scaling in addition to frequency scaling, and 28 * thus a cubic (instead of linear) reduction of energy. Also, we allow for 29 * _any_ cpufreq driver and not only the acpi-cpufreq driver. 30 */ 31 32 #define CPUFREQ_THERMAL_MIN_STEP 0 33 #define CPUFREQ_THERMAL_MAX_STEP 3 34 35 static DEFINE_PER_CPU(unsigned int, cpufreq_thermal_reduction_pctg); 36 37 #define reduction_pctg(cpu) \ 38 per_cpu(cpufreq_thermal_reduction_pctg, phys_package_first_cpu(cpu)) 39 40 /* 41 * Emulate "per package data" using per cpu data (which should really be 42 * provided elsewhere) 43 * 44 * Note we can lose a CPU on cpu hotunplug, in this case we forget the state 45 * temporarily. Fortunately that's not a big issue here (I hope) 46 */ 47 static int phys_package_first_cpu(int cpu) 48 { 49 int i; 50 int id = topology_physical_package_id(cpu); 51 52 for_each_online_cpu(i) 53 if (topology_physical_package_id(i) == id) 54 return i; 55 return 0; 56 } 57 58 static int cpu_has_cpufreq(unsigned int cpu) 59 { 60 struct cpufreq_policy policy; 61 if (!acpi_processor_cpufreq_init || cpufreq_get_policy(&policy, cpu)) 62 return 0; 63 return 1; 64 } 65 66 static int cpufreq_get_max_state(unsigned int cpu) 67 { 68 if (!cpu_has_cpufreq(cpu)) 69 return 0; 70 71 return CPUFREQ_THERMAL_MAX_STEP; 72 } 73 74 static int cpufreq_get_cur_state(unsigned int cpu) 75 { 76 if (!cpu_has_cpufreq(cpu)) 77 return 0; 78 79 return reduction_pctg(cpu); 80 } 81 82 static int cpufreq_set_cur_state(unsigned int cpu, int state) 83 { 84 struct cpufreq_policy *policy; 85 struct acpi_processor *pr; 86 unsigned long max_freq; 87 int i, ret; 88 89 if (!cpu_has_cpufreq(cpu)) 90 return 0; 91 92 reduction_pctg(cpu) = state; 93 94 /* 95 * Update all the CPUs in the same package because they all 96 * contribute to the temperature and often share the same 97 * frequency. 98 */ 99 for_each_online_cpu(i) { 100 if (topology_physical_package_id(i) != 101 topology_physical_package_id(cpu)) 102 continue; 103 104 pr = per_cpu(processors, i); 105 106 if (unlikely(!freq_qos_request_active(&pr->thermal_req))) 107 continue; 108 109 policy = cpufreq_cpu_get(i); 110 if (!policy) 111 return -EINVAL; 112 113 max_freq = (policy->cpuinfo.max_freq * (100 - reduction_pctg(i) * 20)) / 100; 114 115 cpufreq_cpu_put(policy); 116 117 ret = freq_qos_update_request(&pr->thermal_req, max_freq); 118 if (ret < 0) { 119 pr_warn("Failed to update thermal freq constraint: CPU%d (%d)\n", 120 pr->id, ret); 121 } 122 } 123 return 0; 124 } 125 126 void acpi_thermal_cpufreq_init(struct cpufreq_policy *policy) 127 { 128 unsigned int cpu; 129 130 for_each_cpu(cpu, policy->related_cpus) { 131 struct acpi_processor *pr = per_cpu(processors, cpu); 132 int ret; 133 134 if (!pr) 135 continue; 136 137 ret = freq_qos_add_request(&policy->constraints, 138 &pr->thermal_req, 139 FREQ_QOS_MAX, INT_MAX); 140 if (ret < 0) 141 pr_err("Failed to add freq constraint for CPU%d (%d)\n", 142 cpu, ret); 143 } 144 } 145 146 void acpi_thermal_cpufreq_exit(struct cpufreq_policy *policy) 147 { 148 unsigned int cpu; 149 150 for_each_cpu(cpu, policy->related_cpus) { 151 struct acpi_processor *pr = per_cpu(processors, policy->cpu); 152 153 if (pr) 154 freq_qos_remove_request(&pr->thermal_req); 155 } 156 } 157 #else /* ! CONFIG_CPU_FREQ */ 158 static int cpufreq_get_max_state(unsigned int cpu) 159 { 160 return 0; 161 } 162 163 static int cpufreq_get_cur_state(unsigned int cpu) 164 { 165 return 0; 166 } 167 168 static int cpufreq_set_cur_state(unsigned int cpu, int state) 169 { 170 return 0; 171 } 172 173 #endif 174 175 /* thermal cooling device callbacks */ 176 static int acpi_processor_max_state(struct acpi_processor *pr) 177 { 178 int max_state = 0; 179 180 /* 181 * There exists four states according to 182 * cpufreq_thermal_reduction_pctg. 0, 1, 2, 3 183 */ 184 max_state += cpufreq_get_max_state(pr->id); 185 if (pr->flags.throttling) 186 max_state += (pr->throttling.state_count -1); 187 188 return max_state; 189 } 190 static int 191 processor_get_max_state(struct thermal_cooling_device *cdev, 192 unsigned long *state) 193 { 194 struct acpi_device *device = cdev->devdata; 195 struct acpi_processor *pr; 196 197 if (!device) 198 return -EINVAL; 199 200 pr = acpi_driver_data(device); 201 if (!pr) 202 return -EINVAL; 203 204 *state = acpi_processor_max_state(pr); 205 return 0; 206 } 207 208 static int 209 processor_get_cur_state(struct thermal_cooling_device *cdev, 210 unsigned long *cur_state) 211 { 212 struct acpi_device *device = cdev->devdata; 213 struct acpi_processor *pr; 214 215 if (!device) 216 return -EINVAL; 217 218 pr = acpi_driver_data(device); 219 if (!pr) 220 return -EINVAL; 221 222 *cur_state = cpufreq_get_cur_state(pr->id); 223 if (pr->flags.throttling) 224 *cur_state += pr->throttling.state; 225 return 0; 226 } 227 228 static int 229 processor_set_cur_state(struct thermal_cooling_device *cdev, 230 unsigned long state) 231 { 232 struct acpi_device *device = cdev->devdata; 233 struct acpi_processor *pr; 234 int result = 0; 235 int max_pstate; 236 237 if (!device) 238 return -EINVAL; 239 240 pr = acpi_driver_data(device); 241 if (!pr) 242 return -EINVAL; 243 244 max_pstate = cpufreq_get_max_state(pr->id); 245 246 if (state > acpi_processor_max_state(pr)) 247 return -EINVAL; 248 249 if (state <= max_pstate) { 250 if (pr->flags.throttling && pr->throttling.state) 251 result = acpi_processor_set_throttling(pr, 0, false); 252 cpufreq_set_cur_state(pr->id, state); 253 } else { 254 cpufreq_set_cur_state(pr->id, max_pstate); 255 result = acpi_processor_set_throttling(pr, 256 state - max_pstate, false); 257 } 258 return result; 259 } 260 261 const struct thermal_cooling_device_ops processor_cooling_ops = { 262 .get_max_state = processor_get_max_state, 263 .get_cur_state = processor_get_cur_state, 264 .set_cur_state = processor_set_cur_state, 265 }; 266