0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include <linux/kernel.h>
0013 #include <linux/module.h>
0014 #include <linux/init.h>
0015 #include <linux/cpufreq.h>
0016 #include <linux/acpi.h>
0017 #include <acpi/processor.h>
0018 #include <linux/uaccess.h>
0019
0020 #ifdef CONFIG_CPU_FREQ
0021
0022
0023
0024
0025
0026
0027
0028 #define CPUFREQ_THERMAL_MIN_STEP 0
0029 #define CPUFREQ_THERMAL_MAX_STEP 3
0030
0031 static DEFINE_PER_CPU(unsigned int, cpufreq_thermal_reduction_pctg);
0032
0033 #define reduction_pctg(cpu) \
0034 per_cpu(cpufreq_thermal_reduction_pctg, phys_package_first_cpu(cpu))
0035
0036
0037
0038
0039
0040
0041
0042
0043 static int phys_package_first_cpu(int cpu)
0044 {
0045 int i;
0046 int id = topology_physical_package_id(cpu);
0047
0048 for_each_online_cpu(i)
0049 if (topology_physical_package_id(i) == id)
0050 return i;
0051 return 0;
0052 }
0053
0054 static int cpu_has_cpufreq(unsigned int cpu)
0055 {
0056 struct cpufreq_policy *policy;
0057
0058 if (!acpi_processor_cpufreq_init)
0059 return 0;
0060
0061 policy = cpufreq_cpu_get(cpu);
0062 if (policy) {
0063 cpufreq_cpu_put(policy);
0064 return 1;
0065 }
0066 return 0;
0067 }
0068
0069 static int cpufreq_get_max_state(unsigned int cpu)
0070 {
0071 if (!cpu_has_cpufreq(cpu))
0072 return 0;
0073
0074 return CPUFREQ_THERMAL_MAX_STEP;
0075 }
0076
0077 static int cpufreq_get_cur_state(unsigned int cpu)
0078 {
0079 if (!cpu_has_cpufreq(cpu))
0080 return 0;
0081
0082 return reduction_pctg(cpu);
0083 }
0084
0085 static int cpufreq_set_cur_state(unsigned int cpu, int state)
0086 {
0087 struct cpufreq_policy *policy;
0088 struct acpi_processor *pr;
0089 unsigned long max_freq;
0090 int i, ret;
0091
0092 if (!cpu_has_cpufreq(cpu))
0093 return 0;
0094
0095 reduction_pctg(cpu) = state;
0096
0097
0098
0099
0100
0101
0102 for_each_online_cpu(i) {
0103 if (topology_physical_package_id(i) !=
0104 topology_physical_package_id(cpu))
0105 continue;
0106
0107 pr = per_cpu(processors, i);
0108
0109 if (unlikely(!freq_qos_request_active(&pr->thermal_req)))
0110 continue;
0111
0112 policy = cpufreq_cpu_get(i);
0113 if (!policy)
0114 return -EINVAL;
0115
0116 max_freq = (policy->cpuinfo.max_freq * (100 - reduction_pctg(i) * 20)) / 100;
0117
0118 cpufreq_cpu_put(policy);
0119
0120 ret = freq_qos_update_request(&pr->thermal_req, max_freq);
0121 if (ret < 0) {
0122 pr_warn("Failed to update thermal freq constraint: CPU%d (%d)\n",
0123 pr->id, ret);
0124 }
0125 }
0126 return 0;
0127 }
0128
0129 void acpi_thermal_cpufreq_init(struct cpufreq_policy *policy)
0130 {
0131 unsigned int cpu;
0132
0133 for_each_cpu(cpu, policy->related_cpus) {
0134 struct acpi_processor *pr = per_cpu(processors, cpu);
0135 int ret;
0136
0137 if (!pr)
0138 continue;
0139
0140 ret = freq_qos_add_request(&policy->constraints,
0141 &pr->thermal_req,
0142 FREQ_QOS_MAX, INT_MAX);
0143 if (ret < 0)
0144 pr_err("Failed to add freq constraint for CPU%d (%d)\n",
0145 cpu, ret);
0146 }
0147 }
0148
0149 void acpi_thermal_cpufreq_exit(struct cpufreq_policy *policy)
0150 {
0151 unsigned int cpu;
0152
0153 for_each_cpu(cpu, policy->related_cpus) {
0154 struct acpi_processor *pr = per_cpu(processors, cpu);
0155
0156 if (pr)
0157 freq_qos_remove_request(&pr->thermal_req);
0158 }
0159 }
0160 #else
0161 static int cpufreq_get_max_state(unsigned int cpu)
0162 {
0163 return 0;
0164 }
0165
0166 static int cpufreq_get_cur_state(unsigned int cpu)
0167 {
0168 return 0;
0169 }
0170
0171 static int cpufreq_set_cur_state(unsigned int cpu, int state)
0172 {
0173 return 0;
0174 }
0175
0176 #endif
0177
0178
0179 static int acpi_processor_max_state(struct acpi_processor *pr)
0180 {
0181 int max_state = 0;
0182
0183
0184
0185
0186
0187 max_state += cpufreq_get_max_state(pr->id);
0188 if (pr->flags.throttling)
0189 max_state += (pr->throttling.state_count -1);
0190
0191 return max_state;
0192 }
0193 static int
0194 processor_get_max_state(struct thermal_cooling_device *cdev,
0195 unsigned long *state)
0196 {
0197 struct acpi_device *device = cdev->devdata;
0198 struct acpi_processor *pr;
0199
0200 if (!device)
0201 return -EINVAL;
0202
0203 pr = acpi_driver_data(device);
0204 if (!pr)
0205 return -EINVAL;
0206
0207 *state = acpi_processor_max_state(pr);
0208 return 0;
0209 }
0210
0211 static int
0212 processor_get_cur_state(struct thermal_cooling_device *cdev,
0213 unsigned long *cur_state)
0214 {
0215 struct acpi_device *device = cdev->devdata;
0216 struct acpi_processor *pr;
0217
0218 if (!device)
0219 return -EINVAL;
0220
0221 pr = acpi_driver_data(device);
0222 if (!pr)
0223 return -EINVAL;
0224
0225 *cur_state = cpufreq_get_cur_state(pr->id);
0226 if (pr->flags.throttling)
0227 *cur_state += pr->throttling.state;
0228 return 0;
0229 }
0230
0231 static int
0232 processor_set_cur_state(struct thermal_cooling_device *cdev,
0233 unsigned long state)
0234 {
0235 struct acpi_device *device = cdev->devdata;
0236 struct acpi_processor *pr;
0237 int result = 0;
0238 int max_pstate;
0239
0240 if (!device)
0241 return -EINVAL;
0242
0243 pr = acpi_driver_data(device);
0244 if (!pr)
0245 return -EINVAL;
0246
0247 max_pstate = cpufreq_get_max_state(pr->id);
0248
0249 if (state > acpi_processor_max_state(pr))
0250 return -EINVAL;
0251
0252 if (state <= max_pstate) {
0253 if (pr->flags.throttling && pr->throttling.state)
0254 result = acpi_processor_set_throttling(pr, 0, false);
0255 cpufreq_set_cur_state(pr->id, state);
0256 } else {
0257 cpufreq_set_cur_state(pr->id, max_pstate);
0258 result = acpi_processor_set_throttling(pr,
0259 state - max_pstate, false);
0260 }
0261 return result;
0262 }
0263
0264 const struct thermal_cooling_device_ops processor_cooling_ops = {
0265 .get_max_state = processor_get_max_state,
0266 .get_cur_state = processor_get_cur_state,
0267 .set_cur_state = processor_set_cur_state,
0268 };
0269
0270 int acpi_processor_thermal_init(struct acpi_processor *pr,
0271 struct acpi_device *device)
0272 {
0273 int result = 0;
0274
0275 pr->cdev = thermal_cooling_device_register("Processor", device,
0276 &processor_cooling_ops);
0277 if (IS_ERR(pr->cdev)) {
0278 result = PTR_ERR(pr->cdev);
0279 return result;
0280 }
0281
0282 dev_dbg(&device->dev, "registered as cooling_device%d\n",
0283 pr->cdev->id);
0284
0285 result = sysfs_create_link(&device->dev.kobj,
0286 &pr->cdev->device.kobj,
0287 "thermal_cooling");
0288 if (result) {
0289 dev_err(&device->dev,
0290 "Failed to create sysfs link 'thermal_cooling'\n");
0291 goto err_thermal_unregister;
0292 }
0293
0294 result = sysfs_create_link(&pr->cdev->device.kobj,
0295 &device->dev.kobj,
0296 "device");
0297 if (result) {
0298 dev_err(&pr->cdev->device,
0299 "Failed to create sysfs link 'device'\n");
0300 goto err_remove_sysfs_thermal;
0301 }
0302
0303 return 0;
0304
0305 err_remove_sysfs_thermal:
0306 sysfs_remove_link(&device->dev.kobj, "thermal_cooling");
0307 err_thermal_unregister:
0308 thermal_cooling_device_unregister(pr->cdev);
0309
0310 return result;
0311 }
0312
0313 void acpi_processor_thermal_exit(struct acpi_processor *pr,
0314 struct acpi_device *device)
0315 {
0316 if (pr->cdev) {
0317 sysfs_remove_link(&device->dev.kobj, "thermal_cooling");
0318 sysfs_remove_link(&pr->cdev->device.kobj, "device");
0319 thermal_cooling_device_unregister(pr->cdev);
0320 pr->cdev = NULL;
0321 }
0322 }