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_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("thermal"); 74 75 MODULE_AUTHOR("Paul Diefenbaugh"); 76 MODULE_DESCRIPTION("ACPI Thermal Zone Driver"); 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); 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 = "thermal", 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 const 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 const 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 const 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 const 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 const 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/10)); 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 = 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), 762 jiffies + (HZ * sleep_time) / 1000); 763 else { 764 tz->timer.data = (unsigned long)tz; 765 tz->timer.function = acpi_thermal_run; 766 tz->timer.expires = jiffies + (HZ * sleep_time) / 1000; 767 add_timer(&(tz->timer)); 768 } 769 } 770 771 return; 772 } 773 774 /* -------------------------------------------------------------------------- 775 FS Interface (/proc) 776 -------------------------------------------------------------------------- */ 777 778 static struct proc_dir_entry *acpi_thermal_dir; 779 780 static int acpi_thermal_state_seq_show(struct seq_file *seq, void *offset) 781 { 782 struct acpi_thermal *tz = seq->private; 783 784 785 if (!tz) 786 goto end; 787 788 seq_puts(seq, "state: "); 789 790 if (!tz->state.critical && !tz->state.hot && !tz->state.passive 791 && !tz->state.active) 792 seq_puts(seq, "ok\n"); 793 else { 794 if (tz->state.critical) 795 seq_puts(seq, "critical "); 796 if (tz->state.hot) 797 seq_puts(seq, "hot "); 798 if (tz->state.passive) 799 seq_puts(seq, "passive "); 800 if (tz->state.active) 801 seq_printf(seq, "active[%d]", tz->state.active_index); 802 seq_puts(seq, "\n"); 803 } 804 805 end: 806 return 0; 807 } 808 809 static int acpi_thermal_state_open_fs(struct inode *inode, struct file *file) 810 { 811 return single_open(file, acpi_thermal_state_seq_show, PDE(inode)->data); 812 } 813 814 static int acpi_thermal_temp_seq_show(struct seq_file *seq, void *offset) 815 { 816 int result = 0; 817 struct acpi_thermal *tz = seq->private; 818 819 820 if (!tz) 821 goto end; 822 823 result = acpi_thermal_get_temperature(tz); 824 if (result) 825 goto end; 826 827 seq_printf(seq, "temperature: %ld C\n", 828 KELVIN_TO_CELSIUS(tz->temperature)); 829 830 end: 831 return 0; 832 } 833 834 static int acpi_thermal_temp_open_fs(struct inode *inode, struct file *file) 835 { 836 return single_open(file, acpi_thermal_temp_seq_show, PDE(inode)->data); 837 } 838 839 static int acpi_thermal_trip_seq_show(struct seq_file *seq, void *offset) 840 { 841 struct acpi_thermal *tz = seq->private; 842 int i = 0; 843 int j = 0; 844 845 846 if (!tz) 847 goto end; 848 849 if (tz->trips.critical.flags.valid) 850 seq_printf(seq, "critical (S5): %ld C\n", 851 KELVIN_TO_CELSIUS(tz->trips.critical.temperature)); 852 853 if (tz->trips.hot.flags.valid) 854 seq_printf(seq, "hot (S4): %ld C\n", 855 KELVIN_TO_CELSIUS(tz->trips.hot.temperature)); 856 857 if (tz->trips.passive.flags.valid) { 858 seq_printf(seq, 859 "passive: %ld C: tc1=%lu tc2=%lu tsp=%lu devices=", 860 KELVIN_TO_CELSIUS(tz->trips.passive.temperature), 861 tz->trips.passive.tc1, tz->trips.passive.tc2, 862 tz->trips.passive.tsp); 863 for (j = 0; j < tz->trips.passive.devices.count; j++) { 864 865 seq_printf(seq, "0x%p ", 866 tz->trips.passive.devices.handles[j]); 867 } 868 seq_puts(seq, "\n"); 869 } 870 871 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { 872 if (!(tz->trips.active[i].flags.valid)) 873 break; 874 seq_printf(seq, "active[%d]: %ld C: devices=", 875 i, 876 KELVIN_TO_CELSIUS(tz->trips.active[i].temperature)); 877 for (j = 0; j < tz->trips.active[i].devices.count; j++) 878 seq_printf(seq, "0x%p ", 879 tz->trips.active[i].devices.handles[j]); 880 seq_puts(seq, "\n"); 881 } 882 883 end: 884 return 0; 885 } 886 887 static int acpi_thermal_trip_open_fs(struct inode *inode, struct file *file) 888 { 889 return single_open(file, acpi_thermal_trip_seq_show, PDE(inode)->data); 890 } 891 892 static ssize_t 893 acpi_thermal_write_trip_points(struct file *file, 894 const char __user * buffer, 895 size_t count, loff_t * ppos) 896 { 897 struct seq_file *m = file->private_data; 898 struct acpi_thermal *tz = m->private; 899 900 char *limit_string; 901 int num, critical, hot, passive; 902 int *active; 903 int i = 0; 904 905 906 limit_string = kzalloc(ACPI_THERMAL_MAX_LIMIT_STR_LEN, GFP_KERNEL); 907 if (!limit_string) 908 return -ENOMEM; 909 910 active = kmalloc(ACPI_THERMAL_MAX_ACTIVE * sizeof(int), GFP_KERNEL); 911 if (!active) { 912 kfree(limit_string); 913 return -ENOMEM; 914 } 915 916 if (!tz || (count > ACPI_THERMAL_MAX_LIMIT_STR_LEN - 1)) { 917 count = -EINVAL; 918 goto end; 919 } 920 921 if (copy_from_user(limit_string, buffer, count)) { 922 count = -EFAULT; 923 goto end; 924 } 925 926 limit_string[count] = '\0'; 927 928 num = sscanf(limit_string, "%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d", 929 &critical, &hot, &passive, 930 &active[0], &active[1], &active[2], &active[3], &active[4], 931 &active[5], &active[6], &active[7], &active[8], 932 &active[9]); 933 if (!(num >= 5 && num < (ACPI_THERMAL_MAX_ACTIVE + 3))) { 934 count = -EINVAL; 935 goto end; 936 } 937 938 tz->trips.critical.temperature = CELSIUS_TO_KELVIN(critical); 939 tz->trips.hot.temperature = CELSIUS_TO_KELVIN(hot); 940 tz->trips.passive.temperature = CELSIUS_TO_KELVIN(passive); 941 for (i = 0; i < num - 3; i++) { 942 if (!(tz->trips.active[i].flags.valid)) 943 break; 944 tz->trips.active[i].temperature = CELSIUS_TO_KELVIN(active[i]); 945 } 946 947 end: 948 kfree(active); 949 kfree(limit_string); 950 return count; 951 } 952 953 static int acpi_thermal_cooling_seq_show(struct seq_file *seq, void *offset) 954 { 955 struct acpi_thermal *tz = seq->private; 956 957 958 if (!tz) 959 goto end; 960 961 if (!tz->flags.cooling_mode) { 962 seq_puts(seq, "<setting not supported>\n"); 963 } 964 965 if (tz->cooling_mode == ACPI_THERMAL_MODE_CRITICAL) 966 seq_printf(seq, "cooling mode: critical\n"); 967 else 968 seq_printf(seq, "cooling mode: %s\n", 969 tz->cooling_mode ? "passive" : "active"); 970 971 end: 972 return 0; 973 } 974 975 static int acpi_thermal_cooling_open_fs(struct inode *inode, struct file *file) 976 { 977 return single_open(file, acpi_thermal_cooling_seq_show, 978 PDE(inode)->data); 979 } 980 981 static ssize_t 982 acpi_thermal_write_cooling_mode(struct file *file, 983 const char __user * buffer, 984 size_t count, loff_t * ppos) 985 { 986 struct seq_file *m = file->private_data; 987 struct acpi_thermal *tz = m->private; 988 int result = 0; 989 char mode_string[12] = { '\0' }; 990 991 992 if (!tz || (count > sizeof(mode_string) - 1)) 993 return -EINVAL; 994 995 if (!tz->flags.cooling_mode) 996 return -ENODEV; 997 998 if (copy_from_user(mode_string, buffer, count)) 999 return -EFAULT; 1000 1001 mode_string[count] = '\0'; 1002 1003 result = acpi_thermal_set_cooling_mode(tz, 1004 simple_strtoul(mode_string, NULL, 1005 0)); 1006 if (result) 1007 return result; 1008 1009 acpi_thermal_check(tz); 1010 1011 return count; 1012 } 1013 1014 static int acpi_thermal_polling_seq_show(struct seq_file *seq, void *offset) 1015 { 1016 struct acpi_thermal *tz = seq->private; 1017 1018 1019 if (!tz) 1020 goto end; 1021 1022 if (!tz->polling_frequency) { 1023 seq_puts(seq, "<polling disabled>\n"); 1024 goto end; 1025 } 1026 1027 seq_printf(seq, "polling frequency: %lu seconds\n", 1028 (tz->polling_frequency / 10)); 1029 1030 end: 1031 return 0; 1032 } 1033 1034 static int acpi_thermal_polling_open_fs(struct inode *inode, struct file *file) 1035 { 1036 return single_open(file, acpi_thermal_polling_seq_show, 1037 PDE(inode)->data); 1038 } 1039 1040 static ssize_t 1041 acpi_thermal_write_polling(struct file *file, 1042 const char __user * buffer, 1043 size_t count, loff_t * ppos) 1044 { 1045 struct seq_file *m = file->private_data; 1046 struct acpi_thermal *tz = m->private; 1047 int result = 0; 1048 char polling_string[12] = { '\0' }; 1049 int seconds = 0; 1050 1051 1052 if (!tz || (count > sizeof(polling_string) - 1)) 1053 return -EINVAL; 1054 1055 if (copy_from_user(polling_string, buffer, count)) 1056 return -EFAULT; 1057 1058 polling_string[count] = '\0'; 1059 1060 seconds = simple_strtoul(polling_string, NULL, 0); 1061 1062 result = acpi_thermal_set_polling(tz, seconds); 1063 if (result) 1064 return result; 1065 1066 acpi_thermal_check(tz); 1067 1068 return count; 1069 } 1070 1071 static int acpi_thermal_add_fs(struct acpi_device *device) 1072 { 1073 struct proc_dir_entry *entry = NULL; 1074 1075 1076 if (!acpi_device_dir(device)) { 1077 acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), 1078 acpi_thermal_dir); 1079 if (!acpi_device_dir(device)) 1080 return -ENODEV; 1081 acpi_device_dir(device)->owner = THIS_MODULE; 1082 } 1083 1084 /* 'state' [R] */ 1085 entry = create_proc_entry(ACPI_THERMAL_FILE_STATE, 1086 S_IRUGO, acpi_device_dir(device)); 1087 if (!entry) 1088 return -ENODEV; 1089 else { 1090 entry->proc_fops = &acpi_thermal_state_fops; 1091 entry->data = acpi_driver_data(device); 1092 entry->owner = THIS_MODULE; 1093 } 1094 1095 /* 'temperature' [R] */ 1096 entry = create_proc_entry(ACPI_THERMAL_FILE_TEMPERATURE, 1097 S_IRUGO, acpi_device_dir(device)); 1098 if (!entry) 1099 return -ENODEV; 1100 else { 1101 entry->proc_fops = &acpi_thermal_temp_fops; 1102 entry->data = acpi_driver_data(device); 1103 entry->owner = THIS_MODULE; 1104 } 1105 1106 /* 'trip_points' [R/W] */ 1107 entry = create_proc_entry(ACPI_THERMAL_FILE_TRIP_POINTS, 1108 S_IFREG | S_IRUGO | S_IWUSR, 1109 acpi_device_dir(device)); 1110 if (!entry) 1111 return -ENODEV; 1112 else { 1113 entry->proc_fops = &acpi_thermal_trip_fops; 1114 entry->data = acpi_driver_data(device); 1115 entry->owner = THIS_MODULE; 1116 } 1117 1118 /* 'cooling_mode' [R/W] */ 1119 entry = create_proc_entry(ACPI_THERMAL_FILE_COOLING_MODE, 1120 S_IFREG | S_IRUGO | S_IWUSR, 1121 acpi_device_dir(device)); 1122 if (!entry) 1123 return -ENODEV; 1124 else { 1125 entry->proc_fops = &acpi_thermal_cooling_fops; 1126 entry->data = acpi_driver_data(device); 1127 entry->owner = THIS_MODULE; 1128 } 1129 1130 /* 'polling_frequency' [R/W] */ 1131 entry = create_proc_entry(ACPI_THERMAL_FILE_POLLING_FREQ, 1132 S_IFREG | S_IRUGO | S_IWUSR, 1133 acpi_device_dir(device)); 1134 if (!entry) 1135 return -ENODEV; 1136 else { 1137 entry->proc_fops = &acpi_thermal_polling_fops; 1138 entry->data = acpi_driver_data(device); 1139 entry->owner = THIS_MODULE; 1140 } 1141 1142 return 0; 1143 } 1144 1145 static int acpi_thermal_remove_fs(struct acpi_device *device) 1146 { 1147 1148 if (acpi_device_dir(device)) { 1149 remove_proc_entry(ACPI_THERMAL_FILE_POLLING_FREQ, 1150 acpi_device_dir(device)); 1151 remove_proc_entry(ACPI_THERMAL_FILE_COOLING_MODE, 1152 acpi_device_dir(device)); 1153 remove_proc_entry(ACPI_THERMAL_FILE_TRIP_POINTS, 1154 acpi_device_dir(device)); 1155 remove_proc_entry(ACPI_THERMAL_FILE_TEMPERATURE, 1156 acpi_device_dir(device)); 1157 remove_proc_entry(ACPI_THERMAL_FILE_STATE, 1158 acpi_device_dir(device)); 1159 remove_proc_entry(acpi_device_bid(device), acpi_thermal_dir); 1160 acpi_device_dir(device) = NULL; 1161 } 1162 1163 return 0; 1164 } 1165 1166 /* -------------------------------------------------------------------------- 1167 Driver Interface 1168 -------------------------------------------------------------------------- */ 1169 1170 static void acpi_thermal_notify(acpi_handle handle, u32 event, void *data) 1171 { 1172 struct acpi_thermal *tz = data; 1173 struct acpi_device *device = NULL; 1174 1175 1176 if (!tz) 1177 return; 1178 1179 device = tz->device; 1180 1181 switch (event) { 1182 case ACPI_THERMAL_NOTIFY_TEMPERATURE: 1183 acpi_thermal_check(tz); 1184 break; 1185 case ACPI_THERMAL_NOTIFY_THRESHOLDS: 1186 acpi_thermal_get_trip_points(tz); 1187 acpi_thermal_check(tz); 1188 acpi_bus_generate_event(device, event, 0); 1189 break; 1190 case ACPI_THERMAL_NOTIFY_DEVICES: 1191 if (tz->flags.devices) 1192 acpi_thermal_get_devices(tz); 1193 acpi_bus_generate_event(device, event, 0); 1194 break; 1195 default: 1196 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 1197 "Unsupported event [0x%x]\n", event)); 1198 break; 1199 } 1200 1201 return; 1202 } 1203 1204 static int acpi_thermal_get_info(struct acpi_thermal *tz) 1205 { 1206 int result = 0; 1207 1208 1209 if (!tz) 1210 return -EINVAL; 1211 1212 /* Get temperature [_TMP] (required) */ 1213 result = acpi_thermal_get_temperature(tz); 1214 if (result) 1215 return result; 1216 1217 /* Get trip points [_CRT, _PSV, etc.] (required) */ 1218 result = acpi_thermal_get_trip_points(tz); 1219 if (result) 1220 return result; 1221 1222 /* Set the cooling mode [_SCP] to active cooling (default) */ 1223 result = acpi_thermal_set_cooling_mode(tz, ACPI_THERMAL_MODE_ACTIVE); 1224 if (!result) 1225 tz->flags.cooling_mode = 1; 1226 else { 1227 /* Oh,we have not _SCP method. 1228 Generally show cooling_mode by _ACx, _PSV,spec 12.2 */ 1229 tz->flags.cooling_mode = 0; 1230 if (tz->trips.active[0].flags.valid 1231 && tz->trips.passive.flags.valid) { 1232 if (tz->trips.passive.temperature > 1233 tz->trips.active[0].temperature) 1234 tz->cooling_mode = ACPI_THERMAL_MODE_ACTIVE; 1235 else 1236 tz->cooling_mode = ACPI_THERMAL_MODE_PASSIVE; 1237 } else if (!tz->trips.active[0].flags.valid 1238 && tz->trips.passive.flags.valid) { 1239 tz->cooling_mode = ACPI_THERMAL_MODE_PASSIVE; 1240 } else if (tz->trips.active[0].flags.valid 1241 && !tz->trips.passive.flags.valid) { 1242 tz->cooling_mode = ACPI_THERMAL_MODE_ACTIVE; 1243 } else { 1244 /* _ACx and _PSV are optional, but _CRT is required */ 1245 tz->cooling_mode = ACPI_THERMAL_MODE_CRITICAL; 1246 } 1247 } 1248 1249 /* Get default polling frequency [_TZP] (optional) */ 1250 if (tzp) 1251 tz->polling_frequency = tzp; 1252 else 1253 acpi_thermal_get_polling_frequency(tz); 1254 1255 /* Get devices in this thermal zone [_TZD] (optional) */ 1256 result = acpi_thermal_get_devices(tz); 1257 if (!result) 1258 tz->flags.devices = 1; 1259 1260 return 0; 1261 } 1262 1263 static int acpi_thermal_add(struct acpi_device *device) 1264 { 1265 int result = 0; 1266 acpi_status status = AE_OK; 1267 struct acpi_thermal *tz = NULL; 1268 1269 1270 if (!device) 1271 return -EINVAL; 1272 1273 tz = kzalloc(sizeof(struct acpi_thermal), GFP_KERNEL); 1274 if (!tz) 1275 return -ENOMEM; 1276 1277 tz->device = device; 1278 strcpy(tz->name, device->pnp.bus_id); 1279 strcpy(acpi_device_name(device), ACPI_THERMAL_DEVICE_NAME); 1280 strcpy(acpi_device_class(device), ACPI_THERMAL_CLASS); 1281 acpi_driver_data(device) = tz; 1282 1283 result = acpi_thermal_get_info(tz); 1284 if (result) 1285 goto end; 1286 1287 result = acpi_thermal_add_fs(device); 1288 if (result) 1289 goto end; 1290 1291 init_timer(&tz->timer); 1292 1293 acpi_thermal_check(tz); 1294 1295 status = acpi_install_notify_handler(device->handle, 1296 ACPI_DEVICE_NOTIFY, 1297 acpi_thermal_notify, tz); 1298 if (ACPI_FAILURE(status)) { 1299 result = -ENODEV; 1300 goto end; 1301 } 1302 1303 printk(KERN_INFO PREFIX "%s [%s] (%ld C)\n", 1304 acpi_device_name(device), acpi_device_bid(device), 1305 KELVIN_TO_CELSIUS(tz->temperature)); 1306 1307 end: 1308 if (result) { 1309 acpi_thermal_remove_fs(device); 1310 kfree(tz); 1311 } 1312 1313 return result; 1314 } 1315 1316 static int acpi_thermal_remove(struct acpi_device *device, int type) 1317 { 1318 acpi_status status = AE_OK; 1319 struct acpi_thermal *tz = NULL; 1320 1321 1322 if (!device || !acpi_driver_data(device)) 1323 return -EINVAL; 1324 1325 tz = acpi_driver_data(device); 1326 1327 /* avoid timer adding new defer task */ 1328 tz->zombie = 1; 1329 /* wait for running timer (on other CPUs) finish */ 1330 del_timer_sync(&(tz->timer)); 1331 /* synchronize deferred task */ 1332 acpi_os_wait_events_complete(NULL); 1333 /* deferred task may reinsert timer */ 1334 del_timer_sync(&(tz->timer)); 1335 1336 status = acpi_remove_notify_handler(device->handle, 1337 ACPI_DEVICE_NOTIFY, 1338 acpi_thermal_notify); 1339 1340 /* Terminate policy */ 1341 if (tz->trips.passive.flags.valid && tz->trips.passive.flags.enabled) { 1342 tz->trips.passive.flags.enabled = 0; 1343 acpi_thermal_passive(tz); 1344 } 1345 if (tz->trips.active[0].flags.valid 1346 && tz->trips.active[0].flags.enabled) { 1347 tz->trips.active[0].flags.enabled = 0; 1348 acpi_thermal_active(tz); 1349 } 1350 1351 acpi_thermal_remove_fs(device); 1352 1353 kfree(tz); 1354 return 0; 1355 } 1356 1357 static int acpi_thermal_resume(struct acpi_device *device) 1358 { 1359 struct acpi_thermal *tz = NULL; 1360 int i, j, power_state, result; 1361 1362 1363 if (!device || !acpi_driver_data(device)) 1364 return -EINVAL; 1365 1366 tz = acpi_driver_data(device); 1367 1368 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { 1369 if (!(&tz->trips.active[i])) 1370 break; 1371 if (!tz->trips.active[i].flags.valid) 1372 break; 1373 tz->trips.active[i].flags.enabled = 1; 1374 for (j = 0; j < tz->trips.active[i].devices.count; j++) { 1375 result = acpi_bus_get_power(tz->trips.active[i].devices. 1376 handles[j], &power_state); 1377 if (result || (power_state != ACPI_STATE_D0)) { 1378 tz->trips.active[i].flags.enabled = 0; 1379 break; 1380 } 1381 } 1382 tz->state.active |= tz->trips.active[i].flags.enabled; 1383 } 1384 1385 acpi_thermal_check(tz); 1386 1387 return AE_OK; 1388 } 1389 1390 static int __init acpi_thermal_init(void) 1391 { 1392 int result = 0; 1393 1394 1395 acpi_thermal_dir = proc_mkdir(ACPI_THERMAL_CLASS, acpi_root_dir); 1396 if (!acpi_thermal_dir) 1397 return -ENODEV; 1398 acpi_thermal_dir->owner = THIS_MODULE; 1399 1400 result = acpi_bus_register_driver(&acpi_thermal_driver); 1401 if (result < 0) { 1402 remove_proc_entry(ACPI_THERMAL_CLASS, acpi_root_dir); 1403 return -ENODEV; 1404 } 1405 1406 return 0; 1407 } 1408 1409 static void __exit acpi_thermal_exit(void) 1410 { 1411 1412 acpi_bus_unregister_driver(&acpi_thermal_driver); 1413 1414 remove_proc_entry(ACPI_THERMAL_CLASS, acpi_root_dir); 1415 1416 return; 1417 } 1418 1419 module_init(acpi_thermal_init); 1420 module_exit(acpi_thermal_exit); 1421