1 /* 2 * acpi_thermal.c - ACPI Thermal Zone Driver ($Revision: 41 $) 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 * 7 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation; either version 2 of the License, or (at 12 * your option) any later version. 13 * 14 * This program is distributed in the hope that it will be useful, but 15 * WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 * General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License along 20 * with this program; if not, write to the Free Software Foundation, Inc., 21 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 22 * 23 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 24 * 25 * This driver fully implements the ACPI thermal policy as described in the 26 * ACPI 2.0 Specification. 27 * 28 * TBD: 1. Implement passive cooling hysteresis. 29 * 2. Enhance passive cooling (CPU) states/limit interface to support 30 * concepts of 'multiple limiters', upper/lower limits, etc. 31 * 32 */ 33 34 #include <linux/kernel.h> 35 #include <linux/module.h> 36 #include <linux/dmi.h> 37 #include <linux/init.h> 38 #include <linux/types.h> 39 #include <linux/proc_fs.h> 40 #include <linux/timer.h> 41 #include <linux/jiffies.h> 42 #include <linux/kmod.h> 43 #include <linux/seq_file.h> 44 #include <linux/reboot.h> 45 #include <asm/uaccess.h> 46 #include <linux/thermal.h> 47 #include <acpi/acpi_bus.h> 48 #include <acpi/acpi_drivers.h> 49 50 #define ACPI_THERMAL_COMPONENT 0x04000000 51 #define ACPI_THERMAL_CLASS "thermal_zone" 52 #define ACPI_THERMAL_DEVICE_NAME "Thermal Zone" 53 #define ACPI_THERMAL_FILE_STATE "state" 54 #define ACPI_THERMAL_FILE_TEMPERATURE "temperature" 55 #define ACPI_THERMAL_FILE_TRIP_POINTS "trip_points" 56 #define ACPI_THERMAL_FILE_COOLING_MODE "cooling_mode" 57 #define ACPI_THERMAL_FILE_POLLING_FREQ "polling_frequency" 58 #define ACPI_THERMAL_NOTIFY_TEMPERATURE 0x80 59 #define ACPI_THERMAL_NOTIFY_THRESHOLDS 0x81 60 #define ACPI_THERMAL_NOTIFY_DEVICES 0x82 61 #define ACPI_THERMAL_NOTIFY_CRITICAL 0xF0 62 #define ACPI_THERMAL_NOTIFY_HOT 0xF1 63 #define ACPI_THERMAL_MODE_ACTIVE 0x00 64 65 #define ACPI_THERMAL_MAX_ACTIVE 10 66 #define ACPI_THERMAL_MAX_LIMIT_STR_LEN 65 67 68 #define _COMPONENT ACPI_THERMAL_COMPONENT 69 ACPI_MODULE_NAME("thermal"); 70 71 MODULE_AUTHOR("Paul Diefenbaugh"); 72 MODULE_DESCRIPTION("ACPI Thermal Zone Driver"); 73 MODULE_LICENSE("GPL"); 74 75 static int act; 76 module_param(act, int, 0644); 77 MODULE_PARM_DESC(act, "Disable or override all lowest active trip points."); 78 79 static int crt; 80 module_param(crt, int, 0644); 81 MODULE_PARM_DESC(crt, "Disable or lower all critical trip points."); 82 83 static int tzp; 84 module_param(tzp, int, 0444); 85 MODULE_PARM_DESC(tzp, "Thermal zone polling frequency, in 1/10 seconds."); 86 87 static int nocrt; 88 module_param(nocrt, int, 0); 89 MODULE_PARM_DESC(nocrt, "Set to take no action upon ACPI thermal zone critical trips points."); 90 91 static int off; 92 module_param(off, int, 0); 93 MODULE_PARM_DESC(off, "Set to disable ACPI thermal support."); 94 95 static int psv; 96 module_param(psv, int, 0644); 97 MODULE_PARM_DESC(psv, "Disable or override all passive trip points."); 98 99 static int acpi_thermal_add(struct acpi_device *device); 100 static int acpi_thermal_remove(struct acpi_device *device, int type); 101 static int acpi_thermal_resume(struct acpi_device *device); 102 static int acpi_thermal_state_open_fs(struct inode *inode, struct file *file); 103 static int acpi_thermal_temp_open_fs(struct inode *inode, struct file *file); 104 static int acpi_thermal_trip_open_fs(struct inode *inode, struct file *file); 105 static int acpi_thermal_cooling_open_fs(struct inode *inode, struct file *file); 106 static ssize_t acpi_thermal_write_cooling_mode(struct file *, 107 const char __user *, size_t, 108 loff_t *); 109 static int acpi_thermal_polling_open_fs(struct inode *inode, struct file *file); 110 static ssize_t acpi_thermal_write_polling(struct file *, const char __user *, 111 size_t, loff_t *); 112 113 static const struct acpi_device_id thermal_device_ids[] = { 114 {ACPI_THERMAL_HID, 0}, 115 {"", 0}, 116 }; 117 MODULE_DEVICE_TABLE(acpi, thermal_device_ids); 118 119 static struct acpi_driver acpi_thermal_driver = { 120 .name = "thermal", 121 .class = ACPI_THERMAL_CLASS, 122 .ids = thermal_device_ids, 123 .ops = { 124 .add = acpi_thermal_add, 125 .remove = acpi_thermal_remove, 126 .resume = acpi_thermal_resume, 127 }, 128 }; 129 130 struct acpi_thermal_state { 131 u8 critical:1; 132 u8 hot:1; 133 u8 passive:1; 134 u8 active:1; 135 u8 reserved:4; 136 int active_index; 137 }; 138 139 struct acpi_thermal_state_flags { 140 u8 valid:1; 141 u8 enabled:1; 142 u8 reserved:6; 143 }; 144 145 struct acpi_thermal_critical { 146 struct acpi_thermal_state_flags flags; 147 unsigned long temperature; 148 }; 149 150 struct acpi_thermal_hot { 151 struct acpi_thermal_state_flags flags; 152 unsigned long temperature; 153 }; 154 155 struct acpi_thermal_passive { 156 struct acpi_thermal_state_flags flags; 157 unsigned long temperature; 158 unsigned long tc1; 159 unsigned long tc2; 160 unsigned long tsp; 161 struct acpi_handle_list devices; 162 }; 163 164 struct acpi_thermal_active { 165 struct acpi_thermal_state_flags flags; 166 unsigned long temperature; 167 struct acpi_handle_list devices; 168 }; 169 170 struct acpi_thermal_trips { 171 struct acpi_thermal_critical critical; 172 struct acpi_thermal_hot hot; 173 struct acpi_thermal_passive passive; 174 struct acpi_thermal_active active[ACPI_THERMAL_MAX_ACTIVE]; 175 }; 176 177 struct acpi_thermal_flags { 178 u8 cooling_mode:1; /* _SCP */ 179 u8 devices:1; /* _TZD */ 180 u8 reserved:6; 181 }; 182 183 struct acpi_thermal { 184 struct acpi_device * device; 185 acpi_bus_id name; 186 unsigned long temperature; 187 unsigned long last_temperature; 188 unsigned long polling_frequency; 189 volatile u8 zombie; 190 struct acpi_thermal_flags flags; 191 struct acpi_thermal_state state; 192 struct acpi_thermal_trips trips; 193 struct acpi_handle_list devices; 194 struct timer_list timer; 195 struct thermal_zone_device *thermal_zone; 196 int tz_enabled; 197 struct mutex lock; 198 }; 199 200 static const struct file_operations acpi_thermal_state_fops = { 201 .owner = THIS_MODULE, 202 .open = acpi_thermal_state_open_fs, 203 .read = seq_read, 204 .llseek = seq_lseek, 205 .release = single_release, 206 }; 207 208 static const struct file_operations acpi_thermal_temp_fops = { 209 .owner = THIS_MODULE, 210 .open = acpi_thermal_temp_open_fs, 211 .read = seq_read, 212 .llseek = seq_lseek, 213 .release = single_release, 214 }; 215 216 static const struct file_operations acpi_thermal_trip_fops = { 217 .owner = THIS_MODULE, 218 .open = acpi_thermal_trip_open_fs, 219 .read = seq_read, 220 .llseek = seq_lseek, 221 .release = single_release, 222 }; 223 224 static const struct file_operations acpi_thermal_cooling_fops = { 225 .owner = THIS_MODULE, 226 .open = acpi_thermal_cooling_open_fs, 227 .read = seq_read, 228 .write = acpi_thermal_write_cooling_mode, 229 .llseek = seq_lseek, 230 .release = single_release, 231 }; 232 233 static const struct file_operations acpi_thermal_polling_fops = { 234 .owner = THIS_MODULE, 235 .open = acpi_thermal_polling_open_fs, 236 .read = seq_read, 237 .write = acpi_thermal_write_polling, 238 .llseek = seq_lseek, 239 .release = single_release, 240 }; 241 242 /* -------------------------------------------------------------------------- 243 Thermal Zone Management 244 -------------------------------------------------------------------------- */ 245 246 static int acpi_thermal_get_temperature(struct acpi_thermal *tz) 247 { 248 acpi_status status = AE_OK; 249 250 251 if (!tz) 252 return -EINVAL; 253 254 tz->last_temperature = tz->temperature; 255 256 status = 257 acpi_evaluate_integer(tz->device->handle, "_TMP", NULL, &tz->temperature); 258 if (ACPI_FAILURE(status)) 259 return -ENODEV; 260 261 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Temperature is %lu dK\n", 262 tz->temperature)); 263 264 return 0; 265 } 266 267 static int acpi_thermal_get_polling_frequency(struct acpi_thermal *tz) 268 { 269 acpi_status status = AE_OK; 270 271 272 if (!tz) 273 return -EINVAL; 274 275 status = 276 acpi_evaluate_integer(tz->device->handle, "_TZP", NULL, 277 &tz->polling_frequency); 278 if (ACPI_FAILURE(status)) 279 return -ENODEV; 280 281 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Polling frequency is %lu dS\n", 282 tz->polling_frequency)); 283 284 return 0; 285 } 286 287 static int acpi_thermal_set_polling(struct acpi_thermal *tz, int seconds) 288 { 289 290 if (!tz) 291 return -EINVAL; 292 293 tz->polling_frequency = seconds * 10; /* Convert value to deci-seconds */ 294 295 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 296 "Polling frequency set to %lu seconds\n", 297 tz->polling_frequency/10)); 298 299 return 0; 300 } 301 302 static int acpi_thermal_set_cooling_mode(struct acpi_thermal *tz, int mode) 303 { 304 acpi_status status = AE_OK; 305 union acpi_object arg0 = { ACPI_TYPE_INTEGER }; 306 struct acpi_object_list arg_list = { 1, &arg0 }; 307 acpi_handle handle = NULL; 308 309 310 if (!tz) 311 return -EINVAL; 312 313 status = acpi_get_handle(tz->device->handle, "_SCP", &handle); 314 if (ACPI_FAILURE(status)) { 315 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "_SCP not present\n")); 316 return -ENODEV; 317 } 318 319 arg0.integer.value = mode; 320 321 status = acpi_evaluate_object(handle, NULL, &arg_list, NULL); 322 if (ACPI_FAILURE(status)) 323 return -ENODEV; 324 325 return 0; 326 } 327 328 #define ACPI_TRIPS_CRITICAL 0x01 329 #define ACPI_TRIPS_HOT 0x02 330 #define ACPI_TRIPS_PASSIVE 0x04 331 #define ACPI_TRIPS_ACTIVE 0x08 332 #define ACPI_TRIPS_DEVICES 0x10 333 334 #define ACPI_TRIPS_REFRESH_THRESHOLDS (ACPI_TRIPS_PASSIVE | ACPI_TRIPS_ACTIVE) 335 #define ACPI_TRIPS_REFRESH_DEVICES ACPI_TRIPS_DEVICES 336 337 #define ACPI_TRIPS_INIT (ACPI_TRIPS_CRITICAL | ACPI_TRIPS_HOT | \ 338 ACPI_TRIPS_PASSIVE | ACPI_TRIPS_ACTIVE | \ 339 ACPI_TRIPS_DEVICES) 340 341 /* 342 * This exception is thrown out in two cases: 343 * 1.An invalid trip point becomes invalid or a valid trip point becomes invalid 344 * when re-evaluating the AML code. 345 * 2.TODO: Devices listed in _PSL, _ALx, _TZD may change. 346 * We need to re-bind the cooling devices of a thermal zone when this occurs. 347 */ 348 #define ACPI_THERMAL_TRIPS_EXCEPTION(flags, str) \ 349 do { \ 350 if (flags != ACPI_TRIPS_INIT) \ 351 ACPI_EXCEPTION((AE_INFO, AE_ERROR, \ 352 "ACPI thermal trip point %s changed\n" \ 353 "Please send acpidump to linux-acpi@vger.kernel.org\n", str)); \ 354 } while (0) 355 356 static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag) 357 { 358 acpi_status status = AE_OK; 359 struct acpi_handle_list devices; 360 int valid = 0; 361 int i; 362 363 /* Critical Shutdown (required) */ 364 if (flag & ACPI_TRIPS_CRITICAL) { 365 status = acpi_evaluate_integer(tz->device->handle, 366 "_CRT", NULL, &tz->trips.critical.temperature); 367 /* 368 * Treat freezing temperatures as invalid as well; some 369 * BIOSes return really low values and cause reboots at startup. 370 * Below zero (Celcius) values clearly aren't right for sure.. 371 * ... so lets discard those as invalid. 372 */ 373 if (ACPI_FAILURE(status) || 374 tz->trips.critical.temperature <= 2732) { 375 tz->trips.critical.flags.valid = 0; 376 ACPI_EXCEPTION((AE_INFO, status, 377 "No or invalid critical threshold")); 378 return -ENODEV; 379 } else { 380 tz->trips.critical.flags.valid = 1; 381 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 382 "Found critical threshold [%lu]\n", 383 tz->trips.critical.temperature)); 384 } 385 if (tz->trips.critical.flags.valid == 1) { 386 if (crt == -1) { 387 tz->trips.critical.flags.valid = 0; 388 } else if (crt > 0) { 389 unsigned long crt_k = CELSIUS_TO_KELVIN(crt); 390 /* 391 * Allow override to lower critical threshold 392 */ 393 if (crt_k < tz->trips.critical.temperature) 394 tz->trips.critical.temperature = crt_k; 395 } 396 } 397 } 398 399 /* Critical Sleep (optional) */ 400 if (flag & ACPI_TRIPS_HOT) { 401 status = acpi_evaluate_integer(tz->device->handle, 402 "_HOT", NULL, &tz->trips.hot.temperature); 403 if (ACPI_FAILURE(status)) { 404 tz->trips.hot.flags.valid = 0; 405 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 406 "No hot threshold\n")); 407 } else { 408 tz->trips.hot.flags.valid = 1; 409 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 410 "Found hot threshold [%lu]\n", 411 tz->trips.critical.temperature)); 412 } 413 } 414 415 /* Passive (optional) */ 416 if (flag & ACPI_TRIPS_PASSIVE) { 417 valid = tz->trips.passive.flags.valid; 418 if (psv == -1) { 419 status = AE_SUPPORT; 420 } else if (psv > 0) { 421 tz->trips.passive.temperature = CELSIUS_TO_KELVIN(psv); 422 status = AE_OK; 423 } else { 424 status = acpi_evaluate_integer(tz->device->handle, 425 "_PSV", NULL, &tz->trips.passive.temperature); 426 } 427 428 if (ACPI_FAILURE(status)) 429 tz->trips.passive.flags.valid = 0; 430 else { 431 tz->trips.passive.flags.valid = 1; 432 if (flag == ACPI_TRIPS_INIT) { 433 status = acpi_evaluate_integer( 434 tz->device->handle, "_TC1", 435 NULL, &tz->trips.passive.tc1); 436 if (ACPI_FAILURE(status)) 437 tz->trips.passive.flags.valid = 0; 438 status = acpi_evaluate_integer( 439 tz->device->handle, "_TC2", 440 NULL, &tz->trips.passive.tc2); 441 if (ACPI_FAILURE(status)) 442 tz->trips.passive.flags.valid = 0; 443 status = acpi_evaluate_integer( 444 tz->device->handle, "_TSP", 445 NULL, &tz->trips.passive.tsp); 446 if (ACPI_FAILURE(status)) 447 tz->trips.passive.flags.valid = 0; 448 } 449 } 450 } 451 if ((flag & ACPI_TRIPS_DEVICES) && tz->trips.passive.flags.valid) { 452 memset(&devices, 0, sizeof(struct acpi_handle_list)); 453 status = acpi_evaluate_reference(tz->device->handle, "_PSL", 454 NULL, &devices); 455 if (ACPI_FAILURE(status)) 456 tz->trips.passive.flags.valid = 0; 457 else 458 tz->trips.passive.flags.valid = 1; 459 460 if (memcmp(&tz->trips.passive.devices, &devices, 461 sizeof(struct acpi_handle_list))) { 462 memcpy(&tz->trips.passive.devices, &devices, 463 sizeof(struct acpi_handle_list)); 464 ACPI_THERMAL_TRIPS_EXCEPTION(flag, "device"); 465 } 466 } 467 if ((flag & ACPI_TRIPS_PASSIVE) || (flag & ACPI_TRIPS_DEVICES)) { 468 if (valid != tz->trips.passive.flags.valid) 469 ACPI_THERMAL_TRIPS_EXCEPTION(flag, "state"); 470 } 471 472 /* Active (optional) */ 473 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { 474 char name[5] = { '_', 'A', 'C', ('0' + i), '\0' }; 475 valid = tz->trips.active[i].flags.valid; 476 477 if (act == -1) 478 break; /* disable all active trip points */ 479 480 if (flag & ACPI_TRIPS_ACTIVE) { 481 status = acpi_evaluate_integer(tz->device->handle, 482 name, NULL, &tz->trips.active[i].temperature); 483 if (ACPI_FAILURE(status)) { 484 tz->trips.active[i].flags.valid = 0; 485 if (i == 0) 486 break; 487 if (act <= 0) 488 break; 489 if (i == 1) 490 tz->trips.active[0].temperature = 491 CELSIUS_TO_KELVIN(act); 492 else 493 /* 494 * Don't allow override higher than 495 * the next higher trip point 496 */ 497 tz->trips.active[i - 1].temperature = 498 (tz->trips.active[i - 2].temperature < 499 CELSIUS_TO_KELVIN(act) ? 500 tz->trips.active[i - 2].temperature : 501 CELSIUS_TO_KELVIN(act)); 502 break; 503 } else 504 tz->trips.active[i].flags.valid = 1; 505 } 506 507 name[2] = 'L'; 508 if ((flag & ACPI_TRIPS_DEVICES) && tz->trips.active[i].flags.valid ) { 509 memset(&devices, 0, sizeof(struct acpi_handle_list)); 510 status = acpi_evaluate_reference(tz->device->handle, 511 name, NULL, &devices); 512 if (ACPI_FAILURE(status)) 513 tz->trips.active[i].flags.valid = 0; 514 else 515 tz->trips.active[i].flags.valid = 1; 516 517 if (memcmp(&tz->trips.active[i].devices, &devices, 518 sizeof(struct acpi_handle_list))) { 519 memcpy(&tz->trips.active[i].devices, &devices, 520 sizeof(struct acpi_handle_list)); 521 ACPI_THERMAL_TRIPS_EXCEPTION(flag, "device"); 522 } 523 } 524 if ((flag & ACPI_TRIPS_ACTIVE) || (flag & ACPI_TRIPS_DEVICES)) 525 if (valid != tz->trips.active[i].flags.valid) 526 ACPI_THERMAL_TRIPS_EXCEPTION(flag, "state"); 527 528 if (!tz->trips.active[i].flags.valid) 529 break; 530 } 531 532 if (flag & ACPI_TRIPS_DEVICES) { 533 memset(&devices, 0, sizeof(struct acpi_handle_list)); 534 status = acpi_evaluate_reference(tz->device->handle, "_TZD", 535 NULL, &devices); 536 if (memcmp(&tz->devices, &devices, 537 sizeof(struct acpi_handle_list))) { 538 memcpy(&tz->devices, &devices, 539 sizeof(struct acpi_handle_list)); 540 ACPI_THERMAL_TRIPS_EXCEPTION(flag, "device"); 541 } 542 } 543 544 return 0; 545 } 546 547 static int acpi_thermal_get_trip_points(struct acpi_thermal *tz) 548 { 549 return acpi_thermal_trips_update(tz, ACPI_TRIPS_INIT); 550 } 551 552 static int acpi_thermal_critical(struct acpi_thermal *tz) 553 { 554 if (!tz || !tz->trips.critical.flags.valid) 555 return -EINVAL; 556 557 if (tz->temperature >= tz->trips.critical.temperature) { 558 printk(KERN_WARNING PREFIX "Critical trip point\n"); 559 tz->trips.critical.flags.enabled = 1; 560 } else if (tz->trips.critical.flags.enabled) 561 tz->trips.critical.flags.enabled = 0; 562 563 acpi_bus_generate_proc_event(tz->device, ACPI_THERMAL_NOTIFY_CRITICAL, 564 tz->trips.critical.flags.enabled); 565 acpi_bus_generate_netlink_event(tz->device->pnp.device_class, 566 tz->device->dev.bus_id, 567 ACPI_THERMAL_NOTIFY_CRITICAL, 568 tz->trips.critical.flags.enabled); 569 570 /* take no action if nocrt is set */ 571 if(!nocrt) { 572 printk(KERN_EMERG 573 "Critical temperature reached (%ld C), shutting down.\n", 574 KELVIN_TO_CELSIUS(tz->temperature)); 575 orderly_poweroff(true); 576 } 577 578 return 0; 579 } 580 581 static int acpi_thermal_hot(struct acpi_thermal *tz) 582 { 583 if (!tz || !tz->trips.hot.flags.valid) 584 return -EINVAL; 585 586 if (tz->temperature >= tz->trips.hot.temperature) { 587 printk(KERN_WARNING PREFIX "Hot trip point\n"); 588 tz->trips.hot.flags.enabled = 1; 589 } else if (tz->trips.hot.flags.enabled) 590 tz->trips.hot.flags.enabled = 0; 591 592 acpi_bus_generate_proc_event(tz->device, ACPI_THERMAL_NOTIFY_HOT, 593 tz->trips.hot.flags.enabled); 594 acpi_bus_generate_netlink_event(tz->device->pnp.device_class, 595 tz->device->dev.bus_id, 596 ACPI_THERMAL_NOTIFY_HOT, 597 tz->trips.hot.flags.enabled); 598 599 /* TBD: Call user-mode "sleep(S4)" function if nocrt is cleared */ 600 601 return 0; 602 } 603 604 static void acpi_thermal_passive(struct acpi_thermal *tz) 605 { 606 int result = 1; 607 struct acpi_thermal_passive *passive = NULL; 608 int trend = 0; 609 int i = 0; 610 611 612 if (!tz || !tz->trips.passive.flags.valid) 613 return; 614 615 passive = &(tz->trips.passive); 616 617 /* 618 * Above Trip? 619 * ----------- 620 * Calculate the thermal trend (using the passive cooling equation) 621 * and modify the performance limit for all passive cooling devices 622 * accordingly. Note that we assume symmetry. 623 */ 624 if (tz->temperature >= passive->temperature) { 625 trend = 626 (passive->tc1 * (tz->temperature - tz->last_temperature)) + 627 (passive->tc2 * (tz->temperature - passive->temperature)); 628 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 629 "trend[%d]=(tc1[%lu]*(tmp[%lu]-last[%lu]))+(tc2[%lu]*(tmp[%lu]-psv[%lu]))\n", 630 trend, passive->tc1, tz->temperature, 631 tz->last_temperature, passive->tc2, 632 tz->temperature, passive->temperature)); 633 passive->flags.enabled = 1; 634 /* Heating up? */ 635 if (trend > 0) 636 for (i = 0; i < passive->devices.count; i++) 637 acpi_processor_set_thermal_limit(passive-> 638 devices. 639 handles[i], 640 ACPI_PROCESSOR_LIMIT_INCREMENT); 641 /* Cooling off? */ 642 else if (trend < 0) { 643 for (i = 0; i < passive->devices.count; i++) 644 /* 645 * assume that we are on highest 646 * freq/lowest thrott and can leave 647 * passive mode, even in error case 648 */ 649 if (!acpi_processor_set_thermal_limit 650 (passive->devices.handles[i], 651 ACPI_PROCESSOR_LIMIT_DECREMENT)) 652 result = 0; 653 /* 654 * Leave cooling mode, even if the temp might 655 * higher than trip point This is because some 656 * machines might have long thermal polling 657 * frequencies (tsp) defined. We will fall back 658 * into passive mode in next cycle (probably quicker) 659 */ 660 if (result) { 661 passive->flags.enabled = 0; 662 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 663 "Disabling passive cooling, still above threshold," 664 " but we are cooling down\n")); 665 } 666 } 667 return; 668 } 669 670 /* 671 * Below Trip? 672 * ----------- 673 * Implement passive cooling hysteresis to slowly increase performance 674 * and avoid thrashing around the passive trip point. Note that we 675 * assume symmetry. 676 */ 677 if (!passive->flags.enabled) 678 return; 679 for (i = 0; i < passive->devices.count; i++) 680 if (!acpi_processor_set_thermal_limit 681 (passive->devices.handles[i], 682 ACPI_PROCESSOR_LIMIT_DECREMENT)) 683 result = 0; 684 if (result) { 685 passive->flags.enabled = 0; 686 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 687 "Disabling passive cooling (zone is cool)\n")); 688 } 689 } 690 691 static void acpi_thermal_active(struct acpi_thermal *tz) 692 { 693 int result = 0; 694 struct acpi_thermal_active *active = NULL; 695 int i = 0; 696 int j = 0; 697 unsigned long maxtemp = 0; 698 699 700 if (!tz) 701 return; 702 703 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { 704 active = &(tz->trips.active[i]); 705 if (!active || !active->flags.valid) 706 break; 707 if (tz->temperature >= active->temperature) { 708 /* 709 * Above Threshold? 710 * ---------------- 711 * If not already enabled, turn ON all cooling devices 712 * associated with this active threshold. 713 */ 714 if (active->temperature > maxtemp) 715 tz->state.active_index = i; 716 maxtemp = active->temperature; 717 if (active->flags.enabled) 718 continue; 719 for (j = 0; j < active->devices.count; j++) { 720 result = 721 acpi_bus_set_power(active->devices. 722 handles[j], 723 ACPI_STATE_D0); 724 if (result) { 725 printk(KERN_WARNING PREFIX 726 "Unable to turn cooling device [%p] 'on'\n", 727 active->devices. 728 handles[j]); 729 continue; 730 } 731 active->flags.enabled = 1; 732 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 733 "Cooling device [%p] now 'on'\n", 734 active->devices.handles[j])); 735 } 736 continue; 737 } 738 if (!active->flags.enabled) 739 continue; 740 /* 741 * Below Threshold? 742 * ---------------- 743 * Turn OFF all cooling devices associated with this 744 * threshold. 745 */ 746 for (j = 0; j < active->devices.count; j++) { 747 result = acpi_bus_set_power(active->devices.handles[j], 748 ACPI_STATE_D3); 749 if (result) { 750 printk(KERN_WARNING PREFIX 751 "Unable to turn cooling device [%p] 'off'\n", 752 active->devices.handles[j]); 753 continue; 754 } 755 active->flags.enabled = 0; 756 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 757 "Cooling device [%p] now 'off'\n", 758 active->devices.handles[j])); 759 } 760 } 761 } 762 763 static void acpi_thermal_check(void *context); 764 765 static void acpi_thermal_run(unsigned long data) 766 { 767 struct acpi_thermal *tz = (struct acpi_thermal *)data; 768 if (!tz->zombie) 769 acpi_os_execute(OSL_GPE_HANDLER, acpi_thermal_check, (void *)data); 770 } 771 772 static void acpi_thermal_active_off(void *data) 773 { 774 int result = 0; 775 struct acpi_thermal *tz = data; 776 int i = 0; 777 int j = 0; 778 struct acpi_thermal_active *active = NULL; 779 780 if (!tz) { 781 printk(KERN_ERR PREFIX "Invalid (NULL) context\n"); 782 return; 783 } 784 785 result = acpi_thermal_get_temperature(tz); 786 if (result) 787 return; 788 789 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { 790 active = &(tz->trips.active[i]); 791 if (!active || !active->flags.valid) 792 break; 793 if (tz->temperature >= active->temperature) { 794 /* 795 * If the thermal temperature is greater than the 796 * active threshod, unnecessary to turn off the 797 * the active cooling device. 798 */ 799 continue; 800 } 801 /* 802 * Below Threshold? 803 * ---------------- 804 * Turn OFF all cooling devices associated with this 805 * threshold. 806 */ 807 for (j = 0; j < active->devices.count; j++) 808 result = acpi_bus_set_power(active->devices.handles[j], 809 ACPI_STATE_D3); 810 } 811 } 812 813 static void acpi_thermal_check(void *data) 814 { 815 int result = 0; 816 struct acpi_thermal *tz = data; 817 unsigned long sleep_time = 0; 818 unsigned long timeout_jiffies = 0; 819 int i = 0; 820 struct acpi_thermal_state state; 821 822 823 if (!tz) { 824 printk(KERN_ERR PREFIX "Invalid (NULL) context\n"); 825 return; 826 } 827 828 /* Check if someone else is already running */ 829 if (!mutex_trylock(&tz->lock)) 830 return; 831 832 state = tz->state; 833 834 result = acpi_thermal_get_temperature(tz); 835 if (result) 836 goto unlock; 837 838 if (!tz->tz_enabled) 839 goto unlock; 840 841 memset(&tz->state, 0, sizeof(tz->state)); 842 843 /* 844 * Check Trip Points 845 * ----------------- 846 * Compare the current temperature to the trip point values to see 847 * if we've entered one of the thermal policy states. Note that 848 * this function determines when a state is entered, but the 849 * individual policy decides when it is exited (e.g. hysteresis). 850 */ 851 if (tz->trips.critical.flags.valid) 852 state.critical |= 853 (tz->temperature >= tz->trips.critical.temperature); 854 if (tz->trips.hot.flags.valid) 855 state.hot |= (tz->temperature >= tz->trips.hot.temperature); 856 if (tz->trips.passive.flags.valid) 857 state.passive |= 858 (tz->temperature >= tz->trips.passive.temperature); 859 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) 860 if (tz->trips.active[i].flags.valid) 861 state.active |= 862 (tz->temperature >= 863 tz->trips.active[i].temperature); 864 865 /* 866 * Invoke Policy 867 * ------------- 868 * Separated from the above check to allow individual policy to 869 * determine when to exit a given state. 870 */ 871 if (state.critical) 872 acpi_thermal_critical(tz); 873 if (state.hot) 874 acpi_thermal_hot(tz); 875 if (state.passive) 876 acpi_thermal_passive(tz); 877 if (state.active) 878 acpi_thermal_active(tz); 879 880 /* 881 * Calculate State 882 * --------------- 883 * Again, separated from the above two to allow independent policy 884 * decisions. 885 */ 886 tz->state.critical = tz->trips.critical.flags.enabled; 887 tz->state.hot = tz->trips.hot.flags.enabled; 888 tz->state.passive = tz->trips.passive.flags.enabled; 889 tz->state.active = 0; 890 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) 891 tz->state.active |= tz->trips.active[i].flags.enabled; 892 893 /* 894 * Calculate Sleep Time 895 * -------------------- 896 * If we're in the passive state, use _TSP's value. Otherwise 897 * use the default polling frequency (e.g. _TZP). If no polling 898 * frequency is specified then we'll wait forever (at least until 899 * a thermal event occurs). Note that _TSP and _TZD values are 900 * given in 1/10th seconds (we must covert to milliseconds). 901 */ 902 if (tz->state.passive) { 903 sleep_time = tz->trips.passive.tsp * 100; 904 timeout_jiffies = jiffies + (HZ * sleep_time) / 1000; 905 } else if (tz->polling_frequency > 0) { 906 sleep_time = tz->polling_frequency * 100; 907 timeout_jiffies = round_jiffies(jiffies + (HZ * sleep_time) / 1000); 908 } 909 910 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s: temperature[%lu] sleep[%lu]\n", 911 tz->name, tz->temperature, sleep_time)); 912 913 /* 914 * Schedule Next Poll 915 * ------------------ 916 */ 917 if (!sleep_time) { 918 if (timer_pending(&(tz->timer))) 919 del_timer(&(tz->timer)); 920 } else { 921 if (timer_pending(&(tz->timer))) 922 mod_timer(&(tz->timer), timeout_jiffies); 923 else { 924 tz->timer.data = (unsigned long)tz; 925 tz->timer.function = acpi_thermal_run; 926 tz->timer.expires = timeout_jiffies; 927 add_timer(&(tz->timer)); 928 } 929 } 930 unlock: 931 mutex_unlock(&tz->lock); 932 } 933 934 /* sys I/F for generic thermal sysfs support */ 935 #define KELVIN_TO_MILLICELSIUS(t) (t * 100 - 273200) 936 937 static int thermal_get_temp(struct thermal_zone_device *thermal, char *buf) 938 { 939 struct acpi_thermal *tz = thermal->devdata; 940 int result; 941 942 if (!tz) 943 return -EINVAL; 944 945 result = acpi_thermal_get_temperature(tz); 946 if (result) 947 return result; 948 949 return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS(tz->temperature)); 950 } 951 952 static const char enabled[] = "kernel"; 953 static const char disabled[] = "user"; 954 static int thermal_get_mode(struct thermal_zone_device *thermal, 955 char *buf) 956 { 957 struct acpi_thermal *tz = thermal->devdata; 958 959 if (!tz) 960 return -EINVAL; 961 962 return sprintf(buf, "%s\n", tz->tz_enabled ? 963 enabled : disabled); 964 } 965 966 static int thermal_set_mode(struct thermal_zone_device *thermal, 967 const char *buf) 968 { 969 struct acpi_thermal *tz = thermal->devdata; 970 int enable; 971 972 if (!tz) 973 return -EINVAL; 974 975 /* 976 * enable/disable thermal management from ACPI thermal driver 977 */ 978 if (!strncmp(buf, enabled, sizeof enabled - 1)) 979 enable = 1; 980 else if (!strncmp(buf, disabled, sizeof disabled - 1)) 981 enable = 0; 982 else 983 return -EINVAL; 984 985 if (enable != tz->tz_enabled) { 986 tz->tz_enabled = enable; 987 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 988 "%s ACPI thermal control\n", 989 tz->tz_enabled ? enabled : disabled)); 990 acpi_thermal_check(tz); 991 } 992 return 0; 993 } 994 995 static int thermal_get_trip_type(struct thermal_zone_device *thermal, 996 int trip, char *buf) 997 { 998 struct acpi_thermal *tz = thermal->devdata; 999 int i; 1000 1001 if (!tz || trip < 0) 1002 return -EINVAL; 1003 1004 if (tz->trips.critical.flags.valid) { 1005 if (!trip) 1006 return sprintf(buf, "critical\n"); 1007 trip--; 1008 } 1009 1010 if (tz->trips.hot.flags.valid) { 1011 if (!trip) 1012 return sprintf(buf, "hot\n"); 1013 trip--; 1014 } 1015 1016 if (tz->trips.passive.flags.valid) { 1017 if (!trip) 1018 return sprintf(buf, "passive\n"); 1019 trip--; 1020 } 1021 1022 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE && 1023 tz->trips.active[i].flags.valid; i++) { 1024 if (!trip) 1025 return sprintf(buf, "active%d\n", i); 1026 trip--; 1027 } 1028 1029 return -EINVAL; 1030 } 1031 1032 static int thermal_get_trip_temp(struct thermal_zone_device *thermal, 1033 int trip, char *buf) 1034 { 1035 struct acpi_thermal *tz = thermal->devdata; 1036 int i; 1037 1038 if (!tz || trip < 0) 1039 return -EINVAL; 1040 1041 if (tz->trips.critical.flags.valid) { 1042 if (!trip) 1043 return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS( 1044 tz->trips.critical.temperature)); 1045 trip--; 1046 } 1047 1048 if (tz->trips.hot.flags.valid) { 1049 if (!trip) 1050 return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS( 1051 tz->trips.hot.temperature)); 1052 trip--; 1053 } 1054 1055 if (tz->trips.passive.flags.valid) { 1056 if (!trip) 1057 return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS( 1058 tz->trips.passive.temperature)); 1059 trip--; 1060 } 1061 1062 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE && 1063 tz->trips.active[i].flags.valid; i++) { 1064 if (!trip) 1065 return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS( 1066 tz->trips.active[i].temperature)); 1067 trip--; 1068 } 1069 1070 return -EINVAL; 1071 } 1072 1073 static int thermal_get_crit_temp(struct thermal_zone_device *thermal, 1074 unsigned long *temperature) { 1075 struct acpi_thermal *tz = thermal->devdata; 1076 1077 if (tz->trips.critical.flags.valid) { 1078 *temperature = KELVIN_TO_MILLICELSIUS( 1079 tz->trips.critical.temperature); 1080 return 0; 1081 } else 1082 return -EINVAL; 1083 } 1084 1085 typedef int (*cb)(struct thermal_zone_device *, int, 1086 struct thermal_cooling_device *); 1087 static int acpi_thermal_cooling_device_cb(struct thermal_zone_device *thermal, 1088 struct thermal_cooling_device *cdev, 1089 cb action) 1090 { 1091 struct acpi_device *device = cdev->devdata; 1092 struct acpi_thermal *tz = thermal->devdata; 1093 struct acpi_device *dev; 1094 acpi_status status; 1095 acpi_handle handle; 1096 int i; 1097 int j; 1098 int trip = -1; 1099 int result = 0; 1100 1101 if (tz->trips.critical.flags.valid) 1102 trip++; 1103 1104 if (tz->trips.hot.flags.valid) 1105 trip++; 1106 1107 if (tz->trips.passive.flags.valid) { 1108 trip++; 1109 for (i = 0; i < tz->trips.passive.devices.count; 1110 i++) { 1111 handle = tz->trips.passive.devices.handles[i]; 1112 status = acpi_bus_get_device(handle, &dev); 1113 if (ACPI_SUCCESS(status) && (dev == device)) { 1114 result = action(thermal, trip, cdev); 1115 if (result) 1116 goto failed; 1117 } 1118 } 1119 } 1120 1121 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { 1122 if (!tz->trips.active[i].flags.valid) 1123 break; 1124 trip++; 1125 for (j = 0; 1126 j < tz->trips.active[i].devices.count; 1127 j++) { 1128 handle = tz->trips.active[i].devices.handles[j]; 1129 status = acpi_bus_get_device(handle, &dev); 1130 if (ACPI_SUCCESS(status) && (dev == device)) { 1131 result = action(thermal, trip, cdev); 1132 if (result) 1133 goto failed; 1134 } 1135 } 1136 } 1137 1138 for (i = 0; i < tz->devices.count; i++) { 1139 handle = tz->devices.handles[i]; 1140 status = acpi_bus_get_device(handle, &dev); 1141 if (ACPI_SUCCESS(status) && (dev == device)) { 1142 result = action(thermal, -1, cdev); 1143 if (result) 1144 goto failed; 1145 } 1146 } 1147 1148 failed: 1149 return result; 1150 } 1151 1152 static int 1153 acpi_thermal_bind_cooling_device(struct thermal_zone_device *thermal, 1154 struct thermal_cooling_device *cdev) 1155 { 1156 return acpi_thermal_cooling_device_cb(thermal, cdev, 1157 thermal_zone_bind_cooling_device); 1158 } 1159 1160 static int 1161 acpi_thermal_unbind_cooling_device(struct thermal_zone_device *thermal, 1162 struct thermal_cooling_device *cdev) 1163 { 1164 return acpi_thermal_cooling_device_cb(thermal, cdev, 1165 thermal_zone_unbind_cooling_device); 1166 } 1167 1168 static struct thermal_zone_device_ops acpi_thermal_zone_ops = { 1169 .bind = acpi_thermal_bind_cooling_device, 1170 .unbind = acpi_thermal_unbind_cooling_device, 1171 .get_temp = thermal_get_temp, 1172 .get_mode = thermal_get_mode, 1173 .set_mode = thermal_set_mode, 1174 .get_trip_type = thermal_get_trip_type, 1175 .get_trip_temp = thermal_get_trip_temp, 1176 .get_crit_temp = thermal_get_crit_temp, 1177 }; 1178 1179 static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz) 1180 { 1181 int trips = 0; 1182 int result; 1183 acpi_status status; 1184 int i; 1185 1186 if (tz->trips.critical.flags.valid) 1187 trips++; 1188 1189 if (tz->trips.hot.flags.valid) 1190 trips++; 1191 1192 if (tz->trips.passive.flags.valid) 1193 trips++; 1194 1195 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE && 1196 tz->trips.active[i].flags.valid; i++, trips++); 1197 tz->thermal_zone = thermal_zone_device_register("acpitz", 1198 trips, tz, &acpi_thermal_zone_ops); 1199 if (IS_ERR(tz->thermal_zone)) 1200 return -ENODEV; 1201 1202 result = sysfs_create_link(&tz->device->dev.kobj, 1203 &tz->thermal_zone->device.kobj, "thermal_zone"); 1204 if (result) 1205 return result; 1206 1207 result = sysfs_create_link(&tz->thermal_zone->device.kobj, 1208 &tz->device->dev.kobj, "device"); 1209 if (result) 1210 return result; 1211 1212 status = acpi_attach_data(tz->device->handle, 1213 acpi_bus_private_data_handler, 1214 tz->thermal_zone); 1215 if (ACPI_FAILURE(status)) { 1216 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 1217 "Error attaching device data\n")); 1218 return -ENODEV; 1219 } 1220 1221 tz->tz_enabled = 1; 1222 1223 dev_info(&tz->device->dev, "registered as thermal_zone%d\n", 1224 tz->thermal_zone->id); 1225 return 0; 1226 } 1227 1228 static void acpi_thermal_unregister_thermal_zone(struct acpi_thermal *tz) 1229 { 1230 sysfs_remove_link(&tz->device->dev.kobj, "thermal_zone"); 1231 sysfs_remove_link(&tz->thermal_zone->device.kobj, "device"); 1232 thermal_zone_device_unregister(tz->thermal_zone); 1233 tz->thermal_zone = NULL; 1234 acpi_detach_data(tz->device->handle, acpi_bus_private_data_handler); 1235 } 1236 1237 1238 /* -------------------------------------------------------------------------- 1239 FS Interface (/proc) 1240 -------------------------------------------------------------------------- */ 1241 1242 static struct proc_dir_entry *acpi_thermal_dir; 1243 1244 static int acpi_thermal_state_seq_show(struct seq_file *seq, void *offset) 1245 { 1246 struct acpi_thermal *tz = seq->private; 1247 1248 1249 if (!tz) 1250 goto end; 1251 1252 seq_puts(seq, "state: "); 1253 1254 if (!tz->state.critical && !tz->state.hot && !tz->state.passive 1255 && !tz->state.active) 1256 seq_puts(seq, "ok\n"); 1257 else { 1258 if (tz->state.critical) 1259 seq_puts(seq, "critical "); 1260 if (tz->state.hot) 1261 seq_puts(seq, "hot "); 1262 if (tz->state.passive) 1263 seq_puts(seq, "passive "); 1264 if (tz->state.active) 1265 seq_printf(seq, "active[%d]", tz->state.active_index); 1266 seq_puts(seq, "\n"); 1267 } 1268 1269 end: 1270 return 0; 1271 } 1272 1273 static int acpi_thermal_state_open_fs(struct inode *inode, struct file *file) 1274 { 1275 return single_open(file, acpi_thermal_state_seq_show, PDE(inode)->data); 1276 } 1277 1278 static int acpi_thermal_temp_seq_show(struct seq_file *seq, void *offset) 1279 { 1280 int result = 0; 1281 struct acpi_thermal *tz = seq->private; 1282 1283 1284 if (!tz) 1285 goto end; 1286 1287 result = acpi_thermal_get_temperature(tz); 1288 if (result) 1289 goto end; 1290 1291 seq_printf(seq, "temperature: %ld C\n", 1292 KELVIN_TO_CELSIUS(tz->temperature)); 1293 1294 end: 1295 return 0; 1296 } 1297 1298 static int acpi_thermal_temp_open_fs(struct inode *inode, struct file *file) 1299 { 1300 return single_open(file, acpi_thermal_temp_seq_show, PDE(inode)->data); 1301 } 1302 1303 static int acpi_thermal_trip_seq_show(struct seq_file *seq, void *offset) 1304 { 1305 struct acpi_thermal *tz = seq->private; 1306 struct acpi_device *device; 1307 acpi_status status; 1308 1309 int i = 0; 1310 int j = 0; 1311 1312 1313 if (!tz) 1314 goto end; 1315 1316 if (tz->trips.critical.flags.valid) 1317 seq_printf(seq, "critical (S5): %ld C%s", 1318 KELVIN_TO_CELSIUS(tz->trips.critical.temperature), 1319 nocrt ? " <disabled>\n" : "\n"); 1320 1321 if (tz->trips.hot.flags.valid) 1322 seq_printf(seq, "hot (S4): %ld C%s", 1323 KELVIN_TO_CELSIUS(tz->trips.hot.temperature), 1324 nocrt ? " <disabled>\n" : "\n"); 1325 1326 if (tz->trips.passive.flags.valid) { 1327 seq_printf(seq, 1328 "passive: %ld C: tc1=%lu tc2=%lu tsp=%lu devices=", 1329 KELVIN_TO_CELSIUS(tz->trips.passive.temperature), 1330 tz->trips.passive.tc1, tz->trips.passive.tc2, 1331 tz->trips.passive.tsp); 1332 for (j = 0; j < tz->trips.passive.devices.count; j++) { 1333 status = acpi_bus_get_device(tz->trips.passive.devices. 1334 handles[j], &device); 1335 seq_printf(seq, "%4.4s ", status ? "" : 1336 acpi_device_bid(device)); 1337 } 1338 seq_puts(seq, "\n"); 1339 } 1340 1341 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { 1342 if (!(tz->trips.active[i].flags.valid)) 1343 break; 1344 seq_printf(seq, "active[%d]: %ld C: devices=", 1345 i, 1346 KELVIN_TO_CELSIUS(tz->trips.active[i].temperature)); 1347 for (j = 0; j < tz->trips.active[i].devices.count; j++){ 1348 status = acpi_bus_get_device(tz->trips.active[i]. 1349 devices.handles[j], 1350 &device); 1351 seq_printf(seq, "%4.4s ", status ? "" : 1352 acpi_device_bid(device)); 1353 } 1354 seq_puts(seq, "\n"); 1355 } 1356 1357 end: 1358 return 0; 1359 } 1360 1361 static int acpi_thermal_trip_open_fs(struct inode *inode, struct file *file) 1362 { 1363 return single_open(file, acpi_thermal_trip_seq_show, PDE(inode)->data); 1364 } 1365 1366 static int acpi_thermal_cooling_seq_show(struct seq_file *seq, void *offset) 1367 { 1368 struct acpi_thermal *tz = seq->private; 1369 1370 1371 if (!tz) 1372 goto end; 1373 1374 if (!tz->flags.cooling_mode) 1375 seq_puts(seq, "<setting not supported>\n"); 1376 else 1377 seq_puts(seq, "0 - Active; 1 - Passive\n"); 1378 1379 end: 1380 return 0; 1381 } 1382 1383 static int acpi_thermal_cooling_open_fs(struct inode *inode, struct file *file) 1384 { 1385 return single_open(file, acpi_thermal_cooling_seq_show, 1386 PDE(inode)->data); 1387 } 1388 1389 static ssize_t 1390 acpi_thermal_write_cooling_mode(struct file *file, 1391 const char __user * buffer, 1392 size_t count, loff_t * ppos) 1393 { 1394 struct seq_file *m = file->private_data; 1395 struct acpi_thermal *tz = m->private; 1396 int result = 0; 1397 char mode_string[12] = { '\0' }; 1398 1399 1400 if (!tz || (count > sizeof(mode_string) - 1)) 1401 return -EINVAL; 1402 1403 if (!tz->flags.cooling_mode) 1404 return -ENODEV; 1405 1406 if (copy_from_user(mode_string, buffer, count)) 1407 return -EFAULT; 1408 1409 mode_string[count] = '\0'; 1410 1411 result = acpi_thermal_set_cooling_mode(tz, 1412 simple_strtoul(mode_string, NULL, 1413 0)); 1414 if (result) 1415 return result; 1416 1417 acpi_thermal_check(tz); 1418 1419 return count; 1420 } 1421 1422 static int acpi_thermal_polling_seq_show(struct seq_file *seq, void *offset) 1423 { 1424 struct acpi_thermal *tz = seq->private; 1425 1426 1427 if (!tz) 1428 goto end; 1429 1430 if (!tz->polling_frequency) { 1431 seq_puts(seq, "<polling disabled>\n"); 1432 goto end; 1433 } 1434 1435 seq_printf(seq, "polling frequency: %lu seconds\n", 1436 (tz->polling_frequency / 10)); 1437 1438 end: 1439 return 0; 1440 } 1441 1442 static int acpi_thermal_polling_open_fs(struct inode *inode, struct file *file) 1443 { 1444 return single_open(file, acpi_thermal_polling_seq_show, 1445 PDE(inode)->data); 1446 } 1447 1448 static ssize_t 1449 acpi_thermal_write_polling(struct file *file, 1450 const char __user * buffer, 1451 size_t count, loff_t * ppos) 1452 { 1453 struct seq_file *m = file->private_data; 1454 struct acpi_thermal *tz = m->private; 1455 int result = 0; 1456 char polling_string[12] = { '\0' }; 1457 int seconds = 0; 1458 1459 1460 if (!tz || (count > sizeof(polling_string) - 1)) 1461 return -EINVAL; 1462 1463 if (copy_from_user(polling_string, buffer, count)) 1464 return -EFAULT; 1465 1466 polling_string[count] = '\0'; 1467 1468 seconds = simple_strtoul(polling_string, NULL, 0); 1469 1470 result = acpi_thermal_set_polling(tz, seconds); 1471 if (result) 1472 return result; 1473 1474 acpi_thermal_check(tz); 1475 1476 return count; 1477 } 1478 1479 static int acpi_thermal_add_fs(struct acpi_device *device) 1480 { 1481 struct proc_dir_entry *entry = NULL; 1482 1483 1484 if (!acpi_device_dir(device)) { 1485 acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), 1486 acpi_thermal_dir); 1487 if (!acpi_device_dir(device)) 1488 return -ENODEV; 1489 acpi_device_dir(device)->owner = THIS_MODULE; 1490 } 1491 1492 /* 'state' [R] */ 1493 entry = proc_create_data(ACPI_THERMAL_FILE_STATE, 1494 S_IRUGO, acpi_device_dir(device), 1495 &acpi_thermal_state_fops, 1496 acpi_driver_data(device)); 1497 if (!entry) 1498 return -ENODEV; 1499 1500 /* 'temperature' [R] */ 1501 entry = proc_create_data(ACPI_THERMAL_FILE_TEMPERATURE, 1502 S_IRUGO, acpi_device_dir(device), 1503 &acpi_thermal_temp_fops, 1504 acpi_driver_data(device)); 1505 if (!entry) 1506 return -ENODEV; 1507 1508 /* 'trip_points' [R] */ 1509 entry = proc_create_data(ACPI_THERMAL_FILE_TRIP_POINTS, 1510 S_IRUGO, 1511 acpi_device_dir(device), 1512 &acpi_thermal_trip_fops, 1513 acpi_driver_data(device)); 1514 if (!entry) 1515 return -ENODEV; 1516 1517 /* 'cooling_mode' [R/W] */ 1518 entry = proc_create_data(ACPI_THERMAL_FILE_COOLING_MODE, 1519 S_IFREG | S_IRUGO | S_IWUSR, 1520 acpi_device_dir(device), 1521 &acpi_thermal_cooling_fops, 1522 acpi_driver_data(device)); 1523 if (!entry) 1524 return -ENODEV; 1525 1526 /* 'polling_frequency' [R/W] */ 1527 entry = proc_create_data(ACPI_THERMAL_FILE_POLLING_FREQ, 1528 S_IFREG | S_IRUGO | S_IWUSR, 1529 acpi_device_dir(device), 1530 &acpi_thermal_polling_fops, 1531 acpi_driver_data(device)); 1532 if (!entry) 1533 return -ENODEV; 1534 return 0; 1535 } 1536 1537 static int acpi_thermal_remove_fs(struct acpi_device *device) 1538 { 1539 1540 if (acpi_device_dir(device)) { 1541 remove_proc_entry(ACPI_THERMAL_FILE_POLLING_FREQ, 1542 acpi_device_dir(device)); 1543 remove_proc_entry(ACPI_THERMAL_FILE_COOLING_MODE, 1544 acpi_device_dir(device)); 1545 remove_proc_entry(ACPI_THERMAL_FILE_TRIP_POINTS, 1546 acpi_device_dir(device)); 1547 remove_proc_entry(ACPI_THERMAL_FILE_TEMPERATURE, 1548 acpi_device_dir(device)); 1549 remove_proc_entry(ACPI_THERMAL_FILE_STATE, 1550 acpi_device_dir(device)); 1551 remove_proc_entry(acpi_device_bid(device), acpi_thermal_dir); 1552 acpi_device_dir(device) = NULL; 1553 } 1554 1555 return 0; 1556 } 1557 1558 /* -------------------------------------------------------------------------- 1559 Driver Interface 1560 -------------------------------------------------------------------------- */ 1561 1562 static void acpi_thermal_notify(acpi_handle handle, u32 event, void *data) 1563 { 1564 struct acpi_thermal *tz = data; 1565 struct acpi_device *device = NULL; 1566 1567 1568 if (!tz) 1569 return; 1570 1571 device = tz->device; 1572 1573 switch (event) { 1574 case ACPI_THERMAL_NOTIFY_TEMPERATURE: 1575 acpi_thermal_check(tz); 1576 break; 1577 case ACPI_THERMAL_NOTIFY_THRESHOLDS: 1578 acpi_thermal_trips_update(tz, ACPI_TRIPS_REFRESH_THRESHOLDS); 1579 acpi_thermal_check(tz); 1580 acpi_bus_generate_proc_event(device, event, 0); 1581 acpi_bus_generate_netlink_event(device->pnp.device_class, 1582 device->dev.bus_id, event, 0); 1583 break; 1584 case ACPI_THERMAL_NOTIFY_DEVICES: 1585 acpi_thermal_trips_update(tz, ACPI_TRIPS_REFRESH_DEVICES); 1586 acpi_thermal_check(tz); 1587 acpi_bus_generate_proc_event(device, event, 0); 1588 acpi_bus_generate_netlink_event(device->pnp.device_class, 1589 device->dev.bus_id, event, 0); 1590 break; 1591 default: 1592 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 1593 "Unsupported event [0x%x]\n", event)); 1594 break; 1595 } 1596 1597 return; 1598 } 1599 1600 static int acpi_thermal_get_info(struct acpi_thermal *tz) 1601 { 1602 int result = 0; 1603 1604 1605 if (!tz) 1606 return -EINVAL; 1607 1608 /* Get temperature [_TMP] (required) */ 1609 result = acpi_thermal_get_temperature(tz); 1610 if (result) 1611 return result; 1612 1613 /* Get trip points [_CRT, _PSV, etc.] (required) */ 1614 result = acpi_thermal_get_trip_points(tz); 1615 if (result) 1616 return result; 1617 1618 /* Set the cooling mode [_SCP] to active cooling (default) */ 1619 result = acpi_thermal_set_cooling_mode(tz, ACPI_THERMAL_MODE_ACTIVE); 1620 if (!result) 1621 tz->flags.cooling_mode = 1; 1622 1623 /* Get default polling frequency [_TZP] (optional) */ 1624 if (tzp) 1625 tz->polling_frequency = tzp; 1626 else 1627 acpi_thermal_get_polling_frequency(tz); 1628 1629 return 0; 1630 } 1631 1632 static int acpi_thermal_add(struct acpi_device *device) 1633 { 1634 int result = 0; 1635 acpi_status status = AE_OK; 1636 struct acpi_thermal *tz = NULL; 1637 1638 1639 if (!device) 1640 return -EINVAL; 1641 1642 tz = kzalloc(sizeof(struct acpi_thermal), GFP_KERNEL); 1643 if (!tz) 1644 return -ENOMEM; 1645 1646 tz->device = device; 1647 strcpy(tz->name, device->pnp.bus_id); 1648 strcpy(acpi_device_name(device), ACPI_THERMAL_DEVICE_NAME); 1649 strcpy(acpi_device_class(device), ACPI_THERMAL_CLASS); 1650 acpi_driver_data(device) = tz; 1651 mutex_init(&tz->lock); 1652 1653 1654 result = acpi_thermal_get_info(tz); 1655 if (result) 1656 goto free_memory; 1657 1658 result = acpi_thermal_register_thermal_zone(tz); 1659 if (result) 1660 goto free_memory; 1661 1662 result = acpi_thermal_add_fs(device); 1663 if (result) 1664 goto unregister_thermal_zone; 1665 1666 init_timer(&tz->timer); 1667 1668 acpi_thermal_active_off(tz); 1669 1670 acpi_thermal_check(tz); 1671 1672 status = acpi_install_notify_handler(device->handle, 1673 ACPI_DEVICE_NOTIFY, 1674 acpi_thermal_notify, tz); 1675 if (ACPI_FAILURE(status)) { 1676 result = -ENODEV; 1677 goto remove_fs; 1678 } 1679 1680 printk(KERN_INFO PREFIX "%s [%s] (%ld C)\n", 1681 acpi_device_name(device), acpi_device_bid(device), 1682 KELVIN_TO_CELSIUS(tz->temperature)); 1683 goto end; 1684 1685 remove_fs: 1686 acpi_thermal_remove_fs(device); 1687 unregister_thermal_zone: 1688 thermal_zone_device_unregister(tz->thermal_zone); 1689 free_memory: 1690 kfree(tz); 1691 end: 1692 return result; 1693 } 1694 1695 static int acpi_thermal_remove(struct acpi_device *device, int type) 1696 { 1697 acpi_status status = AE_OK; 1698 struct acpi_thermal *tz = NULL; 1699 1700 1701 if (!device || !acpi_driver_data(device)) 1702 return -EINVAL; 1703 1704 tz = acpi_driver_data(device); 1705 1706 /* avoid timer adding new defer task */ 1707 tz->zombie = 1; 1708 /* wait for running timer (on other CPUs) finish */ 1709 del_timer_sync(&(tz->timer)); 1710 /* synchronize deferred task */ 1711 acpi_os_wait_events_complete(NULL); 1712 /* deferred task may reinsert timer */ 1713 del_timer_sync(&(tz->timer)); 1714 1715 status = acpi_remove_notify_handler(device->handle, 1716 ACPI_DEVICE_NOTIFY, 1717 acpi_thermal_notify); 1718 1719 /* Terminate policy */ 1720 if (tz->trips.passive.flags.valid && tz->trips.passive.flags.enabled) { 1721 tz->trips.passive.flags.enabled = 0; 1722 acpi_thermal_passive(tz); 1723 } 1724 if (tz->trips.active[0].flags.valid 1725 && tz->trips.active[0].flags.enabled) { 1726 tz->trips.active[0].flags.enabled = 0; 1727 acpi_thermal_active(tz); 1728 } 1729 1730 acpi_thermal_remove_fs(device); 1731 acpi_thermal_unregister_thermal_zone(tz); 1732 mutex_destroy(&tz->lock); 1733 kfree(tz); 1734 return 0; 1735 } 1736 1737 static int acpi_thermal_resume(struct acpi_device *device) 1738 { 1739 struct acpi_thermal *tz = NULL; 1740 int i, j, power_state, result; 1741 1742 1743 if (!device || !acpi_driver_data(device)) 1744 return -EINVAL; 1745 1746 tz = acpi_driver_data(device); 1747 1748 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { 1749 if (!(&tz->trips.active[i])) 1750 break; 1751 if (!tz->trips.active[i].flags.valid) 1752 break; 1753 tz->trips.active[i].flags.enabled = 1; 1754 for (j = 0; j < tz->trips.active[i].devices.count; j++) { 1755 result = acpi_bus_get_power(tz->trips.active[i].devices. 1756 handles[j], &power_state); 1757 if (result || (power_state != ACPI_STATE_D0)) { 1758 tz->trips.active[i].flags.enabled = 0; 1759 break; 1760 } 1761 } 1762 tz->state.active |= tz->trips.active[i].flags.enabled; 1763 } 1764 1765 acpi_thermal_check(tz); 1766 1767 return AE_OK; 1768 } 1769 1770 static int thermal_act(const struct dmi_system_id *d) { 1771 1772 if (act == 0) { 1773 printk(KERN_NOTICE "ACPI: %s detected: " 1774 "disabling all active thermal trip points\n", d->ident); 1775 act = -1; 1776 } 1777 return 0; 1778 } 1779 static int thermal_nocrt(const struct dmi_system_id *d) { 1780 1781 printk(KERN_NOTICE "ACPI: %s detected: " 1782 "disabling all critical thermal trip point actions.\n", d->ident); 1783 nocrt = 1; 1784 return 0; 1785 } 1786 static int thermal_tzp(const struct dmi_system_id *d) { 1787 1788 if (tzp == 0) { 1789 printk(KERN_NOTICE "ACPI: %s detected: " 1790 "enabling thermal zone polling\n", d->ident); 1791 tzp = 300; /* 300 dS = 30 Seconds */ 1792 } 1793 return 0; 1794 } 1795 static int thermal_psv(const struct dmi_system_id *d) { 1796 1797 if (psv == 0) { 1798 printk(KERN_NOTICE "ACPI: %s detected: " 1799 "disabling all passive thermal trip points\n", d->ident); 1800 psv = -1; 1801 } 1802 return 0; 1803 } 1804 1805 static struct dmi_system_id thermal_dmi_table[] __initdata = { 1806 /* 1807 * Award BIOS on this AOpen makes thermal control almost worthless. 1808 * http://bugzilla.kernel.org/show_bug.cgi?id=8842 1809 */ 1810 { 1811 .callback = thermal_act, 1812 .ident = "AOpen i915GMm-HFS", 1813 .matches = { 1814 DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"), 1815 DMI_MATCH(DMI_BOARD_NAME, "i915GMm-HFS"), 1816 }, 1817 }, 1818 { 1819 .callback = thermal_psv, 1820 .ident = "AOpen i915GMm-HFS", 1821 .matches = { 1822 DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"), 1823 DMI_MATCH(DMI_BOARD_NAME, "i915GMm-HFS"), 1824 }, 1825 }, 1826 { 1827 .callback = thermal_tzp, 1828 .ident = "AOpen i915GMm-HFS", 1829 .matches = { 1830 DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"), 1831 DMI_MATCH(DMI_BOARD_NAME, "i915GMm-HFS"), 1832 }, 1833 }, 1834 { 1835 .callback = thermal_nocrt, 1836 .ident = "Gigabyte GA-7ZX", 1837 .matches = { 1838 DMI_MATCH(DMI_BOARD_VENDOR, "Gigabyte Technology Co., Ltd."), 1839 DMI_MATCH(DMI_BOARD_NAME, "7ZX"), 1840 }, 1841 }, 1842 {} 1843 }; 1844 1845 static int __init acpi_thermal_init(void) 1846 { 1847 int result = 0; 1848 1849 dmi_check_system(thermal_dmi_table); 1850 1851 if (off) { 1852 printk(KERN_NOTICE "ACPI: thermal control disabled\n"); 1853 return -ENODEV; 1854 } 1855 acpi_thermal_dir = proc_mkdir(ACPI_THERMAL_CLASS, acpi_root_dir); 1856 if (!acpi_thermal_dir) 1857 return -ENODEV; 1858 acpi_thermal_dir->owner = THIS_MODULE; 1859 1860 result = acpi_bus_register_driver(&acpi_thermal_driver); 1861 if (result < 0) { 1862 remove_proc_entry(ACPI_THERMAL_CLASS, acpi_root_dir); 1863 return -ENODEV; 1864 } 1865 1866 return 0; 1867 } 1868 1869 static void __exit acpi_thermal_exit(void) 1870 { 1871 1872 acpi_bus_unregister_driver(&acpi_thermal_driver); 1873 1874 remove_proc_entry(ACPI_THERMAL_CLASS, acpi_root_dir); 1875 1876 return; 1877 } 1878 1879 module_init(acpi_thermal_init); 1880 module_exit(acpi_thermal_exit); 1881