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