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/dmi.h> 37 #include <linux/init.h> 38 #include <linux/slab.h> 39 #include <linux/types.h> 40 41 #ifdef CONFIG_ACPI_PROCFS 42 #include <linux/proc_fs.h> 43 #include <linux/seq_file.h> 44 #endif 45 46 #include <linux/jiffies.h> 47 #include <linux/kmod.h> 48 #include <linux/reboot.h> 49 #include <linux/device.h> 50 #include <asm/uaccess.h> 51 #include <linux/thermal.h> 52 #include <acpi/acpi_bus.h> 53 #include <acpi/acpi_drivers.h> 54 55 #define PREFIX "ACPI: " 56 57 #define ACPI_THERMAL_CLASS "thermal_zone" 58 #define ACPI_THERMAL_DEVICE_NAME "Thermal Zone" 59 #define ACPI_THERMAL_FILE_STATE "state" 60 #define ACPI_THERMAL_FILE_TEMPERATURE "temperature" 61 #define ACPI_THERMAL_FILE_TRIP_POINTS "trip_points" 62 #define ACPI_THERMAL_FILE_COOLING_MODE "cooling_mode" 63 #define ACPI_THERMAL_FILE_POLLING_FREQ "polling_frequency" 64 #define ACPI_THERMAL_NOTIFY_TEMPERATURE 0x80 65 #define ACPI_THERMAL_NOTIFY_THRESHOLDS 0x81 66 #define ACPI_THERMAL_NOTIFY_DEVICES 0x82 67 #define ACPI_THERMAL_NOTIFY_CRITICAL 0xF0 68 #define ACPI_THERMAL_NOTIFY_HOT 0xF1 69 #define ACPI_THERMAL_MODE_ACTIVE 0x00 70 71 #define ACPI_THERMAL_MAX_ACTIVE 10 72 #define ACPI_THERMAL_MAX_LIMIT_STR_LEN 65 73 74 #define _COMPONENT ACPI_THERMAL_COMPONENT 75 ACPI_MODULE_NAME("thermal"); 76 77 MODULE_AUTHOR("Paul Diefenbaugh"); 78 MODULE_DESCRIPTION("ACPI Thermal Zone Driver"); 79 MODULE_LICENSE("GPL"); 80 81 static int act; 82 module_param(act, int, 0644); 83 MODULE_PARM_DESC(act, "Disable or override all lowest active trip points."); 84 85 static int crt; 86 module_param(crt, int, 0644); 87 MODULE_PARM_DESC(crt, "Disable or lower all critical trip points."); 88 89 static int tzp; 90 module_param(tzp, int, 0444); 91 MODULE_PARM_DESC(tzp, "Thermal zone polling frequency, in 1/10 seconds."); 92 93 static int nocrt; 94 module_param(nocrt, int, 0); 95 MODULE_PARM_DESC(nocrt, "Set to take no action upon ACPI thermal zone critical trips points."); 96 97 static int off; 98 module_param(off, int, 0); 99 MODULE_PARM_DESC(off, "Set to disable ACPI thermal support."); 100 101 static int psv; 102 module_param(psv, int, 0644); 103 MODULE_PARM_DESC(psv, "Disable or override all passive trip points."); 104 105 static int acpi_thermal_add(struct acpi_device *device); 106 static int acpi_thermal_remove(struct acpi_device *device, int type); 107 static int acpi_thermal_resume(struct acpi_device *device); 108 static void acpi_thermal_notify(struct acpi_device *device, u32 event); 109 110 static const struct acpi_device_id thermal_device_ids[] = { 111 {ACPI_THERMAL_HID, 0}, 112 {"", 0}, 113 }; 114 MODULE_DEVICE_TABLE(acpi, thermal_device_ids); 115 116 static struct acpi_driver acpi_thermal_driver = { 117 .name = "thermal", 118 .class = ACPI_THERMAL_CLASS, 119 .ids = thermal_device_ids, 120 .ops = { 121 .add = acpi_thermal_add, 122 .remove = acpi_thermal_remove, 123 .resume = acpi_thermal_resume, 124 .notify = acpi_thermal_notify, 125 }, 126 }; 127 128 struct acpi_thermal_state { 129 u8 critical:1; 130 u8 hot:1; 131 u8 passive:1; 132 u8 active:1; 133 u8 reserved:4; 134 int active_index; 135 }; 136 137 struct acpi_thermal_state_flags { 138 u8 valid:1; 139 u8 enabled:1; 140 u8 reserved:6; 141 }; 142 143 struct acpi_thermal_critical { 144 struct acpi_thermal_state_flags flags; 145 unsigned long temperature; 146 }; 147 148 struct acpi_thermal_hot { 149 struct acpi_thermal_state_flags flags; 150 unsigned long temperature; 151 }; 152 153 struct acpi_thermal_passive { 154 struct acpi_thermal_state_flags flags; 155 unsigned long temperature; 156 unsigned long tc1; 157 unsigned long tc2; 158 unsigned long tsp; 159 struct acpi_handle_list devices; 160 }; 161 162 struct acpi_thermal_active { 163 struct acpi_thermal_state_flags flags; 164 unsigned long temperature; 165 struct acpi_handle_list devices; 166 }; 167 168 struct acpi_thermal_trips { 169 struct acpi_thermal_critical critical; 170 struct acpi_thermal_hot hot; 171 struct acpi_thermal_passive passive; 172 struct acpi_thermal_active active[ACPI_THERMAL_MAX_ACTIVE]; 173 }; 174 175 struct acpi_thermal_flags { 176 u8 cooling_mode:1; /* _SCP */ 177 u8 devices:1; /* _TZD */ 178 u8 reserved:6; 179 }; 180 181 struct acpi_thermal { 182 struct acpi_device * device; 183 acpi_bus_id name; 184 unsigned long temperature; 185 unsigned long last_temperature; 186 unsigned long polling_frequency; 187 volatile u8 zombie; 188 struct acpi_thermal_flags flags; 189 struct acpi_thermal_state state; 190 struct acpi_thermal_trips trips; 191 struct acpi_handle_list devices; 192 struct thermal_zone_device *thermal_zone; 193 int tz_enabled; 194 int kelvin_offset; 195 struct mutex lock; 196 }; 197 198 #ifdef CONFIG_ACPI_PROCFS 199 static int acpi_thermal_state_open_fs(struct inode *inode, struct file *file); 200 static int acpi_thermal_temp_open_fs(struct inode *inode, struct file *file); 201 static int acpi_thermal_trip_open_fs(struct inode *inode, struct file *file); 202 static int acpi_thermal_cooling_open_fs(struct inode *inode, struct file *file); 203 static ssize_t acpi_thermal_write_cooling_mode(struct file *, 204 const char __user *, size_t, 205 loff_t *); 206 static int acpi_thermal_polling_open_fs(struct inode *inode, struct file *file); 207 static ssize_t acpi_thermal_write_polling(struct file *, const char __user *, 208 size_t, loff_t *); 209 210 static const struct file_operations acpi_thermal_state_fops = { 211 .owner = THIS_MODULE, 212 .open = acpi_thermal_state_open_fs, 213 .read = seq_read, 214 .llseek = seq_lseek, 215 .release = single_release, 216 }; 217 218 static const struct file_operations acpi_thermal_temp_fops = { 219 .owner = THIS_MODULE, 220 .open = acpi_thermal_temp_open_fs, 221 .read = seq_read, 222 .llseek = seq_lseek, 223 .release = single_release, 224 }; 225 226 static const struct file_operations acpi_thermal_trip_fops = { 227 .owner = THIS_MODULE, 228 .open = acpi_thermal_trip_open_fs, 229 .read = seq_read, 230 .llseek = seq_lseek, 231 .release = single_release, 232 }; 233 234 static const struct file_operations acpi_thermal_cooling_fops = { 235 .owner = THIS_MODULE, 236 .open = acpi_thermal_cooling_open_fs, 237 .read = seq_read, 238 .write = acpi_thermal_write_cooling_mode, 239 .llseek = seq_lseek, 240 .release = single_release, 241 }; 242 243 static const struct file_operations acpi_thermal_polling_fops = { 244 .owner = THIS_MODULE, 245 .open = acpi_thermal_polling_open_fs, 246 .read = seq_read, 247 .write = acpi_thermal_write_polling, 248 .llseek = seq_lseek, 249 .release = single_release, 250 }; 251 #endif /* CONFIG_ACPI_PROCFS*/ 252 253 /* -------------------------------------------------------------------------- 254 Thermal Zone Management 255 -------------------------------------------------------------------------- */ 256 257 static int acpi_thermal_get_temperature(struct acpi_thermal *tz) 258 { 259 acpi_status status = AE_OK; 260 unsigned long long tmp; 261 262 if (!tz) 263 return -EINVAL; 264 265 tz->last_temperature = tz->temperature; 266 267 status = acpi_evaluate_integer(tz->device->handle, "_TMP", NULL, &tmp); 268 if (ACPI_FAILURE(status)) 269 return -ENODEV; 270 271 tz->temperature = tmp; 272 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Temperature is %lu dK\n", 273 tz->temperature)); 274 275 return 0; 276 } 277 278 static int acpi_thermal_get_polling_frequency(struct acpi_thermal *tz) 279 { 280 acpi_status status = AE_OK; 281 unsigned long long tmp; 282 283 if (!tz) 284 return -EINVAL; 285 286 status = acpi_evaluate_integer(tz->device->handle, "_TZP", NULL, &tmp); 287 if (ACPI_FAILURE(status)) 288 return -ENODEV; 289 290 tz->polling_frequency = tmp; 291 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Polling frequency is %lu dS\n", 292 tz->polling_frequency)); 293 294 return 0; 295 } 296 297 static int acpi_thermal_set_cooling_mode(struct acpi_thermal *tz, int mode) 298 { 299 acpi_status status = AE_OK; 300 union acpi_object arg0 = { ACPI_TYPE_INTEGER }; 301 struct acpi_object_list arg_list = { 1, &arg0 }; 302 acpi_handle handle = NULL; 303 304 305 if (!tz) 306 return -EINVAL; 307 308 status = acpi_get_handle(tz->device->handle, "_SCP", &handle); 309 if (ACPI_FAILURE(status)) { 310 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "_SCP not present\n")); 311 return -ENODEV; 312 } 313 314 arg0.integer.value = mode; 315 316 status = acpi_evaluate_object(handle, NULL, &arg_list, NULL); 317 if (ACPI_FAILURE(status)) 318 return -ENODEV; 319 320 return 0; 321 } 322 323 #define ACPI_TRIPS_CRITICAL 0x01 324 #define ACPI_TRIPS_HOT 0x02 325 #define ACPI_TRIPS_PASSIVE 0x04 326 #define ACPI_TRIPS_ACTIVE 0x08 327 #define ACPI_TRIPS_DEVICES 0x10 328 329 #define ACPI_TRIPS_REFRESH_THRESHOLDS (ACPI_TRIPS_PASSIVE | ACPI_TRIPS_ACTIVE) 330 #define ACPI_TRIPS_REFRESH_DEVICES ACPI_TRIPS_DEVICES 331 332 #define ACPI_TRIPS_INIT (ACPI_TRIPS_CRITICAL | ACPI_TRIPS_HOT | \ 333 ACPI_TRIPS_PASSIVE | ACPI_TRIPS_ACTIVE | \ 334 ACPI_TRIPS_DEVICES) 335 336 /* 337 * This exception is thrown out in two cases: 338 * 1.An invalid trip point becomes invalid or a valid trip point becomes invalid 339 * when re-evaluating the AML code. 340 * 2.TODO: Devices listed in _PSL, _ALx, _TZD may change. 341 * We need to re-bind the cooling devices of a thermal zone when this occurs. 342 */ 343 #define ACPI_THERMAL_TRIPS_EXCEPTION(flags, str) \ 344 do { \ 345 if (flags != ACPI_TRIPS_INIT) \ 346 ACPI_EXCEPTION((AE_INFO, AE_ERROR, \ 347 "ACPI thermal trip point %s changed\n" \ 348 "Please send acpidump to linux-acpi@vger.kernel.org\n", str)); \ 349 } while (0) 350 351 static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag) 352 { 353 acpi_status status = AE_OK; 354 unsigned long long tmp; 355 struct acpi_handle_list devices; 356 int valid = 0; 357 int i; 358 359 /* Critical Shutdown */ 360 if (flag & ACPI_TRIPS_CRITICAL) { 361 status = acpi_evaluate_integer(tz->device->handle, 362 "_CRT", NULL, &tmp); 363 tz->trips.critical.temperature = tmp; 364 /* 365 * Treat freezing temperatures as invalid as well; some 366 * BIOSes return really low values and cause reboots at startup. 367 * Below zero (Celsius) values clearly aren't right for sure.. 368 * ... so lets discard those as invalid. 369 */ 370 if (ACPI_FAILURE(status)) { 371 tz->trips.critical.flags.valid = 0; 372 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 373 "No critical threshold\n")); 374 } else if (tmp <= 2732) { 375 printk(KERN_WARNING FW_BUG "Invalid critical threshold " 376 "(%llu)\n", tmp); 377 tz->trips.critical.flags.valid = 0; 378 } else { 379 tz->trips.critical.flags.valid = 1; 380 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 381 "Found critical threshold [%lu]\n", 382 tz->trips.critical.temperature)); 383 } 384 if (tz->trips.critical.flags.valid == 1) { 385 if (crt == -1) { 386 tz->trips.critical.flags.valid = 0; 387 } else if (crt > 0) { 388 unsigned long crt_k = CELSIUS_TO_KELVIN(crt); 389 /* 390 * Allow override critical threshold 391 */ 392 if (crt_k > tz->trips.critical.temperature) 393 printk(KERN_WARNING PREFIX 394 "Critical threshold %d C\n", crt); 395 tz->trips.critical.temperature = crt_k; 396 } 397 } 398 } 399 400 /* Critical Sleep (optional) */ 401 if (flag & ACPI_TRIPS_HOT) { 402 status = acpi_evaluate_integer(tz->device->handle, 403 "_HOT", NULL, &tmp); 404 if (ACPI_FAILURE(status)) { 405 tz->trips.hot.flags.valid = 0; 406 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 407 "No hot threshold\n")); 408 } else { 409 tz->trips.hot.temperature = tmp; 410 tz->trips.hot.flags.valid = 1; 411 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 412 "Found hot threshold [%lu]\n", 413 tz->trips.critical.temperature)); 414 } 415 } 416 417 /* Passive (optional) */ 418 if (((flag & ACPI_TRIPS_PASSIVE) && tz->trips.passive.flags.valid) || 419 (flag == ACPI_TRIPS_INIT)) { 420 valid = tz->trips.passive.flags.valid; 421 if (psv == -1) { 422 status = AE_SUPPORT; 423 } else if (psv > 0) { 424 tmp = CELSIUS_TO_KELVIN(psv); 425 status = AE_OK; 426 } else { 427 status = acpi_evaluate_integer(tz->device->handle, 428 "_PSV", NULL, &tmp); 429 } 430 431 if (ACPI_FAILURE(status)) 432 tz->trips.passive.flags.valid = 0; 433 else { 434 tz->trips.passive.temperature = tmp; 435 tz->trips.passive.flags.valid = 1; 436 if (flag == ACPI_TRIPS_INIT) { 437 status = acpi_evaluate_integer( 438 tz->device->handle, "_TC1", 439 NULL, &tmp); 440 if (ACPI_FAILURE(status)) 441 tz->trips.passive.flags.valid = 0; 442 else 443 tz->trips.passive.tc1 = tmp; 444 status = acpi_evaluate_integer( 445 tz->device->handle, "_TC2", 446 NULL, &tmp); 447 if (ACPI_FAILURE(status)) 448 tz->trips.passive.flags.valid = 0; 449 else 450 tz->trips.passive.tc2 = tmp; 451 status = acpi_evaluate_integer( 452 tz->device->handle, "_TSP", 453 NULL, &tmp); 454 if (ACPI_FAILURE(status)) 455 tz->trips.passive.flags.valid = 0; 456 else 457 tz->trips.passive.tsp = tmp; 458 } 459 } 460 } 461 if ((flag & ACPI_TRIPS_DEVICES) && tz->trips.passive.flags.valid) { 462 memset(&devices, 0, sizeof(struct acpi_handle_list)); 463 status = acpi_evaluate_reference(tz->device->handle, "_PSL", 464 NULL, &devices); 465 if (ACPI_FAILURE(status)) { 466 printk(KERN_WARNING PREFIX 467 "Invalid passive threshold\n"); 468 tz->trips.passive.flags.valid = 0; 469 } 470 else 471 tz->trips.passive.flags.valid = 1; 472 473 if (memcmp(&tz->trips.passive.devices, &devices, 474 sizeof(struct acpi_handle_list))) { 475 memcpy(&tz->trips.passive.devices, &devices, 476 sizeof(struct acpi_handle_list)); 477 ACPI_THERMAL_TRIPS_EXCEPTION(flag, "device"); 478 } 479 } 480 if ((flag & ACPI_TRIPS_PASSIVE) || (flag & ACPI_TRIPS_DEVICES)) { 481 if (valid != tz->trips.passive.flags.valid) 482 ACPI_THERMAL_TRIPS_EXCEPTION(flag, "state"); 483 } 484 485 /* Active (optional) */ 486 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { 487 char name[5] = { '_', 'A', 'C', ('0' + i), '\0' }; 488 valid = tz->trips.active[i].flags.valid; 489 490 if (act == -1) 491 break; /* disable all active trip points */ 492 493 if ((flag == ACPI_TRIPS_INIT) || ((flag & ACPI_TRIPS_ACTIVE) && 494 tz->trips.active[i].flags.valid)) { 495 status = acpi_evaluate_integer(tz->device->handle, 496 name, NULL, &tmp); 497 if (ACPI_FAILURE(status)) { 498 tz->trips.active[i].flags.valid = 0; 499 if (i == 0) 500 break; 501 if (act <= 0) 502 break; 503 if (i == 1) 504 tz->trips.active[0].temperature = 505 CELSIUS_TO_KELVIN(act); 506 else 507 /* 508 * Don't allow override higher than 509 * the next higher trip point 510 */ 511 tz->trips.active[i - 1].temperature = 512 (tz->trips.active[i - 2].temperature < 513 CELSIUS_TO_KELVIN(act) ? 514 tz->trips.active[i - 2].temperature : 515 CELSIUS_TO_KELVIN(act)); 516 break; 517 } else { 518 tz->trips.active[i].temperature = tmp; 519 tz->trips.active[i].flags.valid = 1; 520 } 521 } 522 523 name[2] = 'L'; 524 if ((flag & ACPI_TRIPS_DEVICES) && tz->trips.active[i].flags.valid ) { 525 memset(&devices, 0, sizeof(struct acpi_handle_list)); 526 status = acpi_evaluate_reference(tz->device->handle, 527 name, NULL, &devices); 528 if (ACPI_FAILURE(status)) { 529 printk(KERN_WARNING PREFIX 530 "Invalid active%d threshold\n", i); 531 tz->trips.active[i].flags.valid = 0; 532 } 533 else 534 tz->trips.active[i].flags.valid = 1; 535 536 if (memcmp(&tz->trips.active[i].devices, &devices, 537 sizeof(struct acpi_handle_list))) { 538 memcpy(&tz->trips.active[i].devices, &devices, 539 sizeof(struct acpi_handle_list)); 540 ACPI_THERMAL_TRIPS_EXCEPTION(flag, "device"); 541 } 542 } 543 if ((flag & ACPI_TRIPS_ACTIVE) || (flag & ACPI_TRIPS_DEVICES)) 544 if (valid != tz->trips.active[i].flags.valid) 545 ACPI_THERMAL_TRIPS_EXCEPTION(flag, "state"); 546 547 if (!tz->trips.active[i].flags.valid) 548 break; 549 } 550 551 if (flag & ACPI_TRIPS_DEVICES) { 552 memset(&devices, 0, sizeof(struct acpi_handle_list)); 553 status = acpi_evaluate_reference(tz->device->handle, "_TZD", 554 NULL, &devices); 555 if (memcmp(&tz->devices, &devices, 556 sizeof(struct acpi_handle_list))) { 557 memcpy(&tz->devices, &devices, 558 sizeof(struct acpi_handle_list)); 559 ACPI_THERMAL_TRIPS_EXCEPTION(flag, "device"); 560 } 561 } 562 563 return 0; 564 } 565 566 static int acpi_thermal_get_trip_points(struct acpi_thermal *tz) 567 { 568 int i, valid, ret = acpi_thermal_trips_update(tz, ACPI_TRIPS_INIT); 569 570 if (ret) 571 return ret; 572 573 valid = tz->trips.critical.flags.valid | 574 tz->trips.hot.flags.valid | 575 tz->trips.passive.flags.valid; 576 577 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) 578 valid |= tz->trips.active[i].flags.valid; 579 580 if (!valid) { 581 printk(KERN_WARNING FW_BUG "No valid trip found\n"); 582 return -ENODEV; 583 } 584 return 0; 585 } 586 587 static void acpi_thermal_check(void *data) 588 { 589 struct acpi_thermal *tz = data; 590 591 thermal_zone_device_update(tz->thermal_zone); 592 } 593 594 /* sys I/F for generic thermal sysfs support */ 595 #define KELVIN_TO_MILLICELSIUS(t, off) (((t) - (off)) * 100) 596 597 static int thermal_get_temp(struct thermal_zone_device *thermal, 598 unsigned long *temp) 599 { 600 struct acpi_thermal *tz = thermal->devdata; 601 int result; 602 603 if (!tz) 604 return -EINVAL; 605 606 result = acpi_thermal_get_temperature(tz); 607 if (result) 608 return result; 609 610 *temp = KELVIN_TO_MILLICELSIUS(tz->temperature, tz->kelvin_offset); 611 return 0; 612 } 613 614 static const char enabled[] = "kernel"; 615 static const char disabled[] = "user"; 616 static int thermal_get_mode(struct thermal_zone_device *thermal, 617 enum thermal_device_mode *mode) 618 { 619 struct acpi_thermal *tz = thermal->devdata; 620 621 if (!tz) 622 return -EINVAL; 623 624 *mode = tz->tz_enabled ? THERMAL_DEVICE_ENABLED : 625 THERMAL_DEVICE_DISABLED; 626 627 return 0; 628 } 629 630 static int thermal_set_mode(struct thermal_zone_device *thermal, 631 enum thermal_device_mode mode) 632 { 633 struct acpi_thermal *tz = thermal->devdata; 634 int enable; 635 636 if (!tz) 637 return -EINVAL; 638 639 /* 640 * enable/disable thermal management from ACPI thermal driver 641 */ 642 if (mode == THERMAL_DEVICE_ENABLED) 643 enable = 1; 644 else if (mode == THERMAL_DEVICE_DISABLED) 645 enable = 0; 646 else 647 return -EINVAL; 648 649 if (enable != tz->tz_enabled) { 650 tz->tz_enabled = enable; 651 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 652 "%s ACPI thermal control\n", 653 tz->tz_enabled ? enabled : disabled)); 654 acpi_thermal_check(tz); 655 } 656 return 0; 657 } 658 659 static int thermal_get_trip_type(struct thermal_zone_device *thermal, 660 int trip, enum thermal_trip_type *type) 661 { 662 struct acpi_thermal *tz = thermal->devdata; 663 int i; 664 665 if (!tz || trip < 0) 666 return -EINVAL; 667 668 if (tz->trips.critical.flags.valid) { 669 if (!trip) { 670 *type = THERMAL_TRIP_CRITICAL; 671 return 0; 672 } 673 trip--; 674 } 675 676 if (tz->trips.hot.flags.valid) { 677 if (!trip) { 678 *type = THERMAL_TRIP_HOT; 679 return 0; 680 } 681 trip--; 682 } 683 684 if (tz->trips.passive.flags.valid) { 685 if (!trip) { 686 *type = THERMAL_TRIP_PASSIVE; 687 return 0; 688 } 689 trip--; 690 } 691 692 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE && 693 tz->trips.active[i].flags.valid; i++) { 694 if (!trip) { 695 *type = THERMAL_TRIP_ACTIVE; 696 return 0; 697 } 698 trip--; 699 } 700 701 return -EINVAL; 702 } 703 704 static int thermal_get_trip_temp(struct thermal_zone_device *thermal, 705 int trip, unsigned long *temp) 706 { 707 struct acpi_thermal *tz = thermal->devdata; 708 int i; 709 710 if (!tz || trip < 0) 711 return -EINVAL; 712 713 if (tz->trips.critical.flags.valid) { 714 if (!trip) { 715 *temp = KELVIN_TO_MILLICELSIUS( 716 tz->trips.critical.temperature, 717 tz->kelvin_offset); 718 return 0; 719 } 720 trip--; 721 } 722 723 if (tz->trips.hot.flags.valid) { 724 if (!trip) { 725 *temp = KELVIN_TO_MILLICELSIUS( 726 tz->trips.hot.temperature, 727 tz->kelvin_offset); 728 return 0; 729 } 730 trip--; 731 } 732 733 if (tz->trips.passive.flags.valid) { 734 if (!trip) { 735 *temp = KELVIN_TO_MILLICELSIUS( 736 tz->trips.passive.temperature, 737 tz->kelvin_offset); 738 return 0; 739 } 740 trip--; 741 } 742 743 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE && 744 tz->trips.active[i].flags.valid; i++) { 745 if (!trip) { 746 *temp = KELVIN_TO_MILLICELSIUS( 747 tz->trips.active[i].temperature, 748 tz->kelvin_offset); 749 return 0; 750 } 751 trip--; 752 } 753 754 return -EINVAL; 755 } 756 757 static int thermal_get_crit_temp(struct thermal_zone_device *thermal, 758 unsigned long *temperature) { 759 struct acpi_thermal *tz = thermal->devdata; 760 761 if (tz->trips.critical.flags.valid) { 762 *temperature = KELVIN_TO_MILLICELSIUS( 763 tz->trips.critical.temperature, 764 tz->kelvin_offset); 765 return 0; 766 } else 767 return -EINVAL; 768 } 769 770 static int thermal_notify(struct thermal_zone_device *thermal, int trip, 771 enum thermal_trip_type trip_type) 772 { 773 u8 type = 0; 774 struct acpi_thermal *tz = thermal->devdata; 775 776 if (trip_type == THERMAL_TRIP_CRITICAL) 777 type = ACPI_THERMAL_NOTIFY_CRITICAL; 778 else if (trip_type == THERMAL_TRIP_HOT) 779 type = ACPI_THERMAL_NOTIFY_HOT; 780 else 781 return 0; 782 783 acpi_bus_generate_proc_event(tz->device, type, 1); 784 acpi_bus_generate_netlink_event(tz->device->pnp.device_class, 785 dev_name(&tz->device->dev), type, 1); 786 787 if (trip_type == THERMAL_TRIP_CRITICAL && nocrt) 788 return 1; 789 790 return 0; 791 } 792 793 typedef int (*cb)(struct thermal_zone_device *, int, 794 struct thermal_cooling_device *); 795 static int acpi_thermal_cooling_device_cb(struct thermal_zone_device *thermal, 796 struct thermal_cooling_device *cdev, 797 cb action) 798 { 799 struct acpi_device *device = cdev->devdata; 800 struct acpi_thermal *tz = thermal->devdata; 801 struct acpi_device *dev; 802 acpi_status status; 803 acpi_handle handle; 804 int i; 805 int j; 806 int trip = -1; 807 int result = 0; 808 809 if (tz->trips.critical.flags.valid) 810 trip++; 811 812 if (tz->trips.hot.flags.valid) 813 trip++; 814 815 if (tz->trips.passive.flags.valid) { 816 trip++; 817 for (i = 0; i < tz->trips.passive.devices.count; 818 i++) { 819 handle = tz->trips.passive.devices.handles[i]; 820 status = acpi_bus_get_device(handle, &dev); 821 if (ACPI_SUCCESS(status) && (dev == device)) { 822 result = action(thermal, trip, cdev); 823 if (result) 824 goto failed; 825 } 826 } 827 } 828 829 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { 830 if (!tz->trips.active[i].flags.valid) 831 break; 832 trip++; 833 for (j = 0; 834 j < tz->trips.active[i].devices.count; 835 j++) { 836 handle = tz->trips.active[i].devices.handles[j]; 837 status = acpi_bus_get_device(handle, &dev); 838 if (ACPI_SUCCESS(status) && (dev == device)) { 839 result = action(thermal, trip, cdev); 840 if (result) 841 goto failed; 842 } 843 } 844 } 845 846 for (i = 0; i < tz->devices.count; i++) { 847 handle = tz->devices.handles[i]; 848 status = acpi_bus_get_device(handle, &dev); 849 if (ACPI_SUCCESS(status) && (dev == device)) { 850 result = action(thermal, -1, cdev); 851 if (result) 852 goto failed; 853 } 854 } 855 856 failed: 857 return result; 858 } 859 860 static int 861 acpi_thermal_bind_cooling_device(struct thermal_zone_device *thermal, 862 struct thermal_cooling_device *cdev) 863 { 864 return acpi_thermal_cooling_device_cb(thermal, cdev, 865 thermal_zone_bind_cooling_device); 866 } 867 868 static int 869 acpi_thermal_unbind_cooling_device(struct thermal_zone_device *thermal, 870 struct thermal_cooling_device *cdev) 871 { 872 return acpi_thermal_cooling_device_cb(thermal, cdev, 873 thermal_zone_unbind_cooling_device); 874 } 875 876 static struct thermal_zone_device_ops acpi_thermal_zone_ops = { 877 .bind = acpi_thermal_bind_cooling_device, 878 .unbind = acpi_thermal_unbind_cooling_device, 879 .get_temp = thermal_get_temp, 880 .get_mode = thermal_get_mode, 881 .set_mode = thermal_set_mode, 882 .get_trip_type = thermal_get_trip_type, 883 .get_trip_temp = thermal_get_trip_temp, 884 .get_crit_temp = thermal_get_crit_temp, 885 .notify = thermal_notify, 886 }; 887 888 static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz) 889 { 890 int trips = 0; 891 int result; 892 acpi_status status; 893 int i; 894 895 if (tz->trips.critical.flags.valid) 896 trips++; 897 898 if (tz->trips.hot.flags.valid) 899 trips++; 900 901 if (tz->trips.passive.flags.valid) 902 trips++; 903 904 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE && 905 tz->trips.active[i].flags.valid; i++, trips++); 906 907 if (tz->trips.passive.flags.valid) 908 tz->thermal_zone = 909 thermal_zone_device_register("acpitz", trips, tz, 910 &acpi_thermal_zone_ops, 911 tz->trips.passive.tc1, 912 tz->trips.passive.tc2, 913 tz->trips.passive.tsp*100, 914 tz->polling_frequency*100); 915 else 916 tz->thermal_zone = 917 thermal_zone_device_register("acpitz", trips, tz, 918 &acpi_thermal_zone_ops, 919 0, 0, 0, 920 tz->polling_frequency*100); 921 if (IS_ERR(tz->thermal_zone)) 922 return -ENODEV; 923 924 result = sysfs_create_link(&tz->device->dev.kobj, 925 &tz->thermal_zone->device.kobj, "thermal_zone"); 926 if (result) 927 return result; 928 929 result = sysfs_create_link(&tz->thermal_zone->device.kobj, 930 &tz->device->dev.kobj, "device"); 931 if (result) 932 return result; 933 934 status = acpi_attach_data(tz->device->handle, 935 acpi_bus_private_data_handler, 936 tz->thermal_zone); 937 if (ACPI_FAILURE(status)) { 938 printk(KERN_ERR PREFIX 939 "Error attaching device data\n"); 940 return -ENODEV; 941 } 942 943 tz->tz_enabled = 1; 944 945 dev_info(&tz->device->dev, "registered as thermal_zone%d\n", 946 tz->thermal_zone->id); 947 return 0; 948 } 949 950 static void acpi_thermal_unregister_thermal_zone(struct acpi_thermal *tz) 951 { 952 sysfs_remove_link(&tz->device->dev.kobj, "thermal_zone"); 953 sysfs_remove_link(&tz->thermal_zone->device.kobj, "device"); 954 thermal_zone_device_unregister(tz->thermal_zone); 955 tz->thermal_zone = NULL; 956 acpi_detach_data(tz->device->handle, acpi_bus_private_data_handler); 957 } 958 959 960 /* -------------------------------------------------------------------------- 961 FS Interface (/proc) 962 -------------------------------------------------------------------------- */ 963 #ifdef CONFIG_ACPI_PROCFS 964 static struct proc_dir_entry *acpi_thermal_dir; 965 966 static int acpi_thermal_state_seq_show(struct seq_file *seq, void *offset) 967 { 968 struct acpi_thermal *tz = seq->private; 969 970 971 if (!tz) 972 goto end; 973 974 seq_puts(seq, "state: "); 975 976 if (!tz->state.critical && !tz->state.hot && !tz->state.passive 977 && !tz->state.active) 978 seq_puts(seq, "ok\n"); 979 else { 980 if (tz->state.critical) 981 seq_puts(seq, "critical "); 982 if (tz->state.hot) 983 seq_puts(seq, "hot "); 984 if (tz->state.passive) 985 seq_puts(seq, "passive "); 986 if (tz->state.active) 987 seq_printf(seq, "active[%d]", tz->state.active_index); 988 seq_puts(seq, "\n"); 989 } 990 991 end: 992 return 0; 993 } 994 995 static int acpi_thermal_state_open_fs(struct inode *inode, struct file *file) 996 { 997 return single_open(file, acpi_thermal_state_seq_show, PDE(inode)->data); 998 } 999 1000 static int acpi_thermal_temp_seq_show(struct seq_file *seq, void *offset) 1001 { 1002 int result = 0; 1003 struct acpi_thermal *tz = seq->private; 1004 1005 1006 if (!tz) 1007 goto end; 1008 1009 result = acpi_thermal_get_temperature(tz); 1010 if (result) 1011 goto end; 1012 1013 seq_printf(seq, "temperature: %ld C\n", 1014 KELVIN_TO_CELSIUS(tz->temperature)); 1015 1016 end: 1017 return 0; 1018 } 1019 1020 static int acpi_thermal_temp_open_fs(struct inode *inode, struct file *file) 1021 { 1022 return single_open(file, acpi_thermal_temp_seq_show, PDE(inode)->data); 1023 } 1024 1025 static int acpi_thermal_trip_seq_show(struct seq_file *seq, void *offset) 1026 { 1027 struct acpi_thermal *tz = seq->private; 1028 struct acpi_device *device; 1029 acpi_status status; 1030 1031 int i = 0; 1032 int j = 0; 1033 1034 1035 if (!tz) 1036 goto end; 1037 1038 if (tz->trips.critical.flags.valid) 1039 seq_printf(seq, "critical (S5): %ld C%s", 1040 KELVIN_TO_CELSIUS(tz->trips.critical.temperature), 1041 nocrt ? " <disabled>\n" : "\n"); 1042 1043 if (tz->trips.hot.flags.valid) 1044 seq_printf(seq, "hot (S4): %ld C%s", 1045 KELVIN_TO_CELSIUS(tz->trips.hot.temperature), 1046 nocrt ? " <disabled>\n" : "\n"); 1047 1048 if (tz->trips.passive.flags.valid) { 1049 seq_printf(seq, 1050 "passive: %ld C: tc1=%lu tc2=%lu tsp=%lu devices=", 1051 KELVIN_TO_CELSIUS(tz->trips.passive.temperature), 1052 tz->trips.passive.tc1, tz->trips.passive.tc2, 1053 tz->trips.passive.tsp); 1054 for (j = 0; j < tz->trips.passive.devices.count; j++) { 1055 status = acpi_bus_get_device(tz->trips.passive.devices. 1056 handles[j], &device); 1057 seq_printf(seq, "%4.4s ", status ? "" : 1058 acpi_device_bid(device)); 1059 } 1060 seq_puts(seq, "\n"); 1061 } else { 1062 seq_printf(seq, "passive (forced):"); 1063 if (tz->thermal_zone->forced_passive) 1064 seq_printf(seq, " %i C\n", 1065 tz->thermal_zone->forced_passive / 1000); 1066 else 1067 seq_printf(seq, "<not set>\n"); 1068 } 1069 1070 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { 1071 if (!(tz->trips.active[i].flags.valid)) 1072 break; 1073 seq_printf(seq, "active[%d]: %ld C: devices=", 1074 i, 1075 KELVIN_TO_CELSIUS(tz->trips.active[i].temperature)); 1076 for (j = 0; j < tz->trips.active[i].devices.count; j++){ 1077 status = acpi_bus_get_device(tz->trips.active[i]. 1078 devices.handles[j], 1079 &device); 1080 seq_printf(seq, "%4.4s ", status ? "" : 1081 acpi_device_bid(device)); 1082 } 1083 seq_puts(seq, "\n"); 1084 } 1085 1086 end: 1087 return 0; 1088 } 1089 1090 static int acpi_thermal_trip_open_fs(struct inode *inode, struct file *file) 1091 { 1092 return single_open(file, acpi_thermal_trip_seq_show, PDE(inode)->data); 1093 } 1094 1095 static int acpi_thermal_cooling_seq_show(struct seq_file *seq, void *offset) 1096 { 1097 struct acpi_thermal *tz = seq->private; 1098 1099 1100 if (!tz) 1101 goto end; 1102 1103 if (!tz->flags.cooling_mode) 1104 seq_puts(seq, "<setting not supported>\n"); 1105 else 1106 seq_puts(seq, "0 - Active; 1 - Passive\n"); 1107 1108 end: 1109 return 0; 1110 } 1111 1112 static int acpi_thermal_cooling_open_fs(struct inode *inode, struct file *file) 1113 { 1114 return single_open(file, acpi_thermal_cooling_seq_show, 1115 PDE(inode)->data); 1116 } 1117 1118 static ssize_t 1119 acpi_thermal_write_cooling_mode(struct file *file, 1120 const char __user * buffer, 1121 size_t count, loff_t * ppos) 1122 { 1123 struct seq_file *m = file->private_data; 1124 struct acpi_thermal *tz = m->private; 1125 int result = 0; 1126 char mode_string[12] = { '\0' }; 1127 1128 1129 if (!tz || (count > sizeof(mode_string) - 1)) 1130 return -EINVAL; 1131 1132 if (!tz->flags.cooling_mode) 1133 return -ENODEV; 1134 1135 if (copy_from_user(mode_string, buffer, count)) 1136 return -EFAULT; 1137 1138 mode_string[count] = '\0'; 1139 1140 result = acpi_thermal_set_cooling_mode(tz, 1141 simple_strtoul(mode_string, NULL, 1142 0)); 1143 if (result) 1144 return result; 1145 1146 acpi_thermal_check(tz); 1147 1148 return count; 1149 } 1150 1151 static int acpi_thermal_polling_seq_show(struct seq_file *seq, void *offset) 1152 { 1153 struct acpi_thermal *tz = seq->private; 1154 1155 1156 if (!tz) 1157 goto end; 1158 1159 if (!tz->thermal_zone->polling_delay) { 1160 seq_puts(seq, "<polling disabled>\n"); 1161 goto end; 1162 } 1163 1164 seq_printf(seq, "polling frequency: %d seconds\n", 1165 (tz->thermal_zone->polling_delay / 1000)); 1166 1167 end: 1168 return 0; 1169 } 1170 1171 static int acpi_thermal_polling_open_fs(struct inode *inode, struct file *file) 1172 { 1173 return single_open(file, acpi_thermal_polling_seq_show, 1174 PDE(inode)->data); 1175 } 1176 1177 static int acpi_thermal_set_polling(struct acpi_thermal *tz, int seconds) 1178 { 1179 if (!tz) 1180 return -EINVAL; 1181 1182 /* Convert value to deci-seconds */ 1183 tz->polling_frequency = seconds * 10; 1184 1185 tz->thermal_zone->polling_delay = seconds * 1000; 1186 1187 if (tz->tz_enabled) 1188 thermal_zone_device_update(tz->thermal_zone); 1189 1190 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 1191 "Polling frequency set to %lu seconds\n", 1192 tz->polling_frequency/10)); 1193 1194 return 0; 1195 } 1196 1197 static ssize_t 1198 acpi_thermal_write_polling(struct file *file, 1199 const char __user * buffer, 1200 size_t count, loff_t * ppos) 1201 { 1202 struct seq_file *m = file->private_data; 1203 struct acpi_thermal *tz = m->private; 1204 int result = 0; 1205 char polling_string[12] = { '\0' }; 1206 int seconds = 0; 1207 1208 1209 if (!tz || (count > sizeof(polling_string) - 1)) 1210 return -EINVAL; 1211 1212 if (copy_from_user(polling_string, buffer, count)) 1213 return -EFAULT; 1214 1215 polling_string[count] = '\0'; 1216 1217 seconds = simple_strtoul(polling_string, NULL, 0); 1218 1219 result = acpi_thermal_set_polling(tz, seconds); 1220 if (result) 1221 return result; 1222 1223 acpi_thermal_check(tz); 1224 1225 return count; 1226 } 1227 1228 static int acpi_thermal_add_fs(struct acpi_device *device) 1229 { 1230 struct proc_dir_entry *entry = NULL; 1231 1232 1233 if (!acpi_device_dir(device)) { 1234 acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), 1235 acpi_thermal_dir); 1236 if (!acpi_device_dir(device)) 1237 return -ENODEV; 1238 } 1239 1240 /* 'state' [R] */ 1241 entry = proc_create_data(ACPI_THERMAL_FILE_STATE, 1242 S_IRUGO, acpi_device_dir(device), 1243 &acpi_thermal_state_fops, 1244 acpi_driver_data(device)); 1245 if (!entry) 1246 return -ENODEV; 1247 1248 /* 'temperature' [R] */ 1249 entry = proc_create_data(ACPI_THERMAL_FILE_TEMPERATURE, 1250 S_IRUGO, acpi_device_dir(device), 1251 &acpi_thermal_temp_fops, 1252 acpi_driver_data(device)); 1253 if (!entry) 1254 return -ENODEV; 1255 1256 /* 'trip_points' [R] */ 1257 entry = proc_create_data(ACPI_THERMAL_FILE_TRIP_POINTS, 1258 S_IRUGO, 1259 acpi_device_dir(device), 1260 &acpi_thermal_trip_fops, 1261 acpi_driver_data(device)); 1262 if (!entry) 1263 return -ENODEV; 1264 1265 /* 'cooling_mode' [R/W] */ 1266 entry = proc_create_data(ACPI_THERMAL_FILE_COOLING_MODE, 1267 S_IFREG | S_IRUGO | S_IWUSR, 1268 acpi_device_dir(device), 1269 &acpi_thermal_cooling_fops, 1270 acpi_driver_data(device)); 1271 if (!entry) 1272 return -ENODEV; 1273 1274 /* 'polling_frequency' [R/W] */ 1275 entry = proc_create_data(ACPI_THERMAL_FILE_POLLING_FREQ, 1276 S_IFREG | S_IRUGO | S_IWUSR, 1277 acpi_device_dir(device), 1278 &acpi_thermal_polling_fops, 1279 acpi_driver_data(device)); 1280 if (!entry) 1281 return -ENODEV; 1282 return 0; 1283 } 1284 1285 static int acpi_thermal_remove_fs(struct acpi_device *device) 1286 { 1287 1288 if (acpi_device_dir(device)) { 1289 remove_proc_entry(ACPI_THERMAL_FILE_POLLING_FREQ, 1290 acpi_device_dir(device)); 1291 remove_proc_entry(ACPI_THERMAL_FILE_COOLING_MODE, 1292 acpi_device_dir(device)); 1293 remove_proc_entry(ACPI_THERMAL_FILE_TRIP_POINTS, 1294 acpi_device_dir(device)); 1295 remove_proc_entry(ACPI_THERMAL_FILE_TEMPERATURE, 1296 acpi_device_dir(device)); 1297 remove_proc_entry(ACPI_THERMAL_FILE_STATE, 1298 acpi_device_dir(device)); 1299 remove_proc_entry(acpi_device_bid(device), acpi_thermal_dir); 1300 acpi_device_dir(device) = NULL; 1301 } 1302 1303 return 0; 1304 } 1305 #else 1306 static inline int acpi_thermal_add_fs(struct acpi_device *device) { return 0; } 1307 static inline int acpi_thermal_remove_fs(struct acpi_device *device) 1308 { 1309 return 0; 1310 } 1311 #endif /* CONFIG_ACPI_PROCFS */ 1312 /* -------------------------------------------------------------------------- 1313 Driver Interface 1314 -------------------------------------------------------------------------- */ 1315 1316 static void acpi_thermal_notify(struct acpi_device *device, u32 event) 1317 { 1318 struct acpi_thermal *tz = acpi_driver_data(device); 1319 1320 1321 if (!tz) 1322 return; 1323 1324 switch (event) { 1325 case ACPI_THERMAL_NOTIFY_TEMPERATURE: 1326 acpi_thermal_check(tz); 1327 break; 1328 case ACPI_THERMAL_NOTIFY_THRESHOLDS: 1329 acpi_thermal_trips_update(tz, ACPI_TRIPS_REFRESH_THRESHOLDS); 1330 acpi_thermal_check(tz); 1331 acpi_bus_generate_proc_event(device, event, 0); 1332 acpi_bus_generate_netlink_event(device->pnp.device_class, 1333 dev_name(&device->dev), event, 0); 1334 break; 1335 case ACPI_THERMAL_NOTIFY_DEVICES: 1336 acpi_thermal_trips_update(tz, ACPI_TRIPS_REFRESH_DEVICES); 1337 acpi_thermal_check(tz); 1338 acpi_bus_generate_proc_event(device, event, 0); 1339 acpi_bus_generate_netlink_event(device->pnp.device_class, 1340 dev_name(&device->dev), event, 0); 1341 break; 1342 default: 1343 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 1344 "Unsupported event [0x%x]\n", event)); 1345 break; 1346 } 1347 } 1348 1349 static int acpi_thermal_get_info(struct acpi_thermal *tz) 1350 { 1351 int result = 0; 1352 1353 1354 if (!tz) 1355 return -EINVAL; 1356 1357 /* Get temperature [_TMP] (required) */ 1358 result = acpi_thermal_get_temperature(tz); 1359 if (result) 1360 return result; 1361 1362 /* Get trip points [_CRT, _PSV, etc.] (required) */ 1363 result = acpi_thermal_get_trip_points(tz); 1364 if (result) 1365 return result; 1366 1367 /* Set the cooling mode [_SCP] to active cooling (default) */ 1368 result = acpi_thermal_set_cooling_mode(tz, ACPI_THERMAL_MODE_ACTIVE); 1369 if (!result) 1370 tz->flags.cooling_mode = 1; 1371 1372 /* Get default polling frequency [_TZP] (optional) */ 1373 if (tzp) 1374 tz->polling_frequency = tzp; 1375 else 1376 acpi_thermal_get_polling_frequency(tz); 1377 1378 return 0; 1379 } 1380 1381 /* 1382 * The exact offset between Kelvin and degree Celsius is 273.15. However ACPI 1383 * handles temperature values with a single decimal place. As a consequence, 1384 * some implementations use an offset of 273.1 and others use an offset of 1385 * 273.2. Try to find out which one is being used, to present the most 1386 * accurate and visually appealing number. 1387 * 1388 * The heuristic below should work for all ACPI thermal zones which have a 1389 * critical trip point with a value being a multiple of 0.5 degree Celsius. 1390 */ 1391 static void acpi_thermal_guess_offset(struct acpi_thermal *tz) 1392 { 1393 if (tz->trips.critical.flags.valid && 1394 (tz->trips.critical.temperature % 5) == 1) 1395 tz->kelvin_offset = 2731; 1396 else 1397 tz->kelvin_offset = 2732; 1398 } 1399 1400 static int acpi_thermal_add(struct acpi_device *device) 1401 { 1402 int result = 0; 1403 struct acpi_thermal *tz = NULL; 1404 1405 1406 if (!device) 1407 return -EINVAL; 1408 1409 tz = kzalloc(sizeof(struct acpi_thermal), GFP_KERNEL); 1410 if (!tz) 1411 return -ENOMEM; 1412 1413 tz->device = device; 1414 strcpy(tz->name, device->pnp.bus_id); 1415 strcpy(acpi_device_name(device), ACPI_THERMAL_DEVICE_NAME); 1416 strcpy(acpi_device_class(device), ACPI_THERMAL_CLASS); 1417 device->driver_data = tz; 1418 mutex_init(&tz->lock); 1419 1420 1421 result = acpi_thermal_get_info(tz); 1422 if (result) 1423 goto free_memory; 1424 1425 acpi_thermal_guess_offset(tz); 1426 1427 result = acpi_thermal_register_thermal_zone(tz); 1428 if (result) 1429 goto free_memory; 1430 1431 result = acpi_thermal_add_fs(device); 1432 if (result) 1433 goto unregister_thermal_zone; 1434 1435 printk(KERN_INFO PREFIX "%s [%s] (%ld C)\n", 1436 acpi_device_name(device), acpi_device_bid(device), 1437 KELVIN_TO_CELSIUS(tz->temperature)); 1438 goto end; 1439 1440 unregister_thermal_zone: 1441 thermal_zone_device_unregister(tz->thermal_zone); 1442 free_memory: 1443 kfree(tz); 1444 end: 1445 return result; 1446 } 1447 1448 static int acpi_thermal_remove(struct acpi_device *device, int type) 1449 { 1450 struct acpi_thermal *tz = NULL; 1451 1452 if (!device || !acpi_driver_data(device)) 1453 return -EINVAL; 1454 1455 tz = acpi_driver_data(device); 1456 1457 acpi_thermal_remove_fs(device); 1458 acpi_thermal_unregister_thermal_zone(tz); 1459 mutex_destroy(&tz->lock); 1460 kfree(tz); 1461 return 0; 1462 } 1463 1464 static int acpi_thermal_resume(struct acpi_device *device) 1465 { 1466 struct acpi_thermal *tz = NULL; 1467 int i, j, power_state, result; 1468 1469 1470 if (!device || !acpi_driver_data(device)) 1471 return -EINVAL; 1472 1473 tz = acpi_driver_data(device); 1474 1475 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { 1476 if (!(&tz->trips.active[i])) 1477 break; 1478 if (!tz->trips.active[i].flags.valid) 1479 break; 1480 tz->trips.active[i].flags.enabled = 1; 1481 for (j = 0; j < tz->trips.active[i].devices.count; j++) { 1482 result = acpi_bus_get_power(tz->trips.active[i].devices. 1483 handles[j], &power_state); 1484 if (result || (power_state != ACPI_STATE_D0)) { 1485 tz->trips.active[i].flags.enabled = 0; 1486 break; 1487 } 1488 } 1489 tz->state.active |= tz->trips.active[i].flags.enabled; 1490 } 1491 1492 acpi_thermal_check(tz); 1493 1494 return AE_OK; 1495 } 1496 1497 static int thermal_act(const struct dmi_system_id *d) { 1498 1499 if (act == 0) { 1500 printk(KERN_NOTICE "ACPI: %s detected: " 1501 "disabling all active thermal trip points\n", d->ident); 1502 act = -1; 1503 } 1504 return 0; 1505 } 1506 static int thermal_nocrt(const struct dmi_system_id *d) { 1507 1508 printk(KERN_NOTICE "ACPI: %s detected: " 1509 "disabling all critical thermal trip point actions.\n", d->ident); 1510 nocrt = 1; 1511 return 0; 1512 } 1513 static int thermal_tzp(const struct dmi_system_id *d) { 1514 1515 if (tzp == 0) { 1516 printk(KERN_NOTICE "ACPI: %s detected: " 1517 "enabling thermal zone polling\n", d->ident); 1518 tzp = 300; /* 300 dS = 30 Seconds */ 1519 } 1520 return 0; 1521 } 1522 static int thermal_psv(const struct dmi_system_id *d) { 1523 1524 if (psv == 0) { 1525 printk(KERN_NOTICE "ACPI: %s detected: " 1526 "disabling all passive thermal trip points\n", d->ident); 1527 psv = -1; 1528 } 1529 return 0; 1530 } 1531 1532 static struct dmi_system_id thermal_dmi_table[] __initdata = { 1533 /* 1534 * Award BIOS on this AOpen makes thermal control almost worthless. 1535 * http://bugzilla.kernel.org/show_bug.cgi?id=8842 1536 */ 1537 { 1538 .callback = thermal_act, 1539 .ident = "AOpen i915GMm-HFS", 1540 .matches = { 1541 DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"), 1542 DMI_MATCH(DMI_BOARD_NAME, "i915GMm-HFS"), 1543 }, 1544 }, 1545 { 1546 .callback = thermal_psv, 1547 .ident = "AOpen i915GMm-HFS", 1548 .matches = { 1549 DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"), 1550 DMI_MATCH(DMI_BOARD_NAME, "i915GMm-HFS"), 1551 }, 1552 }, 1553 { 1554 .callback = thermal_tzp, 1555 .ident = "AOpen i915GMm-HFS", 1556 .matches = { 1557 DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"), 1558 DMI_MATCH(DMI_BOARD_NAME, "i915GMm-HFS"), 1559 }, 1560 }, 1561 { 1562 .callback = thermal_nocrt, 1563 .ident = "Gigabyte GA-7ZX", 1564 .matches = { 1565 DMI_MATCH(DMI_BOARD_VENDOR, "Gigabyte Technology Co., Ltd."), 1566 DMI_MATCH(DMI_BOARD_NAME, "7ZX"), 1567 }, 1568 }, 1569 {} 1570 }; 1571 1572 static int __init acpi_thermal_init(void) 1573 { 1574 int result = 0; 1575 1576 dmi_check_system(thermal_dmi_table); 1577 1578 if (off) { 1579 printk(KERN_NOTICE "ACPI: thermal control disabled\n"); 1580 return -ENODEV; 1581 } 1582 1583 #ifdef CONFIG_ACPI_PROCFS 1584 acpi_thermal_dir = proc_mkdir(ACPI_THERMAL_CLASS, acpi_root_dir); 1585 if (!acpi_thermal_dir) 1586 return -ENODEV; 1587 #endif 1588 1589 result = acpi_bus_register_driver(&acpi_thermal_driver); 1590 if (result < 0) { 1591 #ifdef CONFIG_ACPI_PROCFS 1592 remove_proc_entry(ACPI_THERMAL_CLASS, acpi_root_dir); 1593 #endif 1594 return -ENODEV; 1595 } 1596 1597 return 0; 1598 } 1599 1600 static void __exit acpi_thermal_exit(void) 1601 { 1602 1603 acpi_bus_unregister_driver(&acpi_thermal_driver); 1604 1605 #ifdef CONFIG_ACPI_PROCFS 1606 remove_proc_entry(ACPI_THERMAL_CLASS, acpi_root_dir); 1607 #endif 1608 1609 return; 1610 } 1611 1612 module_init(acpi_thermal_init); 1613 module_exit(acpi_thermal_exit); 1614