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_DRIVER_NAME "ACPI Thermal Zone Driver" 51 #define ACPI_THERMAL_DEVICE_NAME "Thermal Zone" 52 #define ACPI_THERMAL_FILE_STATE "state" 53 #define ACPI_THERMAL_FILE_TEMPERATURE "temperature" 54 #define ACPI_THERMAL_FILE_TRIP_POINTS "trip_points" 55 #define ACPI_THERMAL_FILE_COOLING_MODE "cooling_mode" 56 #define ACPI_THERMAL_FILE_POLLING_FREQ "polling_frequency" 57 #define ACPI_THERMAL_NOTIFY_TEMPERATURE 0x80 58 #define ACPI_THERMAL_NOTIFY_THRESHOLDS 0x81 59 #define ACPI_THERMAL_NOTIFY_DEVICES 0x82 60 #define ACPI_THERMAL_NOTIFY_CRITICAL 0xF0 61 #define ACPI_THERMAL_NOTIFY_HOT 0xF1 62 #define ACPI_THERMAL_MODE_ACTIVE 0x00 63 #define ACPI_THERMAL_MODE_PASSIVE 0x01 64 #define ACPI_THERMAL_MODE_CRITICAL 0xff 65 #define ACPI_THERMAL_PATH_POWEROFF "/sbin/poweroff" 66 67 #define ACPI_THERMAL_MAX_ACTIVE 10 68 #define ACPI_THERMAL_MAX_LIMIT_STR_LEN 65 69 70 #define KELVIN_TO_CELSIUS(t) (long)(((long)t-2732>=0) ? ((long)t-2732+5)/10 : ((long)t-2732-5)/10) 71 #define CELSIUS_TO_KELVIN(t) ((t+273)*10) 72 73 #define _COMPONENT ACPI_THERMAL_COMPONENT 74 ACPI_MODULE_NAME("acpi_thermal") 75 76 MODULE_AUTHOR("Paul Diefenbaugh"); 77 MODULE_DESCRIPTION(ACPI_THERMAL_DRIVER_NAME); 78 MODULE_LICENSE("GPL"); 79 80 static int tzp; 81 module_param(tzp, int, 0); 82 MODULE_PARM_DESC(tzp, "Thermal zone polling frequency, in 1/10 seconds.\n"); 83 84 static int acpi_thermal_add(struct acpi_device *device); 85 static int acpi_thermal_remove(struct acpi_device *device, int type); 86 static int acpi_thermal_resume(struct acpi_device *device); 87 static int acpi_thermal_state_open_fs(struct inode *inode, struct file *file); 88 static int acpi_thermal_temp_open_fs(struct inode *inode, struct file *file); 89 static int acpi_thermal_trip_open_fs(struct inode *inode, struct file *file); 90 static ssize_t acpi_thermal_write_trip_points(struct file *, 91 const char __user *, size_t, 92 loff_t *); 93 static int acpi_thermal_cooling_open_fs(struct inode *inode, struct file *file); 94 static ssize_t acpi_thermal_write_cooling_mode(struct file *, 95 const char __user *, size_t, 96 loff_t *); 97 static int acpi_thermal_polling_open_fs(struct inode *inode, struct file *file); 98 static ssize_t acpi_thermal_write_polling(struct file *, const char __user *, 99 size_t, loff_t *); 100 101 static struct acpi_driver acpi_thermal_driver = { 102 .name = ACPI_THERMAL_DRIVER_NAME, 103 .class = ACPI_THERMAL_CLASS, 104 .ids = ACPI_THERMAL_HID, 105 .ops = { 106 .add = acpi_thermal_add, 107 .remove = acpi_thermal_remove, 108 .resume = acpi_thermal_resume, 109 }, 110 }; 111 112 struct acpi_thermal_state { 113 u8 critical:1; 114 u8 hot:1; 115 u8 passive:1; 116 u8 active:1; 117 u8 reserved:4; 118 int active_index; 119 }; 120 121 struct acpi_thermal_state_flags { 122 u8 valid:1; 123 u8 enabled:1; 124 u8 reserved:6; 125 }; 126 127 struct acpi_thermal_critical { 128 struct acpi_thermal_state_flags flags; 129 unsigned long temperature; 130 }; 131 132 struct acpi_thermal_hot { 133 struct acpi_thermal_state_flags flags; 134 unsigned long temperature; 135 }; 136 137 struct acpi_thermal_passive { 138 struct acpi_thermal_state_flags flags; 139 unsigned long temperature; 140 unsigned long tc1; 141 unsigned long tc2; 142 unsigned long tsp; 143 struct acpi_handle_list devices; 144 }; 145 146 struct acpi_thermal_active { 147 struct acpi_thermal_state_flags flags; 148 unsigned long temperature; 149 struct acpi_handle_list devices; 150 }; 151 152 struct acpi_thermal_trips { 153 struct acpi_thermal_critical critical; 154 struct acpi_thermal_hot hot; 155 struct acpi_thermal_passive passive; 156 struct acpi_thermal_active active[ACPI_THERMAL_MAX_ACTIVE]; 157 }; 158 159 struct acpi_thermal_flags { 160 u8 cooling_mode:1; /* _SCP */ 161 u8 devices:1; /* _TZD */ 162 u8 reserved:6; 163 }; 164 165 struct acpi_thermal { 166 struct acpi_device * device; 167 acpi_bus_id name; 168 unsigned long temperature; 169 unsigned long last_temperature; 170 unsigned long polling_frequency; 171 u8 cooling_mode; 172 volatile u8 zombie; 173 struct acpi_thermal_flags flags; 174 struct acpi_thermal_state state; 175 struct acpi_thermal_trips trips; 176 struct acpi_handle_list devices; 177 struct timer_list timer; 178 }; 179 180 static const struct file_operations acpi_thermal_state_fops = { 181 .open = acpi_thermal_state_open_fs, 182 .read = seq_read, 183 .llseek = seq_lseek, 184 .release = single_release, 185 }; 186 187 static const struct file_operations acpi_thermal_temp_fops = { 188 .open = acpi_thermal_temp_open_fs, 189 .read = seq_read, 190 .llseek = seq_lseek, 191 .release = single_release, 192 }; 193 194 static const struct file_operations acpi_thermal_trip_fops = { 195 .open = acpi_thermal_trip_open_fs, 196 .read = seq_read, 197 .write = acpi_thermal_write_trip_points, 198 .llseek = seq_lseek, 199 .release = single_release, 200 }; 201 202 static const struct file_operations acpi_thermal_cooling_fops = { 203 .open = acpi_thermal_cooling_open_fs, 204 .read = seq_read, 205 .write = acpi_thermal_write_cooling_mode, 206 .llseek = seq_lseek, 207 .release = single_release, 208 }; 209 210 static const struct file_operations acpi_thermal_polling_fops = { 211 .open = acpi_thermal_polling_open_fs, 212 .read = seq_read, 213 .write = acpi_thermal_write_polling, 214 .llseek = seq_lseek, 215 .release = single_release, 216 }; 217 218 /* -------------------------------------------------------------------------- 219 Thermal Zone Management 220 -------------------------------------------------------------------------- */ 221 222 static int acpi_thermal_get_temperature(struct acpi_thermal *tz) 223 { 224 acpi_status status = AE_OK; 225 226 227 if (!tz) 228 return -EINVAL; 229 230 tz->last_temperature = tz->temperature; 231 232 status = 233 acpi_evaluate_integer(tz->device->handle, "_TMP", NULL, &tz->temperature); 234 if (ACPI_FAILURE(status)) 235 return -ENODEV; 236 237 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Temperature is %lu dK\n", 238 tz->temperature)); 239 240 return 0; 241 } 242 243 static int acpi_thermal_get_polling_frequency(struct acpi_thermal *tz) 244 { 245 acpi_status status = AE_OK; 246 247 248 if (!tz) 249 return -EINVAL; 250 251 status = 252 acpi_evaluate_integer(tz->device->handle, "_TZP", NULL, 253 &tz->polling_frequency); 254 if (ACPI_FAILURE(status)) 255 return -ENODEV; 256 257 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Polling frequency is %lu dS\n", 258 tz->polling_frequency)); 259 260 return 0; 261 } 262 263 static int acpi_thermal_set_polling(struct acpi_thermal *tz, int seconds) 264 { 265 266 if (!tz) 267 return -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 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 286 if (!tz) 287 return -EINVAL; 288 289 status = acpi_get_handle(tz->device->handle, "_SCP", &handle); 290 if (ACPI_FAILURE(status)) { 291 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "_SCP not present\n")); 292 return -ENODEV; 293 } 294 295 arg0.integer.value = mode; 296 297 status = acpi_evaluate_object(handle, NULL, &arg_list, NULL); 298 if (ACPI_FAILURE(status)) 299 return -ENODEV; 300 301 tz->cooling_mode = mode; 302 303 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Cooling mode [%s]\n", 304 mode ? "passive" : "active")); 305 306 return 0; 307 } 308 309 static int acpi_thermal_get_trip_points(struct acpi_thermal *tz) 310 { 311 acpi_status status = AE_OK; 312 int i = 0; 313 314 315 if (!tz) 316 return -EINVAL; 317 318 /* Critical Shutdown (required) */ 319 320 status = acpi_evaluate_integer(tz->device->handle, "_CRT", NULL, 321 &tz->trips.critical.temperature); 322 if (ACPI_FAILURE(status)) { 323 tz->trips.critical.flags.valid = 0; 324 ACPI_EXCEPTION((AE_INFO, status, "No critical threshold")); 325 return -ENODEV; 326 } else { 327 tz->trips.critical.flags.valid = 1; 328 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 329 "Found critical threshold [%lu]\n", 330 tz->trips.critical.temperature)); 331 } 332 333 /* Critical Sleep (optional) */ 334 335 status = 336 acpi_evaluate_integer(tz->device->handle, "_HOT", NULL, 337 &tz->trips.hot.temperature); 338 if (ACPI_FAILURE(status)) { 339 tz->trips.hot.flags.valid = 0; 340 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No hot threshold\n")); 341 } else { 342 tz->trips.hot.flags.valid = 1; 343 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found hot threshold [%lu]\n", 344 tz->trips.hot.temperature)); 345 } 346 347 /* Passive: Processors (optional) */ 348 349 status = 350 acpi_evaluate_integer(tz->device->handle, "_PSV", NULL, 351 &tz->trips.passive.temperature); 352 if (ACPI_FAILURE(status)) { 353 tz->trips.passive.flags.valid = 0; 354 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No passive threshold\n")); 355 } else { 356 tz->trips.passive.flags.valid = 1; 357 358 status = 359 acpi_evaluate_integer(tz->device->handle, "_TC1", NULL, 360 &tz->trips.passive.tc1); 361 if (ACPI_FAILURE(status)) 362 tz->trips.passive.flags.valid = 0; 363 364 status = 365 acpi_evaluate_integer(tz->device->handle, "_TC2", NULL, 366 &tz->trips.passive.tc2); 367 if (ACPI_FAILURE(status)) 368 tz->trips.passive.flags.valid = 0; 369 370 status = 371 acpi_evaluate_integer(tz->device->handle, "_TSP", NULL, 372 &tz->trips.passive.tsp); 373 if (ACPI_FAILURE(status)) 374 tz->trips.passive.flags.valid = 0; 375 376 status = 377 acpi_evaluate_reference(tz->device->handle, "_PSL", NULL, 378 &tz->trips.passive.devices); 379 if (ACPI_FAILURE(status)) 380 tz->trips.passive.flags.valid = 0; 381 382 if (!tz->trips.passive.flags.valid) 383 printk(KERN_WARNING PREFIX "Invalid passive threshold\n"); 384 else 385 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 386 "Found passive threshold [%lu]\n", 387 tz->trips.passive.temperature)); 388 } 389 390 /* Active: Fans, etc. (optional) */ 391 392 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { 393 394 char name[5] = { '_', 'A', 'C', ('0' + i), '\0' }; 395 396 status = 397 acpi_evaluate_integer(tz->device->handle, name, NULL, 398 &tz->trips.active[i].temperature); 399 if (ACPI_FAILURE(status)) 400 break; 401 402 name[2] = 'L'; 403 status = 404 acpi_evaluate_reference(tz->device->handle, name, NULL, 405 &tz->trips.active[i].devices); 406 if (ACPI_SUCCESS(status)) { 407 tz->trips.active[i].flags.valid = 1; 408 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 409 "Found active threshold [%d]:[%lu]\n", 410 i, tz->trips.active[i].temperature)); 411 } else 412 ACPI_EXCEPTION((AE_INFO, status, 413 "Invalid active threshold [%d]", i)); 414 } 415 416 return 0; 417 } 418 419 static int acpi_thermal_get_devices(struct acpi_thermal *tz) 420 { 421 acpi_status status = AE_OK; 422 423 424 if (!tz) 425 return -EINVAL; 426 427 status = 428 acpi_evaluate_reference(tz->device->handle, "_TZD", NULL, &tz->devices); 429 if (ACPI_FAILURE(status)) 430 return -ENODEV; 431 432 return 0; 433 } 434 435 static int acpi_thermal_call_usermode(char *path) 436 { 437 char *argv[2] = { NULL, NULL }; 438 char *envp[3] = { NULL, NULL, NULL }; 439 440 441 if (!path) 442 return -EINVAL; 443 444 argv[0] = path; 445 446 /* minimal command environment */ 447 envp[0] = "HOME=/"; 448 envp[1] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin"; 449 450 call_usermodehelper(argv[0], argv, envp, 0); 451 452 return 0; 453 } 454 455 static int acpi_thermal_critical(struct acpi_thermal *tz) 456 { 457 if (!tz || !tz->trips.critical.flags.valid) 458 return -EINVAL; 459 460 if (tz->temperature >= tz->trips.critical.temperature) { 461 printk(KERN_WARNING PREFIX "Critical trip point\n"); 462 tz->trips.critical.flags.enabled = 1; 463 } else if (tz->trips.critical.flags.enabled) 464 tz->trips.critical.flags.enabled = 0; 465 466 printk(KERN_EMERG 467 "Critical temperature reached (%ld C), shutting down.\n", 468 KELVIN_TO_CELSIUS(tz->temperature)); 469 acpi_bus_generate_event(tz->device, ACPI_THERMAL_NOTIFY_CRITICAL, 470 tz->trips.critical.flags.enabled); 471 472 acpi_thermal_call_usermode(ACPI_THERMAL_PATH_POWEROFF); 473 474 return 0; 475 } 476 477 static int acpi_thermal_hot(struct acpi_thermal *tz) 478 { 479 if (!tz || !tz->trips.hot.flags.valid) 480 return -EINVAL; 481 482 if (tz->temperature >= tz->trips.hot.temperature) { 483 printk(KERN_WARNING PREFIX "Hot trip point\n"); 484 tz->trips.hot.flags.enabled = 1; 485 } else if (tz->trips.hot.flags.enabled) 486 tz->trips.hot.flags.enabled = 0; 487 488 acpi_bus_generate_event(tz->device, ACPI_THERMAL_NOTIFY_HOT, 489 tz->trips.hot.flags.enabled); 490 491 /* TBD: Call user-mode "sleep(S4)" function */ 492 493 return 0; 494 } 495 496 static void acpi_thermal_passive(struct acpi_thermal *tz) 497 { 498 int result = 1; 499 struct acpi_thermal_passive *passive = NULL; 500 int trend = 0; 501 int i = 0; 502 503 504 if (!tz || !tz->trips.passive.flags.valid) 505 return; 506 507 passive = &(tz->trips.passive); 508 509 /* 510 * Above Trip? 511 * ----------- 512 * Calculate the thermal trend (using the passive cooling equation) 513 * and modify the performance limit for all passive cooling devices 514 * accordingly. Note that we assume symmetry. 515 */ 516 if (tz->temperature >= passive->temperature) { 517 trend = 518 (passive->tc1 * (tz->temperature - tz->last_temperature)) + 519 (passive->tc2 * (tz->temperature - passive->temperature)); 520 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 521 "trend[%d]=(tc1[%lu]*(tmp[%lu]-last[%lu]))+(tc2[%lu]*(tmp[%lu]-psv[%lu]))\n", 522 trend, passive->tc1, tz->temperature, 523 tz->last_temperature, passive->tc2, 524 tz->temperature, passive->temperature)); 525 passive->flags.enabled = 1; 526 /* Heating up? */ 527 if (trend > 0) 528 for (i = 0; i < passive->devices.count; i++) 529 acpi_processor_set_thermal_limit(passive-> 530 devices. 531 handles[i], 532 ACPI_PROCESSOR_LIMIT_INCREMENT); 533 /* Cooling off? */ 534 else if (trend < 0) { 535 for (i = 0; i < passive->devices.count; i++) 536 /* 537 * assume that we are on highest 538 * freq/lowest thrott and can leave 539 * passive mode, even in error case 540 */ 541 if (!acpi_processor_set_thermal_limit 542 (passive->devices.handles[i], 543 ACPI_PROCESSOR_LIMIT_DECREMENT)) 544 result = 0; 545 /* 546 * Leave cooling mode, even if the temp might 547 * higher than trip point This is because some 548 * machines might have long thermal polling 549 * frequencies (tsp) defined. We will fall back 550 * into passive mode in next cycle (probably quicker) 551 */ 552 if (result) { 553 passive->flags.enabled = 0; 554 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 555 "Disabling passive cooling, still above threshold," 556 " but we are cooling down\n")); 557 } 558 } 559 return; 560 } 561 562 /* 563 * Below Trip? 564 * ----------- 565 * Implement passive cooling hysteresis to slowly increase performance 566 * and avoid thrashing around the passive trip point. Note that we 567 * assume symmetry. 568 */ 569 if (!passive->flags.enabled) 570 return; 571 for (i = 0; i < passive->devices.count; i++) 572 if (!acpi_processor_set_thermal_limit 573 (passive->devices.handles[i], 574 ACPI_PROCESSOR_LIMIT_DECREMENT)) 575 result = 0; 576 if (result) { 577 passive->flags.enabled = 0; 578 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 579 "Disabling passive cooling (zone is cool)\n")); 580 } 581 } 582 583 static void acpi_thermal_active(struct acpi_thermal *tz) 584 { 585 int result = 0; 586 struct acpi_thermal_active *active = NULL; 587 int i = 0; 588 int j = 0; 589 unsigned long maxtemp = 0; 590 591 592 if (!tz) 593 return; 594 595 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { 596 active = &(tz->trips.active[i]); 597 if (!active || !active->flags.valid) 598 break; 599 if (tz->temperature >= active->temperature) { 600 /* 601 * Above Threshold? 602 * ---------------- 603 * If not already enabled, turn ON all cooling devices 604 * associated with this active threshold. 605 */ 606 if (active->temperature > maxtemp) 607 tz->state.active_index = i; 608 maxtemp = active->temperature; 609 if (active->flags.enabled) 610 continue; 611 for (j = 0; j < active->devices.count; j++) { 612 result = 613 acpi_bus_set_power(active->devices. 614 handles[j], 615 ACPI_STATE_D0); 616 if (result) { 617 printk(KERN_WARNING PREFIX 618 "Unable to turn cooling device [%p] 'on'\n", 619 active->devices. 620 handles[j]); 621 continue; 622 } 623 active->flags.enabled = 1; 624 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 625 "Cooling device [%p] now 'on'\n", 626 active->devices.handles[j])); 627 } 628 continue; 629 } 630 if (!active->flags.enabled) 631 continue; 632 /* 633 * Below Threshold? 634 * ---------------- 635 * Turn OFF all cooling devices associated with this 636 * threshold. 637 */ 638 for (j = 0; j < active->devices.count; j++) { 639 result = acpi_bus_set_power(active->devices.handles[j], 640 ACPI_STATE_D3); 641 if (result) { 642 printk(KERN_WARNING PREFIX 643 "Unable to turn cooling device [%p] 'off'\n", 644 active->devices.handles[j]); 645 continue; 646 } 647 active->flags.enabled = 0; 648 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 649 "Cooling device [%p] now 'off'\n", 650 active->devices.handles[j])); 651 } 652 } 653 } 654 655 static void acpi_thermal_check(void *context); 656 657 static void acpi_thermal_run(unsigned long data) 658 { 659 struct acpi_thermal *tz = (struct acpi_thermal *)data; 660 if (!tz->zombie) 661 acpi_os_execute(OSL_GPE_HANDLER, acpi_thermal_check, (void *)data); 662 } 663 664 static void acpi_thermal_check(void *data) 665 { 666 int result = 0; 667 struct acpi_thermal *tz = data; 668 unsigned long sleep_time = 0; 669 int i = 0; 670 struct acpi_thermal_state state; 671 672 673 if (!tz) { 674 printk(KERN_ERR PREFIX "Invalid (NULL) context\n"); 675 return; 676 } 677 678 state = tz->state; 679 680 result = acpi_thermal_get_temperature(tz); 681 if (result) 682 return; 683 684 memset(&tz->state, 0, sizeof(tz->state)); 685 686 /* 687 * Check Trip Points 688 * ----------------- 689 * Compare the current temperature to the trip point values to see 690 * if we've entered one of the thermal policy states. Note that 691 * this function determines when a state is entered, but the 692 * individual policy decides when it is exited (e.g. hysteresis). 693 */ 694 if (tz->trips.critical.flags.valid) 695 state.critical |= 696 (tz->temperature >= tz->trips.critical.temperature); 697 if (tz->trips.hot.flags.valid) 698 state.hot |= (tz->temperature >= tz->trips.hot.temperature); 699 if (tz->trips.passive.flags.valid) 700 state.passive |= 701 (tz->temperature >= tz->trips.passive.temperature); 702 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) 703 if (tz->trips.active[i].flags.valid) 704 state.active |= 705 (tz->temperature >= 706 tz->trips.active[i].temperature); 707 708 /* 709 * Invoke Policy 710 * ------------- 711 * Separated from the above check to allow individual policy to 712 * determine when to exit a given state. 713 */ 714 if (state.critical) 715 acpi_thermal_critical(tz); 716 if (state.hot) 717 acpi_thermal_hot(tz); 718 if (state.passive) 719 acpi_thermal_passive(tz); 720 if (state.active) 721 acpi_thermal_active(tz); 722 723 /* 724 * Calculate State 725 * --------------- 726 * Again, separated from the above two to allow independent policy 727 * decisions. 728 */ 729 tz->state.critical = tz->trips.critical.flags.enabled; 730 tz->state.hot = tz->trips.hot.flags.enabled; 731 tz->state.passive = tz->trips.passive.flags.enabled; 732 tz->state.active = 0; 733 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) 734 tz->state.active |= tz->trips.active[i].flags.enabled; 735 736 /* 737 * Calculate Sleep Time 738 * -------------------- 739 * If we're in the passive state, use _TSP's value. Otherwise 740 * use the default polling frequency (e.g. _TZP). If no polling 741 * frequency is specified then we'll wait forever (at least until 742 * a thermal event occurs). Note that _TSP and _TZD values are 743 * given in 1/10th seconds (we must covert to milliseconds). 744 */ 745 if (tz->state.passive) 746 sleep_time = tz->trips.passive.tsp * 100; 747 else if (tz->polling_frequency > 0) 748 sleep_time = tz->polling_frequency * 100; 749 750 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s: temperature[%lu] sleep[%lu]\n", 751 tz->name, tz->temperature, sleep_time)); 752 753 /* 754 * Schedule Next Poll 755 * ------------------ 756 */ 757 if (!sleep_time) { 758 if (timer_pending(&(tz->timer))) 759 del_timer(&(tz->timer)); 760 } else { 761 if (timer_pending(&(tz->timer))) 762 mod_timer(&(tz->timer), (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; 1361 1362 if (!device || !acpi_driver_data(device)) 1363 return -EINVAL; 1364 1365 tz = acpi_driver_data(device); 1366 1367 acpi_thermal_get_temperature(tz); 1368 1369 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { 1370 if (tz->trips.active[i].flags.valid) { 1371 tz->temperature = tz->trips.active[i].temperature; 1372 tz->trips.active[i].flags.enabled = 0; 1373 1374 acpi_thermal_active(tz); 1375 1376 tz->state.active |= tz->trips.active[i].flags.enabled; 1377 tz->state.active_index = i; 1378 } 1379 } 1380 1381 acpi_thermal_check(tz); 1382 1383 return AE_OK; 1384 } 1385 1386 static int __init acpi_thermal_init(void) 1387 { 1388 int result = 0; 1389 1390 1391 acpi_thermal_dir = proc_mkdir(ACPI_THERMAL_CLASS, acpi_root_dir); 1392 if (!acpi_thermal_dir) 1393 return -ENODEV; 1394 acpi_thermal_dir->owner = THIS_MODULE; 1395 1396 result = acpi_bus_register_driver(&acpi_thermal_driver); 1397 if (result < 0) { 1398 remove_proc_entry(ACPI_THERMAL_CLASS, acpi_root_dir); 1399 return -ENODEV; 1400 } 1401 1402 return 0; 1403 } 1404 1405 static void __exit acpi_thermal_exit(void) 1406 { 1407 1408 acpi_bus_unregister_driver(&acpi_thermal_driver); 1409 1410 remove_proc_entry(ACPI_THERMAL_CLASS, acpi_root_dir); 1411 1412 return; 1413 } 1414 1415 module_init(acpi_thermal_init); 1416 module_exit(acpi_thermal_exit); 1417