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