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/init.h> 37 #include <linux/types.h> 38 #include <linux/proc_fs.h> 39 #include <linux/timer.h> 40 #include <linux/jiffies.h> 41 #include <linux/kmod.h> 42 #include <linux/seq_file.h> 43 #include <asm/uaccess.h> 44 45 #include <acpi/acpi_bus.h> 46 #include <acpi/acpi_drivers.h> 47 48 #define ACPI_THERMAL_COMPONENT 0x04000000 49 #define ACPI_THERMAL_CLASS "thermal_zone" 50 #define ACPI_THERMAL_DEVICE_NAME "Thermal Zone" 51 #define ACPI_THERMAL_FILE_STATE "state" 52 #define ACPI_THERMAL_FILE_TEMPERATURE "temperature" 53 #define ACPI_THERMAL_FILE_TRIP_POINTS "trip_points" 54 #define ACPI_THERMAL_FILE_COOLING_MODE "cooling_mode" 55 #define ACPI_THERMAL_FILE_POLLING_FREQ "polling_frequency" 56 #define ACPI_THERMAL_NOTIFY_TEMPERATURE 0x80 57 #define ACPI_THERMAL_NOTIFY_THRESHOLDS 0x81 58 #define ACPI_THERMAL_NOTIFY_DEVICES 0x82 59 #define ACPI_THERMAL_NOTIFY_CRITICAL 0xF0 60 #define ACPI_THERMAL_NOTIFY_HOT 0xF1 61 #define ACPI_THERMAL_MODE_ACTIVE 0x00 62 #define ACPI_THERMAL_PATH_POWEROFF "/sbin/poweroff" 63 64 #define ACPI_THERMAL_MAX_ACTIVE 10 65 #define ACPI_THERMAL_MAX_LIMIT_STR_LEN 65 66 67 #define KELVIN_TO_CELSIUS(t) (long)(((long)t-2732>=0) ? ((long)t-2732+5)/10 : ((long)t-2732-5)/10) 68 #define CELSIUS_TO_KELVIN(t) ((t+273)*10) 69 70 #define _COMPONENT ACPI_THERMAL_COMPONENT 71 ACPI_MODULE_NAME("thermal"); 72 73 MODULE_AUTHOR("Paul Diefenbaugh"); 74 MODULE_DESCRIPTION("ACPI Thermal Zone Driver"); 75 MODULE_LICENSE("GPL"); 76 77 static int tzp; 78 module_param(tzp, int, 0); 79 MODULE_PARM_DESC(tzp, "Thermal zone polling frequency, in 1/10 seconds.\n"); 80 81 static int acpi_thermal_add(struct acpi_device *device); 82 static int acpi_thermal_remove(struct acpi_device *device, int type); 83 static int acpi_thermal_resume(struct acpi_device *device); 84 static int acpi_thermal_state_open_fs(struct inode *inode, struct file *file); 85 static int acpi_thermal_temp_open_fs(struct inode *inode, struct file *file); 86 static int acpi_thermal_trip_open_fs(struct inode *inode, struct file *file); 87 static int acpi_thermal_cooling_open_fs(struct inode *inode, struct file *file); 88 static ssize_t acpi_thermal_write_cooling_mode(struct file *, 89 const char __user *, size_t, 90 loff_t *); 91 static int acpi_thermal_polling_open_fs(struct inode *inode, struct file *file); 92 static ssize_t acpi_thermal_write_polling(struct file *, const char __user *, 93 size_t, loff_t *); 94 95 static struct acpi_driver acpi_thermal_driver = { 96 .name = "thermal", 97 .class = ACPI_THERMAL_CLASS, 98 .ids = ACPI_THERMAL_HID, 99 .ops = { 100 .add = acpi_thermal_add, 101 .remove = acpi_thermal_remove, 102 .resume = acpi_thermal_resume, 103 }, 104 }; 105 106 struct acpi_thermal_state { 107 u8 critical:1; 108 u8 hot:1; 109 u8 passive:1; 110 u8 active:1; 111 u8 reserved:4; 112 int active_index; 113 }; 114 115 struct acpi_thermal_state_flags { 116 u8 valid:1; 117 u8 enabled:1; 118 u8 reserved:6; 119 }; 120 121 struct acpi_thermal_critical { 122 struct acpi_thermal_state_flags flags; 123 unsigned long temperature; 124 }; 125 126 struct acpi_thermal_hot { 127 struct acpi_thermal_state_flags flags; 128 unsigned long temperature; 129 }; 130 131 struct acpi_thermal_passive { 132 struct acpi_thermal_state_flags flags; 133 unsigned long temperature; 134 unsigned long tc1; 135 unsigned long tc2; 136 unsigned long tsp; 137 struct acpi_handle_list devices; 138 }; 139 140 struct acpi_thermal_active { 141 struct acpi_thermal_state_flags flags; 142 unsigned long temperature; 143 struct acpi_handle_list devices; 144 }; 145 146 struct acpi_thermal_trips { 147 struct acpi_thermal_critical critical; 148 struct acpi_thermal_hot hot; 149 struct acpi_thermal_passive passive; 150 struct acpi_thermal_active active[ACPI_THERMAL_MAX_ACTIVE]; 151 }; 152 153 struct acpi_thermal_flags { 154 u8 cooling_mode:1; /* _SCP */ 155 u8 devices:1; /* _TZD */ 156 u8 reserved:6; 157 }; 158 159 struct acpi_thermal { 160 struct acpi_device * device; 161 acpi_bus_id name; 162 unsigned long temperature; 163 unsigned long last_temperature; 164 unsigned long polling_frequency; 165 volatile u8 zombie; 166 struct acpi_thermal_flags flags; 167 struct acpi_thermal_state state; 168 struct acpi_thermal_trips trips; 169 struct acpi_handle_list devices; 170 struct timer_list timer; 171 }; 172 173 static const struct file_operations acpi_thermal_state_fops = { 174 .open = acpi_thermal_state_open_fs, 175 .read = seq_read, 176 .llseek = seq_lseek, 177 .release = single_release, 178 }; 179 180 static const struct file_operations acpi_thermal_temp_fops = { 181 .open = acpi_thermal_temp_open_fs, 182 .read = seq_read, 183 .llseek = seq_lseek, 184 .release = single_release, 185 }; 186 187 static const struct file_operations acpi_thermal_trip_fops = { 188 .open = acpi_thermal_trip_open_fs, 189 .read = seq_read, 190 .llseek = seq_lseek, 191 .release = single_release, 192 }; 193 194 static const struct file_operations acpi_thermal_cooling_fops = { 195 .open = acpi_thermal_cooling_open_fs, 196 .read = seq_read, 197 .write = acpi_thermal_write_cooling_mode, 198 .llseek = seq_lseek, 199 .release = single_release, 200 }; 201 202 static const struct file_operations acpi_thermal_polling_fops = { 203 .open = acpi_thermal_polling_open_fs, 204 .read = seq_read, 205 .write = acpi_thermal_write_polling, 206 .llseek = seq_lseek, 207 .release = single_release, 208 }; 209 210 /* -------------------------------------------------------------------------- 211 Thermal Zone Management 212 -------------------------------------------------------------------------- */ 213 214 static int acpi_thermal_get_temperature(struct acpi_thermal *tz) 215 { 216 acpi_status status = AE_OK; 217 218 219 if (!tz) 220 return -EINVAL; 221 222 tz->last_temperature = tz->temperature; 223 224 status = 225 acpi_evaluate_integer(tz->device->handle, "_TMP", NULL, &tz->temperature); 226 if (ACPI_FAILURE(status)) 227 return -ENODEV; 228 229 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Temperature is %lu dK\n", 230 tz->temperature)); 231 232 return 0; 233 } 234 235 static int acpi_thermal_get_polling_frequency(struct acpi_thermal *tz) 236 { 237 acpi_status status = AE_OK; 238 239 240 if (!tz) 241 return -EINVAL; 242 243 status = 244 acpi_evaluate_integer(tz->device->handle, "_TZP", NULL, 245 &tz->polling_frequency); 246 if (ACPI_FAILURE(status)) 247 return -ENODEV; 248 249 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Polling frequency is %lu dS\n", 250 tz->polling_frequency)); 251 252 return 0; 253 } 254 255 static int acpi_thermal_set_polling(struct acpi_thermal *tz, int seconds) 256 { 257 258 if (!tz) 259 return -EINVAL; 260 261 tz->polling_frequency = seconds * 10; /* Convert value to deci-seconds */ 262 263 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 264 "Polling frequency set to %lu seconds\n", 265 tz->polling_frequency/10)); 266 267 return 0; 268 } 269 270 static int acpi_thermal_set_cooling_mode(struct acpi_thermal *tz, int mode) 271 { 272 acpi_status status = AE_OK; 273 union acpi_object arg0 = { ACPI_TYPE_INTEGER }; 274 struct acpi_object_list arg_list = { 1, &arg0 }; 275 acpi_handle handle = NULL; 276 277 278 if (!tz) 279 return -EINVAL; 280 281 status = acpi_get_handle(tz->device->handle, "_SCP", &handle); 282 if (ACPI_FAILURE(status)) { 283 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "_SCP not present\n")); 284 return -ENODEV; 285 } 286 287 arg0.integer.value = mode; 288 289 status = acpi_evaluate_object(handle, NULL, &arg_list, NULL); 290 if (ACPI_FAILURE(status)) 291 return -ENODEV; 292 293 return 0; 294 } 295 296 static int acpi_thermal_get_trip_points(struct acpi_thermal *tz) 297 { 298 acpi_status status = AE_OK; 299 int i = 0; 300 301 302 if (!tz) 303 return -EINVAL; 304 305 /* Critical Shutdown (required) */ 306 307 status = acpi_evaluate_integer(tz->device->handle, "_CRT", NULL, 308 &tz->trips.critical.temperature); 309 if (ACPI_FAILURE(status)) { 310 tz->trips.critical.flags.valid = 0; 311 ACPI_EXCEPTION((AE_INFO, status, "No critical threshold")); 312 return -ENODEV; 313 } else { 314 tz->trips.critical.flags.valid = 1; 315 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 316 "Found critical threshold [%lu]\n", 317 tz->trips.critical.temperature)); 318 } 319 320 /* Critical Sleep (optional) */ 321 322 status = 323 acpi_evaluate_integer(tz->device->handle, "_HOT", NULL, 324 &tz->trips.hot.temperature); 325 if (ACPI_FAILURE(status)) { 326 tz->trips.hot.flags.valid = 0; 327 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No hot threshold\n")); 328 } else { 329 tz->trips.hot.flags.valid = 1; 330 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found hot threshold [%lu]\n", 331 tz->trips.hot.temperature)); 332 } 333 334 /* Passive: Processors (optional) */ 335 336 status = 337 acpi_evaluate_integer(tz->device->handle, "_PSV", NULL, 338 &tz->trips.passive.temperature); 339 if (ACPI_FAILURE(status)) { 340 tz->trips.passive.flags.valid = 0; 341 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No passive threshold\n")); 342 } else { 343 tz->trips.passive.flags.valid = 1; 344 345 status = 346 acpi_evaluate_integer(tz->device->handle, "_TC1", NULL, 347 &tz->trips.passive.tc1); 348 if (ACPI_FAILURE(status)) 349 tz->trips.passive.flags.valid = 0; 350 351 status = 352 acpi_evaluate_integer(tz->device->handle, "_TC2", NULL, 353 &tz->trips.passive.tc2); 354 if (ACPI_FAILURE(status)) 355 tz->trips.passive.flags.valid = 0; 356 357 status = 358 acpi_evaluate_integer(tz->device->handle, "_TSP", NULL, 359 &tz->trips.passive.tsp); 360 if (ACPI_FAILURE(status)) 361 tz->trips.passive.flags.valid = 0; 362 363 status = 364 acpi_evaluate_reference(tz->device->handle, "_PSL", NULL, 365 &tz->trips.passive.devices); 366 if (ACPI_FAILURE(status)) 367 tz->trips.passive.flags.valid = 0; 368 369 if (!tz->trips.passive.flags.valid) 370 printk(KERN_WARNING PREFIX "Invalid passive threshold\n"); 371 else 372 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 373 "Found passive threshold [%lu]\n", 374 tz->trips.passive.temperature)); 375 } 376 377 /* Active: Fans, etc. (optional) */ 378 379 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { 380 381 char name[5] = { '_', 'A', 'C', ('0' + i), '\0' }; 382 383 status = 384 acpi_evaluate_integer(tz->device->handle, name, NULL, 385 &tz->trips.active[i].temperature); 386 if (ACPI_FAILURE(status)) 387 break; 388 389 name[2] = 'L'; 390 status = 391 acpi_evaluate_reference(tz->device->handle, name, NULL, 392 &tz->trips.active[i].devices); 393 if (ACPI_SUCCESS(status)) { 394 tz->trips.active[i].flags.valid = 1; 395 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 396 "Found active threshold [%d]:[%lu]\n", 397 i, tz->trips.active[i].temperature)); 398 } else 399 ACPI_EXCEPTION((AE_INFO, status, 400 "Invalid active threshold [%d]", i)); 401 } 402 403 return 0; 404 } 405 406 static int acpi_thermal_get_devices(struct acpi_thermal *tz) 407 { 408 acpi_status status = AE_OK; 409 410 411 if (!tz) 412 return -EINVAL; 413 414 status = 415 acpi_evaluate_reference(tz->device->handle, "_TZD", NULL, &tz->devices); 416 if (ACPI_FAILURE(status)) 417 return -ENODEV; 418 419 return 0; 420 } 421 422 static int acpi_thermal_call_usermode(char *path) 423 { 424 char *argv[2] = { NULL, NULL }; 425 char *envp[3] = { NULL, NULL, NULL }; 426 427 428 if (!path) 429 return -EINVAL; 430 431 argv[0] = path; 432 433 /* minimal command environment */ 434 envp[0] = "HOME=/"; 435 envp[1] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin"; 436 437 call_usermodehelper(argv[0], argv, envp, 0); 438 439 return 0; 440 } 441 442 static int acpi_thermal_critical(struct acpi_thermal *tz) 443 { 444 if (!tz || !tz->trips.critical.flags.valid) 445 return -EINVAL; 446 447 if (tz->temperature >= tz->trips.critical.temperature) { 448 printk(KERN_WARNING PREFIX "Critical trip point\n"); 449 tz->trips.critical.flags.enabled = 1; 450 } else if (tz->trips.critical.flags.enabled) 451 tz->trips.critical.flags.enabled = 0; 452 453 printk(KERN_EMERG 454 "Critical temperature reached (%ld C), shutting down.\n", 455 KELVIN_TO_CELSIUS(tz->temperature)); 456 acpi_bus_generate_event(tz->device, ACPI_THERMAL_NOTIFY_CRITICAL, 457 tz->trips.critical.flags.enabled); 458 459 acpi_thermal_call_usermode(ACPI_THERMAL_PATH_POWEROFF); 460 461 return 0; 462 } 463 464 static int acpi_thermal_hot(struct acpi_thermal *tz) 465 { 466 if (!tz || !tz->trips.hot.flags.valid) 467 return -EINVAL; 468 469 if (tz->temperature >= tz->trips.hot.temperature) { 470 printk(KERN_WARNING PREFIX "Hot trip point\n"); 471 tz->trips.hot.flags.enabled = 1; 472 } else if (tz->trips.hot.flags.enabled) 473 tz->trips.hot.flags.enabled = 0; 474 475 acpi_bus_generate_event(tz->device, ACPI_THERMAL_NOTIFY_HOT, 476 tz->trips.hot.flags.enabled); 477 478 /* TBD: Call user-mode "sleep(S4)" function */ 479 480 return 0; 481 } 482 483 static void acpi_thermal_passive(struct acpi_thermal *tz) 484 { 485 int result = 1; 486 struct acpi_thermal_passive *passive = NULL; 487 int trend = 0; 488 int i = 0; 489 490 491 if (!tz || !tz->trips.passive.flags.valid) 492 return; 493 494 passive = &(tz->trips.passive); 495 496 /* 497 * Above Trip? 498 * ----------- 499 * Calculate the thermal trend (using the passive cooling equation) 500 * and modify the performance limit for all passive cooling devices 501 * accordingly. Note that we assume symmetry. 502 */ 503 if (tz->temperature >= passive->temperature) { 504 trend = 505 (passive->tc1 * (tz->temperature - tz->last_temperature)) + 506 (passive->tc2 * (tz->temperature - passive->temperature)); 507 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 508 "trend[%d]=(tc1[%lu]*(tmp[%lu]-last[%lu]))+(tc2[%lu]*(tmp[%lu]-psv[%lu]))\n", 509 trend, passive->tc1, tz->temperature, 510 tz->last_temperature, passive->tc2, 511 tz->temperature, passive->temperature)); 512 passive->flags.enabled = 1; 513 /* Heating up? */ 514 if (trend > 0) 515 for (i = 0; i < passive->devices.count; i++) 516 acpi_processor_set_thermal_limit(passive-> 517 devices. 518 handles[i], 519 ACPI_PROCESSOR_LIMIT_INCREMENT); 520 /* Cooling off? */ 521 else if (trend < 0) { 522 for (i = 0; i < passive->devices.count; i++) 523 /* 524 * assume that we are on highest 525 * freq/lowest thrott and can leave 526 * passive mode, even in error case 527 */ 528 if (!acpi_processor_set_thermal_limit 529 (passive->devices.handles[i], 530 ACPI_PROCESSOR_LIMIT_DECREMENT)) 531 result = 0; 532 /* 533 * Leave cooling mode, even if the temp might 534 * higher than trip point This is because some 535 * machines might have long thermal polling 536 * frequencies (tsp) defined. We will fall back 537 * into passive mode in next cycle (probably quicker) 538 */ 539 if (result) { 540 passive->flags.enabled = 0; 541 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 542 "Disabling passive cooling, still above threshold," 543 " but we are cooling down\n")); 544 } 545 } 546 return; 547 } 548 549 /* 550 * Below Trip? 551 * ----------- 552 * Implement passive cooling hysteresis to slowly increase performance 553 * and avoid thrashing around the passive trip point. Note that we 554 * assume symmetry. 555 */ 556 if (!passive->flags.enabled) 557 return; 558 for (i = 0; i < passive->devices.count; i++) 559 if (!acpi_processor_set_thermal_limit 560 (passive->devices.handles[i], 561 ACPI_PROCESSOR_LIMIT_DECREMENT)) 562 result = 0; 563 if (result) { 564 passive->flags.enabled = 0; 565 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 566 "Disabling passive cooling (zone is cool)\n")); 567 } 568 } 569 570 static void acpi_thermal_active(struct acpi_thermal *tz) 571 { 572 int result = 0; 573 struct acpi_thermal_active *active = NULL; 574 int i = 0; 575 int j = 0; 576 unsigned long maxtemp = 0; 577 578 579 if (!tz) 580 return; 581 582 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { 583 active = &(tz->trips.active[i]); 584 if (!active || !active->flags.valid) 585 break; 586 if (tz->temperature >= active->temperature) { 587 /* 588 * Above Threshold? 589 * ---------------- 590 * If not already enabled, turn ON all cooling devices 591 * associated with this active threshold. 592 */ 593 if (active->temperature > maxtemp) 594 tz->state.active_index = i; 595 maxtemp = active->temperature; 596 if (active->flags.enabled) 597 continue; 598 for (j = 0; j < active->devices.count; j++) { 599 result = 600 acpi_bus_set_power(active->devices. 601 handles[j], 602 ACPI_STATE_D0); 603 if (result) { 604 printk(KERN_WARNING PREFIX 605 "Unable to turn cooling device [%p] 'on'\n", 606 active->devices. 607 handles[j]); 608 continue; 609 } 610 active->flags.enabled = 1; 611 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 612 "Cooling device [%p] now 'on'\n", 613 active->devices.handles[j])); 614 } 615 continue; 616 } 617 if (!active->flags.enabled) 618 continue; 619 /* 620 * Below Threshold? 621 * ---------------- 622 * Turn OFF all cooling devices associated with this 623 * threshold. 624 */ 625 for (j = 0; j < active->devices.count; j++) { 626 result = acpi_bus_set_power(active->devices.handles[j], 627 ACPI_STATE_D3); 628 if (result) { 629 printk(KERN_WARNING PREFIX 630 "Unable to turn cooling device [%p] 'off'\n", 631 active->devices.handles[j]); 632 continue; 633 } 634 active->flags.enabled = 0; 635 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 636 "Cooling device [%p] now 'off'\n", 637 active->devices.handles[j])); 638 } 639 } 640 } 641 642 static void acpi_thermal_check(void *context); 643 644 static void acpi_thermal_run(unsigned long data) 645 { 646 struct acpi_thermal *tz = (struct acpi_thermal *)data; 647 if (!tz->zombie) 648 acpi_os_execute(OSL_GPE_HANDLER, acpi_thermal_check, (void *)data); 649 } 650 651 static void acpi_thermal_check(void *data) 652 { 653 int result = 0; 654 struct acpi_thermal *tz = data; 655 unsigned long sleep_time = 0; 656 int i = 0; 657 struct acpi_thermal_state state; 658 659 660 if (!tz) { 661 printk(KERN_ERR PREFIX "Invalid (NULL) context\n"); 662 return; 663 } 664 665 state = tz->state; 666 667 result = acpi_thermal_get_temperature(tz); 668 if (result) 669 return; 670 671 memset(&tz->state, 0, sizeof(tz->state)); 672 673 /* 674 * Check Trip Points 675 * ----------------- 676 * Compare the current temperature to the trip point values to see 677 * if we've entered one of the thermal policy states. Note that 678 * this function determines when a state is entered, but the 679 * individual policy decides when it is exited (e.g. hysteresis). 680 */ 681 if (tz->trips.critical.flags.valid) 682 state.critical |= 683 (tz->temperature >= tz->trips.critical.temperature); 684 if (tz->trips.hot.flags.valid) 685 state.hot |= (tz->temperature >= tz->trips.hot.temperature); 686 if (tz->trips.passive.flags.valid) 687 state.passive |= 688 (tz->temperature >= tz->trips.passive.temperature); 689 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) 690 if (tz->trips.active[i].flags.valid) 691 state.active |= 692 (tz->temperature >= 693 tz->trips.active[i].temperature); 694 695 /* 696 * Invoke Policy 697 * ------------- 698 * Separated from the above check to allow individual policy to 699 * determine when to exit a given state. 700 */ 701 if (state.critical) 702 acpi_thermal_critical(tz); 703 if (state.hot) 704 acpi_thermal_hot(tz); 705 if (state.passive) 706 acpi_thermal_passive(tz); 707 if (state.active) 708 acpi_thermal_active(tz); 709 710 /* 711 * Calculate State 712 * --------------- 713 * Again, separated from the above two to allow independent policy 714 * decisions. 715 */ 716 tz->state.critical = tz->trips.critical.flags.enabled; 717 tz->state.hot = tz->trips.hot.flags.enabled; 718 tz->state.passive = tz->trips.passive.flags.enabled; 719 tz->state.active = 0; 720 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) 721 tz->state.active |= tz->trips.active[i].flags.enabled; 722 723 /* 724 * Calculate Sleep Time 725 * -------------------- 726 * If we're in the passive state, use _TSP's value. Otherwise 727 * use the default polling frequency (e.g. _TZP). If no polling 728 * frequency is specified then we'll wait forever (at least until 729 * a thermal event occurs). Note that _TSP and _TZD values are 730 * given in 1/10th seconds (we must covert to milliseconds). 731 */ 732 if (tz->state.passive) 733 sleep_time = tz->trips.passive.tsp * 100; 734 else if (tz->polling_frequency > 0) 735 sleep_time = tz->polling_frequency * 100; 736 737 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s: temperature[%lu] sleep[%lu]\n", 738 tz->name, tz->temperature, sleep_time)); 739 740 /* 741 * Schedule Next Poll 742 * ------------------ 743 */ 744 if (!sleep_time) { 745 if (timer_pending(&(tz->timer))) 746 del_timer(&(tz->timer)); 747 } else { 748 if (timer_pending(&(tz->timer))) 749 mod_timer(&(tz->timer), 750 jiffies + (HZ * sleep_time) / 1000); 751 else { 752 tz->timer.data = (unsigned long)tz; 753 tz->timer.function = acpi_thermal_run; 754 tz->timer.expires = jiffies + (HZ * sleep_time) / 1000; 755 add_timer(&(tz->timer)); 756 } 757 } 758 759 return; 760 } 761 762 /* -------------------------------------------------------------------------- 763 FS Interface (/proc) 764 -------------------------------------------------------------------------- */ 765 766 static struct proc_dir_entry *acpi_thermal_dir; 767 768 static int acpi_thermal_state_seq_show(struct seq_file *seq, void *offset) 769 { 770 struct acpi_thermal *tz = seq->private; 771 772 773 if (!tz) 774 goto end; 775 776 seq_puts(seq, "state: "); 777 778 if (!tz->state.critical && !tz->state.hot && !tz->state.passive 779 && !tz->state.active) 780 seq_puts(seq, "ok\n"); 781 else { 782 if (tz->state.critical) 783 seq_puts(seq, "critical "); 784 if (tz->state.hot) 785 seq_puts(seq, "hot "); 786 if (tz->state.passive) 787 seq_puts(seq, "passive "); 788 if (tz->state.active) 789 seq_printf(seq, "active[%d]", tz->state.active_index); 790 seq_puts(seq, "\n"); 791 } 792 793 end: 794 return 0; 795 } 796 797 static int acpi_thermal_state_open_fs(struct inode *inode, struct file *file) 798 { 799 return single_open(file, acpi_thermal_state_seq_show, PDE(inode)->data); 800 } 801 802 static int acpi_thermal_temp_seq_show(struct seq_file *seq, void *offset) 803 { 804 int result = 0; 805 struct acpi_thermal *tz = seq->private; 806 807 808 if (!tz) 809 goto end; 810 811 result = acpi_thermal_get_temperature(tz); 812 if (result) 813 goto end; 814 815 seq_printf(seq, "temperature: %ld C\n", 816 KELVIN_TO_CELSIUS(tz->temperature)); 817 818 end: 819 return 0; 820 } 821 822 static int acpi_thermal_temp_open_fs(struct inode *inode, struct file *file) 823 { 824 return single_open(file, acpi_thermal_temp_seq_show, PDE(inode)->data); 825 } 826 827 static int acpi_thermal_trip_seq_show(struct seq_file *seq, void *offset) 828 { 829 struct acpi_thermal *tz = seq->private; 830 struct acpi_device *device; 831 acpi_status status; 832 833 int i = 0; 834 int j = 0; 835 836 837 if (!tz) 838 goto end; 839 840 if (tz->trips.critical.flags.valid) 841 seq_printf(seq, "critical (S5): %ld C\n", 842 KELVIN_TO_CELSIUS(tz->trips.critical.temperature)); 843 844 if (tz->trips.hot.flags.valid) 845 seq_printf(seq, "hot (S4): %ld C\n", 846 KELVIN_TO_CELSIUS(tz->trips.hot.temperature)); 847 848 if (tz->trips.passive.flags.valid) { 849 seq_printf(seq, 850 "passive: %ld C: tc1=%lu tc2=%lu tsp=%lu devices=", 851 KELVIN_TO_CELSIUS(tz->trips.passive.temperature), 852 tz->trips.passive.tc1, tz->trips.passive.tc2, 853 tz->trips.passive.tsp); 854 for (j = 0; j < tz->trips.passive.devices.count; j++) { 855 status = acpi_bus_get_device(tz->trips.passive.devices. 856 handles[j], &device); 857 seq_printf(seq, "%4.4s ", status ? "" : 858 acpi_device_bid(device)); 859 } 860 seq_puts(seq, "\n"); 861 } 862 863 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { 864 if (!(tz->trips.active[i].flags.valid)) 865 break; 866 seq_printf(seq, "active[%d]: %ld C: devices=", 867 i, 868 KELVIN_TO_CELSIUS(tz->trips.active[i].temperature)); 869 for (j = 0; j < tz->trips.active[i].devices.count; j++){ 870 status = acpi_bus_get_device(tz->trips.active[i]. 871 devices.handles[j], 872 &device); 873 seq_printf(seq, "%4.4s ", status ? "" : 874 acpi_device_bid(device)); 875 } 876 seq_puts(seq, "\n"); 877 } 878 879 end: 880 return 0; 881 } 882 883 static int acpi_thermal_trip_open_fs(struct inode *inode, struct file *file) 884 { 885 return single_open(file, acpi_thermal_trip_seq_show, PDE(inode)->data); 886 } 887 888 static int acpi_thermal_cooling_seq_show(struct seq_file *seq, void *offset) 889 { 890 struct acpi_thermal *tz = seq->private; 891 892 893 if (!tz) 894 goto end; 895 896 if (!tz->flags.cooling_mode) 897 seq_puts(seq, "<setting not supported>\n"); 898 else 899 seq_puts(seq, "0 - Active; 1 - Passive\n"); 900 901 end: 902 return 0; 903 } 904 905 static int acpi_thermal_cooling_open_fs(struct inode *inode, struct file *file) 906 { 907 return single_open(file, acpi_thermal_cooling_seq_show, 908 PDE(inode)->data); 909 } 910 911 static ssize_t 912 acpi_thermal_write_cooling_mode(struct file *file, 913 const char __user * buffer, 914 size_t count, loff_t * ppos) 915 { 916 struct seq_file *m = file->private_data; 917 struct acpi_thermal *tz = m->private; 918 int result = 0; 919 char mode_string[12] = { '\0' }; 920 921 922 if (!tz || (count > sizeof(mode_string) - 1)) 923 return -EINVAL; 924 925 if (!tz->flags.cooling_mode) 926 return -ENODEV; 927 928 if (copy_from_user(mode_string, buffer, count)) 929 return -EFAULT; 930 931 mode_string[count] = '\0'; 932 933 result = acpi_thermal_set_cooling_mode(tz, 934 simple_strtoul(mode_string, NULL, 935 0)); 936 if (result) 937 return result; 938 939 acpi_thermal_check(tz); 940 941 return count; 942 } 943 944 static int acpi_thermal_polling_seq_show(struct seq_file *seq, void *offset) 945 { 946 struct acpi_thermal *tz = seq->private; 947 948 949 if (!tz) 950 goto end; 951 952 if (!tz->polling_frequency) { 953 seq_puts(seq, "<polling disabled>\n"); 954 goto end; 955 } 956 957 seq_printf(seq, "polling frequency: %lu seconds\n", 958 (tz->polling_frequency / 10)); 959 960 end: 961 return 0; 962 } 963 964 static int acpi_thermal_polling_open_fs(struct inode *inode, struct file *file) 965 { 966 return single_open(file, acpi_thermal_polling_seq_show, 967 PDE(inode)->data); 968 } 969 970 static ssize_t 971 acpi_thermal_write_polling(struct file *file, 972 const char __user * buffer, 973 size_t count, loff_t * ppos) 974 { 975 struct seq_file *m = file->private_data; 976 struct acpi_thermal *tz = m->private; 977 int result = 0; 978 char polling_string[12] = { '\0' }; 979 int seconds = 0; 980 981 982 if (!tz || (count > sizeof(polling_string) - 1)) 983 return -EINVAL; 984 985 if (copy_from_user(polling_string, buffer, count)) 986 return -EFAULT; 987 988 polling_string[count] = '\0'; 989 990 seconds = simple_strtoul(polling_string, NULL, 0); 991 992 result = acpi_thermal_set_polling(tz, seconds); 993 if (result) 994 return result; 995 996 acpi_thermal_check(tz); 997 998 return count; 999 } 1000 1001 static int acpi_thermal_add_fs(struct acpi_device *device) 1002 { 1003 struct proc_dir_entry *entry = NULL; 1004 1005 1006 if (!acpi_device_dir(device)) { 1007 acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), 1008 acpi_thermal_dir); 1009 if (!acpi_device_dir(device)) 1010 return -ENODEV; 1011 acpi_device_dir(device)->owner = THIS_MODULE; 1012 } 1013 1014 /* 'state' [R] */ 1015 entry = create_proc_entry(ACPI_THERMAL_FILE_STATE, 1016 S_IRUGO, acpi_device_dir(device)); 1017 if (!entry) 1018 return -ENODEV; 1019 else { 1020 entry->proc_fops = &acpi_thermal_state_fops; 1021 entry->data = acpi_driver_data(device); 1022 entry->owner = THIS_MODULE; 1023 } 1024 1025 /* 'temperature' [R] */ 1026 entry = create_proc_entry(ACPI_THERMAL_FILE_TEMPERATURE, 1027 S_IRUGO, acpi_device_dir(device)); 1028 if (!entry) 1029 return -ENODEV; 1030 else { 1031 entry->proc_fops = &acpi_thermal_temp_fops; 1032 entry->data = acpi_driver_data(device); 1033 entry->owner = THIS_MODULE; 1034 } 1035 1036 /* 'trip_points' [R/W] */ 1037 entry = create_proc_entry(ACPI_THERMAL_FILE_TRIP_POINTS, 1038 S_IFREG | S_IRUGO | S_IWUSR, 1039 acpi_device_dir(device)); 1040 if (!entry) 1041 return -ENODEV; 1042 else { 1043 entry->proc_fops = &acpi_thermal_trip_fops; 1044 entry->data = acpi_driver_data(device); 1045 entry->owner = THIS_MODULE; 1046 } 1047 1048 /* 'cooling_mode' [R/W] */ 1049 entry = create_proc_entry(ACPI_THERMAL_FILE_COOLING_MODE, 1050 S_IFREG | S_IRUGO | S_IWUSR, 1051 acpi_device_dir(device)); 1052 if (!entry) 1053 return -ENODEV; 1054 else { 1055 entry->proc_fops = &acpi_thermal_cooling_fops; 1056 entry->data = acpi_driver_data(device); 1057 entry->owner = THIS_MODULE; 1058 } 1059 1060 /* 'polling_frequency' [R/W] */ 1061 entry = create_proc_entry(ACPI_THERMAL_FILE_POLLING_FREQ, 1062 S_IFREG | S_IRUGO | S_IWUSR, 1063 acpi_device_dir(device)); 1064 if (!entry) 1065 return -ENODEV; 1066 else { 1067 entry->proc_fops = &acpi_thermal_polling_fops; 1068 entry->data = acpi_driver_data(device); 1069 entry->owner = THIS_MODULE; 1070 } 1071 1072 return 0; 1073 } 1074 1075 static int acpi_thermal_remove_fs(struct acpi_device *device) 1076 { 1077 1078 if (acpi_device_dir(device)) { 1079 remove_proc_entry(ACPI_THERMAL_FILE_POLLING_FREQ, 1080 acpi_device_dir(device)); 1081 remove_proc_entry(ACPI_THERMAL_FILE_COOLING_MODE, 1082 acpi_device_dir(device)); 1083 remove_proc_entry(ACPI_THERMAL_FILE_TRIP_POINTS, 1084 acpi_device_dir(device)); 1085 remove_proc_entry(ACPI_THERMAL_FILE_TEMPERATURE, 1086 acpi_device_dir(device)); 1087 remove_proc_entry(ACPI_THERMAL_FILE_STATE, 1088 acpi_device_dir(device)); 1089 remove_proc_entry(acpi_device_bid(device), acpi_thermal_dir); 1090 acpi_device_dir(device) = NULL; 1091 } 1092 1093 return 0; 1094 } 1095 1096 /* -------------------------------------------------------------------------- 1097 Driver Interface 1098 -------------------------------------------------------------------------- */ 1099 1100 static void acpi_thermal_notify(acpi_handle handle, u32 event, void *data) 1101 { 1102 struct acpi_thermal *tz = data; 1103 struct acpi_device *device = NULL; 1104 1105 1106 if (!tz) 1107 return; 1108 1109 device = tz->device; 1110 1111 switch (event) { 1112 case ACPI_THERMAL_NOTIFY_TEMPERATURE: 1113 acpi_thermal_check(tz); 1114 break; 1115 case ACPI_THERMAL_NOTIFY_THRESHOLDS: 1116 acpi_thermal_get_trip_points(tz); 1117 acpi_thermal_check(tz); 1118 acpi_bus_generate_event(device, event, 0); 1119 break; 1120 case ACPI_THERMAL_NOTIFY_DEVICES: 1121 if (tz->flags.devices) 1122 acpi_thermal_get_devices(tz); 1123 acpi_bus_generate_event(device, event, 0); 1124 break; 1125 default: 1126 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 1127 "Unsupported event [0x%x]\n", event)); 1128 break; 1129 } 1130 1131 return; 1132 } 1133 1134 static int acpi_thermal_get_info(struct acpi_thermal *tz) 1135 { 1136 int result = 0; 1137 1138 1139 if (!tz) 1140 return -EINVAL; 1141 1142 /* Get temperature [_TMP] (required) */ 1143 result = acpi_thermal_get_temperature(tz); 1144 if (result) 1145 return result; 1146 1147 /* Get trip points [_CRT, _PSV, etc.] (required) */ 1148 result = acpi_thermal_get_trip_points(tz); 1149 if (result) 1150 return result; 1151 1152 /* Set the cooling mode [_SCP] to active cooling (default) */ 1153 result = acpi_thermal_set_cooling_mode(tz, ACPI_THERMAL_MODE_ACTIVE); 1154 if (!result) 1155 tz->flags.cooling_mode = 1; 1156 1157 /* Get default polling frequency [_TZP] (optional) */ 1158 if (tzp) 1159 tz->polling_frequency = tzp; 1160 else 1161 acpi_thermal_get_polling_frequency(tz); 1162 1163 /* Get devices in this thermal zone [_TZD] (optional) */ 1164 result = acpi_thermal_get_devices(tz); 1165 if (!result) 1166 tz->flags.devices = 1; 1167 1168 return 0; 1169 } 1170 1171 static int acpi_thermal_add(struct acpi_device *device) 1172 { 1173 int result = 0; 1174 acpi_status status = AE_OK; 1175 struct acpi_thermal *tz = NULL; 1176 1177 1178 if (!device) 1179 return -EINVAL; 1180 1181 tz = kzalloc(sizeof(struct acpi_thermal), GFP_KERNEL); 1182 if (!tz) 1183 return -ENOMEM; 1184 1185 tz->device = device; 1186 strcpy(tz->name, device->pnp.bus_id); 1187 strcpy(acpi_device_name(device), ACPI_THERMAL_DEVICE_NAME); 1188 strcpy(acpi_device_class(device), ACPI_THERMAL_CLASS); 1189 acpi_driver_data(device) = tz; 1190 1191 result = acpi_thermal_get_info(tz); 1192 if (result) 1193 goto end; 1194 1195 result = acpi_thermal_add_fs(device); 1196 if (result) 1197 goto end; 1198 1199 init_timer(&tz->timer); 1200 1201 acpi_thermal_check(tz); 1202 1203 status = acpi_install_notify_handler(device->handle, 1204 ACPI_DEVICE_NOTIFY, 1205 acpi_thermal_notify, tz); 1206 if (ACPI_FAILURE(status)) { 1207 result = -ENODEV; 1208 goto end; 1209 } 1210 1211 printk(KERN_INFO PREFIX "%s [%s] (%ld C)\n", 1212 acpi_device_name(device), acpi_device_bid(device), 1213 KELVIN_TO_CELSIUS(tz->temperature)); 1214 1215 end: 1216 if (result) { 1217 acpi_thermal_remove_fs(device); 1218 kfree(tz); 1219 } 1220 1221 return result; 1222 } 1223 1224 static int acpi_thermal_remove(struct acpi_device *device, int type) 1225 { 1226 acpi_status status = AE_OK; 1227 struct acpi_thermal *tz = NULL; 1228 1229 1230 if (!device || !acpi_driver_data(device)) 1231 return -EINVAL; 1232 1233 tz = acpi_driver_data(device); 1234 1235 /* avoid timer adding new defer task */ 1236 tz->zombie = 1; 1237 /* wait for running timer (on other CPUs) finish */ 1238 del_timer_sync(&(tz->timer)); 1239 /* synchronize deferred task */ 1240 acpi_os_wait_events_complete(NULL); 1241 /* deferred task may reinsert timer */ 1242 del_timer_sync(&(tz->timer)); 1243 1244 status = acpi_remove_notify_handler(device->handle, 1245 ACPI_DEVICE_NOTIFY, 1246 acpi_thermal_notify); 1247 1248 /* Terminate policy */ 1249 if (tz->trips.passive.flags.valid && tz->trips.passive.flags.enabled) { 1250 tz->trips.passive.flags.enabled = 0; 1251 acpi_thermal_passive(tz); 1252 } 1253 if (tz->trips.active[0].flags.valid 1254 && tz->trips.active[0].flags.enabled) { 1255 tz->trips.active[0].flags.enabled = 0; 1256 acpi_thermal_active(tz); 1257 } 1258 1259 acpi_thermal_remove_fs(device); 1260 1261 kfree(tz); 1262 return 0; 1263 } 1264 1265 static int acpi_thermal_resume(struct acpi_device *device) 1266 { 1267 struct acpi_thermal *tz = NULL; 1268 int i, j, power_state, result; 1269 1270 1271 if (!device || !acpi_driver_data(device)) 1272 return -EINVAL; 1273 1274 tz = acpi_driver_data(device); 1275 1276 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { 1277 if (!(&tz->trips.active[i])) 1278 break; 1279 if (!tz->trips.active[i].flags.valid) 1280 break; 1281 tz->trips.active[i].flags.enabled = 1; 1282 for (j = 0; j < tz->trips.active[i].devices.count; j++) { 1283 result = acpi_bus_get_power(tz->trips.active[i].devices. 1284 handles[j], &power_state); 1285 if (result || (power_state != ACPI_STATE_D0)) { 1286 tz->trips.active[i].flags.enabled = 0; 1287 break; 1288 } 1289 } 1290 tz->state.active |= tz->trips.active[i].flags.enabled; 1291 } 1292 1293 acpi_thermal_check(tz); 1294 1295 return AE_OK; 1296 } 1297 1298 static int __init acpi_thermal_init(void) 1299 { 1300 int result = 0; 1301 1302 1303 acpi_thermal_dir = proc_mkdir(ACPI_THERMAL_CLASS, acpi_root_dir); 1304 if (!acpi_thermal_dir) 1305 return -ENODEV; 1306 acpi_thermal_dir->owner = THIS_MODULE; 1307 1308 result = acpi_bus_register_driver(&acpi_thermal_driver); 1309 if (result < 0) { 1310 remove_proc_entry(ACPI_THERMAL_CLASS, acpi_root_dir); 1311 return -ENODEV; 1312 } 1313 1314 return 0; 1315 } 1316 1317 static void __exit acpi_thermal_exit(void) 1318 { 1319 1320 acpi_bus_unregister_driver(&acpi_thermal_driver); 1321 1322 remove_proc_entry(ACPI_THERMAL_CLASS, acpi_root_dir); 1323 1324 return; 1325 } 1326 1327 module_init(acpi_thermal_init); 1328 module_exit(acpi_thermal_exit); 1329