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