1 /* 2 * processor_thermal.c - Passive cooling submodule of the ACPI processor driver 3 * 4 * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com> 5 * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com> 6 * Copyright (C) 2004 Dominik Brodowski <linux@brodo.de> 7 * Copyright (C) 2004 Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com> 8 * - Added processor hotplug support 9 * 10 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 11 * 12 * This program is free software; you can redistribute it and/or modify 13 * it under the terms of the GNU General Public License as published by 14 * the Free Software Foundation; either version 2 of the License, or (at 15 * your option) any later version. 16 * 17 * This program is distributed in the hope that it will be useful, but 18 * WITHOUT ANY WARRANTY; without even the implied warranty of 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 20 * General Public License for more details. 21 * 22 * You should have received a copy of the GNU General Public License along 23 * with this program; if not, write to the Free Software Foundation, Inc., 24 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 25 * 26 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 27 */ 28 29 #include <linux/kernel.h> 30 #include <linux/module.h> 31 #include <linux/init.h> 32 #include <linux/cpufreq.h> 33 #include <linux/proc_fs.h> 34 #include <linux/seq_file.h> 35 #include <linux/sysdev.h> 36 37 #include <asm/uaccess.h> 38 39 #include <acpi/acpi_bus.h> 40 #include <acpi/processor.h> 41 #include <acpi/acpi_drivers.h> 42 43 #define PREFIX "ACPI: " 44 45 #define ACPI_PROCESSOR_CLASS "processor" 46 #define _COMPONENT ACPI_PROCESSOR_COMPONENT 47 ACPI_MODULE_NAME("processor_thermal"); 48 49 /* -------------------------------------------------------------------------- 50 Limit Interface 51 -------------------------------------------------------------------------- */ 52 static int acpi_processor_apply_limit(struct acpi_processor *pr) 53 { 54 int result = 0; 55 u16 px = 0; 56 u16 tx = 0; 57 58 59 if (!pr) 60 return -EINVAL; 61 62 if (!pr->flags.limit) 63 return -ENODEV; 64 65 if (pr->flags.throttling) { 66 if (pr->limit.user.tx > tx) 67 tx = pr->limit.user.tx; 68 if (pr->limit.thermal.tx > tx) 69 tx = pr->limit.thermal.tx; 70 71 result = acpi_processor_set_throttling(pr, tx, false); 72 if (result) 73 goto end; 74 } 75 76 pr->limit.state.px = px; 77 pr->limit.state.tx = tx; 78 79 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 80 "Processor [%d] limit set to (P%d:T%d)\n", pr->id, 81 pr->limit.state.px, pr->limit.state.tx)); 82 83 end: 84 if (result) 85 printk(KERN_ERR PREFIX "Unable to set limit\n"); 86 87 return result; 88 } 89 90 #ifdef CONFIG_CPU_FREQ 91 92 /* If a passive cooling situation is detected, primarily CPUfreq is used, as it 93 * offers (in most cases) voltage scaling in addition to frequency scaling, and 94 * thus a cubic (instead of linear) reduction of energy. Also, we allow for 95 * _any_ cpufreq driver and not only the acpi-cpufreq driver. 96 */ 97 98 #define CPUFREQ_THERMAL_MIN_STEP 0 99 #define CPUFREQ_THERMAL_MAX_STEP 3 100 101 static DEFINE_PER_CPU(unsigned int, cpufreq_thermal_reduction_pctg); 102 static unsigned int acpi_thermal_cpufreq_is_init = 0; 103 104 static int cpu_has_cpufreq(unsigned int cpu) 105 { 106 struct cpufreq_policy policy; 107 if (!acpi_thermal_cpufreq_is_init || cpufreq_get_policy(&policy, cpu)) 108 return 0; 109 return 1; 110 } 111 112 static int acpi_thermal_cpufreq_increase(unsigned int cpu) 113 { 114 if (!cpu_has_cpufreq(cpu)) 115 return -ENODEV; 116 117 if (per_cpu(cpufreq_thermal_reduction_pctg, cpu) < 118 CPUFREQ_THERMAL_MAX_STEP) { 119 per_cpu(cpufreq_thermal_reduction_pctg, cpu)++; 120 cpufreq_update_policy(cpu); 121 return 0; 122 } 123 124 return -ERANGE; 125 } 126 127 static int acpi_thermal_cpufreq_decrease(unsigned int cpu) 128 { 129 if (!cpu_has_cpufreq(cpu)) 130 return -ENODEV; 131 132 if (per_cpu(cpufreq_thermal_reduction_pctg, cpu) > 133 (CPUFREQ_THERMAL_MIN_STEP + 1)) 134 per_cpu(cpufreq_thermal_reduction_pctg, cpu)--; 135 else 136 per_cpu(cpufreq_thermal_reduction_pctg, cpu) = 0; 137 cpufreq_update_policy(cpu); 138 /* We reached max freq again and can leave passive mode */ 139 return !per_cpu(cpufreq_thermal_reduction_pctg, cpu); 140 } 141 142 static int acpi_thermal_cpufreq_notifier(struct notifier_block *nb, 143 unsigned long event, void *data) 144 { 145 struct cpufreq_policy *policy = data; 146 unsigned long max_freq = 0; 147 148 if (event != CPUFREQ_ADJUST) 149 goto out; 150 151 max_freq = ( 152 policy->cpuinfo.max_freq * 153 (100 - per_cpu(cpufreq_thermal_reduction_pctg, policy->cpu) * 20) 154 ) / 100; 155 156 cpufreq_verify_within_limits(policy, 0, max_freq); 157 158 out: 159 return 0; 160 } 161 162 static struct notifier_block acpi_thermal_cpufreq_notifier_block = { 163 .notifier_call = acpi_thermal_cpufreq_notifier, 164 }; 165 166 static int cpufreq_get_max_state(unsigned int cpu) 167 { 168 if (!cpu_has_cpufreq(cpu)) 169 return 0; 170 171 return CPUFREQ_THERMAL_MAX_STEP; 172 } 173 174 static int cpufreq_get_cur_state(unsigned int cpu) 175 { 176 if (!cpu_has_cpufreq(cpu)) 177 return 0; 178 179 return per_cpu(cpufreq_thermal_reduction_pctg, cpu); 180 } 181 182 static int cpufreq_set_cur_state(unsigned int cpu, int state) 183 { 184 if (!cpu_has_cpufreq(cpu)) 185 return 0; 186 187 per_cpu(cpufreq_thermal_reduction_pctg, cpu) = state; 188 cpufreq_update_policy(cpu); 189 return 0; 190 } 191 192 void acpi_thermal_cpufreq_init(void) 193 { 194 int i; 195 196 for (i = 0; i < nr_cpu_ids; i++) 197 if (cpu_present(i)) 198 per_cpu(cpufreq_thermal_reduction_pctg, i) = 0; 199 200 i = cpufreq_register_notifier(&acpi_thermal_cpufreq_notifier_block, 201 CPUFREQ_POLICY_NOTIFIER); 202 if (!i) 203 acpi_thermal_cpufreq_is_init = 1; 204 } 205 206 void acpi_thermal_cpufreq_exit(void) 207 { 208 if (acpi_thermal_cpufreq_is_init) 209 cpufreq_unregister_notifier 210 (&acpi_thermal_cpufreq_notifier_block, 211 CPUFREQ_POLICY_NOTIFIER); 212 213 acpi_thermal_cpufreq_is_init = 0; 214 } 215 216 #else /* ! CONFIG_CPU_FREQ */ 217 static int cpufreq_get_max_state(unsigned int cpu) 218 { 219 return 0; 220 } 221 222 static int cpufreq_get_cur_state(unsigned int cpu) 223 { 224 return 0; 225 } 226 227 static int cpufreq_set_cur_state(unsigned int cpu, int state) 228 { 229 return 0; 230 } 231 232 static int acpi_thermal_cpufreq_increase(unsigned int cpu) 233 { 234 return -ENODEV; 235 } 236 static int acpi_thermal_cpufreq_decrease(unsigned int cpu) 237 { 238 return -ENODEV; 239 } 240 241 #endif 242 243 int acpi_processor_set_thermal_limit(acpi_handle handle, int type) 244 { 245 int result = 0; 246 struct acpi_processor *pr = NULL; 247 struct acpi_device *device = NULL; 248 int tx = 0, max_tx_px = 0; 249 250 251 if ((type < ACPI_PROCESSOR_LIMIT_NONE) 252 || (type > ACPI_PROCESSOR_LIMIT_DECREMENT)) 253 return -EINVAL; 254 255 result = acpi_bus_get_device(handle, &device); 256 if (result) 257 return result; 258 259 pr = acpi_driver_data(device); 260 if (!pr) 261 return -ENODEV; 262 263 /* Thermal limits are always relative to the current Px/Tx state. */ 264 if (pr->flags.throttling) 265 pr->limit.thermal.tx = pr->throttling.state; 266 267 /* 268 * Our default policy is to only use throttling at the lowest 269 * performance state. 270 */ 271 272 tx = pr->limit.thermal.tx; 273 274 switch (type) { 275 276 case ACPI_PROCESSOR_LIMIT_NONE: 277 do { 278 result = acpi_thermal_cpufreq_decrease(pr->id); 279 } while (!result); 280 tx = 0; 281 break; 282 283 case ACPI_PROCESSOR_LIMIT_INCREMENT: 284 /* if going up: P-states first, T-states later */ 285 286 result = acpi_thermal_cpufreq_increase(pr->id); 287 if (!result) 288 goto end; 289 else if (result == -ERANGE) 290 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 291 "At maximum performance state\n")); 292 293 if (pr->flags.throttling) { 294 if (tx == (pr->throttling.state_count - 1)) 295 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 296 "At maximum throttling state\n")); 297 else 298 tx++; 299 } 300 break; 301 302 case ACPI_PROCESSOR_LIMIT_DECREMENT: 303 /* if going down: T-states first, P-states later */ 304 305 if (pr->flags.throttling) { 306 if (tx == 0) { 307 max_tx_px = 1; 308 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 309 "At minimum throttling state\n")); 310 } else { 311 tx--; 312 goto end; 313 } 314 } 315 316 result = acpi_thermal_cpufreq_decrease(pr->id); 317 if (result) { 318 /* 319 * We only could get -ERANGE, 1 or 0. 320 * In the first two cases we reached max freq again. 321 */ 322 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 323 "At minimum performance state\n")); 324 max_tx_px = 1; 325 } else 326 max_tx_px = 0; 327 328 break; 329 } 330 331 end: 332 if (pr->flags.throttling) { 333 pr->limit.thermal.px = 0; 334 pr->limit.thermal.tx = tx; 335 336 result = acpi_processor_apply_limit(pr); 337 if (result) 338 printk(KERN_ERR PREFIX "Unable to set thermal limit\n"); 339 340 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Thermal limit now (P%d:T%d)\n", 341 pr->limit.thermal.px, pr->limit.thermal.tx)); 342 } else 343 result = 0; 344 if (max_tx_px) 345 return 1; 346 else 347 return result; 348 } 349 350 int acpi_processor_get_limit_info(struct acpi_processor *pr) 351 { 352 353 if (!pr) 354 return -EINVAL; 355 356 if (pr->flags.throttling) 357 pr->flags.limit = 1; 358 359 return 0; 360 } 361 362 /* thermal coolign device callbacks */ 363 static int acpi_processor_max_state(struct acpi_processor *pr) 364 { 365 int max_state = 0; 366 367 /* 368 * There exists four states according to 369 * cpufreq_thermal_reduction_ptg. 0, 1, 2, 3 370 */ 371 max_state += cpufreq_get_max_state(pr->id); 372 if (pr->flags.throttling) 373 max_state += (pr->throttling.state_count -1); 374 375 return max_state; 376 } 377 static int 378 processor_get_max_state(struct thermal_cooling_device *cdev, 379 unsigned long *state) 380 { 381 struct acpi_device *device = cdev->devdata; 382 struct acpi_processor *pr = acpi_driver_data(device); 383 384 if (!device || !pr) 385 return -EINVAL; 386 387 *state = acpi_processor_max_state(pr); 388 return 0; 389 } 390 391 static int 392 processor_get_cur_state(struct thermal_cooling_device *cdev, 393 unsigned long *cur_state) 394 { 395 struct acpi_device *device = cdev->devdata; 396 struct acpi_processor *pr = acpi_driver_data(device); 397 398 if (!device || !pr) 399 return -EINVAL; 400 401 *cur_state = cpufreq_get_cur_state(pr->id); 402 if (pr->flags.throttling) 403 *cur_state += pr->throttling.state; 404 return 0; 405 } 406 407 static int 408 processor_set_cur_state(struct thermal_cooling_device *cdev, 409 unsigned long state) 410 { 411 struct acpi_device *device = cdev->devdata; 412 struct acpi_processor *pr = acpi_driver_data(device); 413 int result = 0; 414 int max_pstate; 415 416 if (!device || !pr) 417 return -EINVAL; 418 419 max_pstate = cpufreq_get_max_state(pr->id); 420 421 if (state > acpi_processor_max_state(pr)) 422 return -EINVAL; 423 424 if (state <= max_pstate) { 425 if (pr->flags.throttling && pr->throttling.state) 426 result = acpi_processor_set_throttling(pr, 0, false); 427 cpufreq_set_cur_state(pr->id, state); 428 } else { 429 cpufreq_set_cur_state(pr->id, max_pstate); 430 result = acpi_processor_set_throttling(pr, 431 state - max_pstate, false); 432 } 433 return result; 434 } 435 436 struct thermal_cooling_device_ops processor_cooling_ops = { 437 .get_max_state = processor_get_max_state, 438 .get_cur_state = processor_get_cur_state, 439 .set_cur_state = processor_set_cur_state, 440 }; 441 442 /* /proc interface */ 443 #ifdef CONFIG_ACPI_PROCFS 444 static int acpi_processor_limit_seq_show(struct seq_file *seq, void *offset) 445 { 446 struct acpi_processor *pr = (struct acpi_processor *)seq->private; 447 448 449 if (!pr) 450 goto end; 451 452 if (!pr->flags.limit) { 453 seq_puts(seq, "<not supported>\n"); 454 goto end; 455 } 456 457 seq_printf(seq, "active limit: P%d:T%d\n" 458 "user limit: P%d:T%d\n" 459 "thermal limit: P%d:T%d\n", 460 pr->limit.state.px, pr->limit.state.tx, 461 pr->limit.user.px, pr->limit.user.tx, 462 pr->limit.thermal.px, pr->limit.thermal.tx); 463 464 end: 465 return 0; 466 } 467 468 static int acpi_processor_limit_open_fs(struct inode *inode, struct file *file) 469 { 470 return single_open(file, acpi_processor_limit_seq_show, 471 PDE(inode)->data); 472 } 473 474 static ssize_t acpi_processor_write_limit(struct file * file, 475 const char __user * buffer, 476 size_t count, loff_t * data) 477 { 478 int result = 0; 479 struct seq_file *m = file->private_data; 480 struct acpi_processor *pr = m->private; 481 char limit_string[25] = { '\0' }; 482 int px = 0; 483 int tx = 0; 484 485 486 if (!pr || (count > sizeof(limit_string) - 1)) { 487 return -EINVAL; 488 } 489 490 if (copy_from_user(limit_string, buffer, count)) { 491 return -EFAULT; 492 } 493 494 limit_string[count] = '\0'; 495 496 if (sscanf(limit_string, "%d:%d", &px, &tx) != 2) { 497 printk(KERN_ERR PREFIX "Invalid data format\n"); 498 return -EINVAL; 499 } 500 501 if (pr->flags.throttling) { 502 if ((tx < 0) || (tx > (pr->throttling.state_count - 1))) { 503 printk(KERN_ERR PREFIX "Invalid tx\n"); 504 return -EINVAL; 505 } 506 pr->limit.user.tx = tx; 507 } 508 509 result = acpi_processor_apply_limit(pr); 510 511 return count; 512 } 513 514 const struct file_operations acpi_processor_limit_fops = { 515 .owner = THIS_MODULE, 516 .open = acpi_processor_limit_open_fs, 517 .read = seq_read, 518 .write = acpi_processor_write_limit, 519 .llseek = seq_lseek, 520 .release = single_release, 521 }; 522 #endif 523