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 #include <linux/jiffies.h> 41 #include <linux/kmod.h> 42 #include <linux/reboot.h> 43 #include <linux/device.h> 44 #include <linux/thermal.h> 45 #include <linux/acpi.h> 46 #include <asm/uaccess.h> 47 48 #define PREFIX "ACPI: " 49 50 #define ACPI_THERMAL_CLASS "thermal_zone" 51 #define ACPI_THERMAL_DEVICE_NAME "Thermal Zone" 52 #define ACPI_THERMAL_NOTIFY_TEMPERATURE 0x80 53 #define ACPI_THERMAL_NOTIFY_THRESHOLDS 0x81 54 #define ACPI_THERMAL_NOTIFY_DEVICES 0x82 55 #define ACPI_THERMAL_NOTIFY_CRITICAL 0xF0 56 #define ACPI_THERMAL_NOTIFY_HOT 0xF1 57 #define ACPI_THERMAL_MODE_ACTIVE 0x00 58 59 #define ACPI_THERMAL_MAX_ACTIVE 10 60 #define ACPI_THERMAL_MAX_LIMIT_STR_LEN 65 61 62 #define _COMPONENT ACPI_THERMAL_COMPONENT 63 ACPI_MODULE_NAME("thermal"); 64 65 MODULE_AUTHOR("Paul Diefenbaugh"); 66 MODULE_DESCRIPTION("ACPI Thermal Zone Driver"); 67 MODULE_LICENSE("GPL"); 68 69 static int act; 70 module_param(act, int, 0644); 71 MODULE_PARM_DESC(act, "Disable or override all lowest active trip points."); 72 73 static int crt; 74 module_param(crt, int, 0644); 75 MODULE_PARM_DESC(crt, "Disable or lower all critical trip points."); 76 77 static int tzp; 78 module_param(tzp, int, 0444); 79 MODULE_PARM_DESC(tzp, "Thermal zone polling frequency, in 1/10 seconds."); 80 81 static int nocrt; 82 module_param(nocrt, int, 0); 83 MODULE_PARM_DESC(nocrt, "Set to take no action upon ACPI thermal zone critical trips points."); 84 85 static int off; 86 module_param(off, int, 0); 87 MODULE_PARM_DESC(off, "Set to disable ACPI thermal support."); 88 89 static int psv; 90 module_param(psv, int, 0644); 91 MODULE_PARM_DESC(psv, "Disable or override all passive trip points."); 92 93 static int acpi_thermal_add(struct acpi_device *device); 94 static int acpi_thermal_remove(struct acpi_device *device); 95 static void acpi_thermal_notify(struct acpi_device *device, u32 event); 96 97 static const struct acpi_device_id thermal_device_ids[] = { 98 {ACPI_THERMAL_HID, 0}, 99 {"", 0}, 100 }; 101 MODULE_DEVICE_TABLE(acpi, thermal_device_ids); 102 103 #ifdef CONFIG_PM_SLEEP 104 static int acpi_thermal_resume(struct device *dev); 105 #endif 106 static SIMPLE_DEV_PM_OPS(acpi_thermal_pm, NULL, acpi_thermal_resume); 107 108 static struct acpi_driver acpi_thermal_driver = { 109 .name = "thermal", 110 .class = ACPI_THERMAL_CLASS, 111 .ids = thermal_device_ids, 112 .ops = { 113 .add = acpi_thermal_add, 114 .remove = acpi_thermal_remove, 115 .notify = acpi_thermal_notify, 116 }, 117 .drv.pm = &acpi_thermal_pm, 118 }; 119 120 struct acpi_thermal_state { 121 u8 critical:1; 122 u8 hot:1; 123 u8 passive:1; 124 u8 active:1; 125 u8 reserved:4; 126 int active_index; 127 }; 128 129 struct acpi_thermal_state_flags { 130 u8 valid:1; 131 u8 enabled:1; 132 u8 reserved:6; 133 }; 134 135 struct acpi_thermal_critical { 136 struct acpi_thermal_state_flags flags; 137 unsigned long temperature; 138 }; 139 140 struct acpi_thermal_hot { 141 struct acpi_thermal_state_flags flags; 142 unsigned long temperature; 143 }; 144 145 struct acpi_thermal_passive { 146 struct acpi_thermal_state_flags flags; 147 unsigned long temperature; 148 unsigned long tc1; 149 unsigned long tc2; 150 unsigned long tsp; 151 struct acpi_handle_list devices; 152 }; 153 154 struct acpi_thermal_active { 155 struct acpi_thermal_state_flags flags; 156 unsigned long temperature; 157 struct acpi_handle_list devices; 158 }; 159 160 struct acpi_thermal_trips { 161 struct acpi_thermal_critical critical; 162 struct acpi_thermal_hot hot; 163 struct acpi_thermal_passive passive; 164 struct acpi_thermal_active active[ACPI_THERMAL_MAX_ACTIVE]; 165 }; 166 167 struct acpi_thermal_flags { 168 u8 cooling_mode:1; /* _SCP */ 169 u8 devices:1; /* _TZD */ 170 u8 reserved:6; 171 }; 172 173 struct acpi_thermal { 174 struct acpi_device * device; 175 acpi_bus_id name; 176 unsigned long temperature; 177 unsigned long last_temperature; 178 unsigned long polling_frequency; 179 volatile u8 zombie; 180 struct acpi_thermal_flags flags; 181 struct acpi_thermal_state state; 182 struct acpi_thermal_trips trips; 183 struct acpi_handle_list devices; 184 struct thermal_zone_device *thermal_zone; 185 int tz_enabled; 186 int kelvin_offset; 187 }; 188 189 /* -------------------------------------------------------------------------- 190 Thermal Zone Management 191 -------------------------------------------------------------------------- */ 192 193 static int acpi_thermal_get_temperature(struct acpi_thermal *tz) 194 { 195 acpi_status status = AE_OK; 196 unsigned long long tmp; 197 198 if (!tz) 199 return -EINVAL; 200 201 tz->last_temperature = tz->temperature; 202 203 status = acpi_evaluate_integer(tz->device->handle, "_TMP", NULL, &tmp); 204 if (ACPI_FAILURE(status)) 205 return -ENODEV; 206 207 tz->temperature = tmp; 208 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Temperature is %lu dK\n", 209 tz->temperature)); 210 211 return 0; 212 } 213 214 static int acpi_thermal_get_polling_frequency(struct acpi_thermal *tz) 215 { 216 acpi_status status = AE_OK; 217 unsigned long long tmp; 218 219 if (!tz) 220 return -EINVAL; 221 222 status = acpi_evaluate_integer(tz->device->handle, "_TZP", NULL, &tmp); 223 if (ACPI_FAILURE(status)) 224 return -ENODEV; 225 226 tz->polling_frequency = tmp; 227 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Polling frequency is %lu dS\n", 228 tz->polling_frequency)); 229 230 return 0; 231 } 232 233 static int acpi_thermal_set_cooling_mode(struct acpi_thermal *tz, int mode) 234 { 235 if (!tz) 236 return -EINVAL; 237 238 if (!acpi_has_method(tz->device->handle, "_SCP")) { 239 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "_SCP not present\n")); 240 return -ENODEV; 241 } else if (ACPI_FAILURE(acpi_execute_simple_method(tz->device->handle, 242 "_SCP", mode))) { 243 return -ENODEV; 244 } 245 246 return 0; 247 } 248 249 #define ACPI_TRIPS_CRITICAL 0x01 250 #define ACPI_TRIPS_HOT 0x02 251 #define ACPI_TRIPS_PASSIVE 0x04 252 #define ACPI_TRIPS_ACTIVE 0x08 253 #define ACPI_TRIPS_DEVICES 0x10 254 255 #define ACPI_TRIPS_REFRESH_THRESHOLDS (ACPI_TRIPS_PASSIVE | ACPI_TRIPS_ACTIVE) 256 #define ACPI_TRIPS_REFRESH_DEVICES ACPI_TRIPS_DEVICES 257 258 #define ACPI_TRIPS_INIT (ACPI_TRIPS_CRITICAL | ACPI_TRIPS_HOT | \ 259 ACPI_TRIPS_PASSIVE | ACPI_TRIPS_ACTIVE | \ 260 ACPI_TRIPS_DEVICES) 261 262 /* 263 * This exception is thrown out in two cases: 264 * 1.An invalid trip point becomes invalid or a valid trip point becomes invalid 265 * when re-evaluating the AML code. 266 * 2.TODO: Devices listed in _PSL, _ALx, _TZD may change. 267 * We need to re-bind the cooling devices of a thermal zone when this occurs. 268 */ 269 #define ACPI_THERMAL_TRIPS_EXCEPTION(flags, str) \ 270 do { \ 271 if (flags != ACPI_TRIPS_INIT) \ 272 ACPI_EXCEPTION((AE_INFO, AE_ERROR, \ 273 "ACPI thermal trip point %s changed\n" \ 274 "Please send acpidump to linux-acpi@vger.kernel.org", str)); \ 275 } while (0) 276 277 static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag) 278 { 279 acpi_status status = AE_OK; 280 unsigned long long tmp; 281 struct acpi_handle_list devices; 282 int valid = 0; 283 int i; 284 285 /* Critical Shutdown */ 286 if (flag & ACPI_TRIPS_CRITICAL) { 287 status = acpi_evaluate_integer(tz->device->handle, 288 "_CRT", NULL, &tmp); 289 tz->trips.critical.temperature = tmp; 290 /* 291 * Treat freezing temperatures as invalid as well; some 292 * BIOSes return really low values and cause reboots at startup. 293 * Below zero (Celsius) values clearly aren't right for sure.. 294 * ... so lets discard those as invalid. 295 */ 296 if (ACPI_FAILURE(status)) { 297 tz->trips.critical.flags.valid = 0; 298 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 299 "No critical threshold\n")); 300 } else if (tmp <= 2732) { 301 pr_warn(FW_BUG "Invalid critical threshold (%llu)\n", 302 tmp); 303 tz->trips.critical.flags.valid = 0; 304 } else { 305 tz->trips.critical.flags.valid = 1; 306 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 307 "Found critical threshold [%lu]\n", 308 tz->trips.critical.temperature)); 309 } 310 if (tz->trips.critical.flags.valid == 1) { 311 if (crt == -1) { 312 tz->trips.critical.flags.valid = 0; 313 } else if (crt > 0) { 314 unsigned long crt_k = CELSIUS_TO_KELVIN(crt); 315 /* 316 * Allow override critical threshold 317 */ 318 if (crt_k > tz->trips.critical.temperature) 319 pr_warn(PREFIX "Critical threshold %d C\n", 320 crt); 321 tz->trips.critical.temperature = crt_k; 322 } 323 } 324 } 325 326 /* Critical Sleep (optional) */ 327 if (flag & ACPI_TRIPS_HOT) { 328 status = acpi_evaluate_integer(tz->device->handle, 329 "_HOT", NULL, &tmp); 330 if (ACPI_FAILURE(status)) { 331 tz->trips.hot.flags.valid = 0; 332 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 333 "No hot threshold\n")); 334 } else { 335 tz->trips.hot.temperature = tmp; 336 tz->trips.hot.flags.valid = 1; 337 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 338 "Found hot threshold [%lu]\n", 339 tz->trips.critical.temperature)); 340 } 341 } 342 343 /* Passive (optional) */ 344 if (((flag & ACPI_TRIPS_PASSIVE) && tz->trips.passive.flags.valid) || 345 (flag == ACPI_TRIPS_INIT)) { 346 valid = tz->trips.passive.flags.valid; 347 if (psv == -1) { 348 status = AE_SUPPORT; 349 } else if (psv > 0) { 350 tmp = CELSIUS_TO_KELVIN(psv); 351 status = AE_OK; 352 } else { 353 status = acpi_evaluate_integer(tz->device->handle, 354 "_PSV", NULL, &tmp); 355 } 356 357 if (ACPI_FAILURE(status)) 358 tz->trips.passive.flags.valid = 0; 359 else { 360 tz->trips.passive.temperature = tmp; 361 tz->trips.passive.flags.valid = 1; 362 if (flag == ACPI_TRIPS_INIT) { 363 status = acpi_evaluate_integer( 364 tz->device->handle, "_TC1", 365 NULL, &tmp); 366 if (ACPI_FAILURE(status)) 367 tz->trips.passive.flags.valid = 0; 368 else 369 tz->trips.passive.tc1 = tmp; 370 status = acpi_evaluate_integer( 371 tz->device->handle, "_TC2", 372 NULL, &tmp); 373 if (ACPI_FAILURE(status)) 374 tz->trips.passive.flags.valid = 0; 375 else 376 tz->trips.passive.tc2 = tmp; 377 status = acpi_evaluate_integer( 378 tz->device->handle, "_TSP", 379 NULL, &tmp); 380 if (ACPI_FAILURE(status)) 381 tz->trips.passive.flags.valid = 0; 382 else 383 tz->trips.passive.tsp = tmp; 384 } 385 } 386 } 387 if ((flag & ACPI_TRIPS_DEVICES) && tz->trips.passive.flags.valid) { 388 memset(&devices, 0, sizeof(struct acpi_handle_list)); 389 status = acpi_evaluate_reference(tz->device->handle, "_PSL", 390 NULL, &devices); 391 if (ACPI_FAILURE(status)) { 392 pr_warn(PREFIX "Invalid passive threshold\n"); 393 tz->trips.passive.flags.valid = 0; 394 } 395 else 396 tz->trips.passive.flags.valid = 1; 397 398 if (memcmp(&tz->trips.passive.devices, &devices, 399 sizeof(struct acpi_handle_list))) { 400 memcpy(&tz->trips.passive.devices, &devices, 401 sizeof(struct acpi_handle_list)); 402 ACPI_THERMAL_TRIPS_EXCEPTION(flag, "device"); 403 } 404 } 405 if ((flag & ACPI_TRIPS_PASSIVE) || (flag & ACPI_TRIPS_DEVICES)) { 406 if (valid != tz->trips.passive.flags.valid) 407 ACPI_THERMAL_TRIPS_EXCEPTION(flag, "state"); 408 } 409 410 /* Active (optional) */ 411 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { 412 char name[5] = { '_', 'A', 'C', ('0' + i), '\0' }; 413 valid = tz->trips.active[i].flags.valid; 414 415 if (act == -1) 416 break; /* disable all active trip points */ 417 418 if ((flag == ACPI_TRIPS_INIT) || ((flag & ACPI_TRIPS_ACTIVE) && 419 tz->trips.active[i].flags.valid)) { 420 status = acpi_evaluate_integer(tz->device->handle, 421 name, NULL, &tmp); 422 if (ACPI_FAILURE(status)) { 423 tz->trips.active[i].flags.valid = 0; 424 if (i == 0) 425 break; 426 if (act <= 0) 427 break; 428 if (i == 1) 429 tz->trips.active[0].temperature = 430 CELSIUS_TO_KELVIN(act); 431 else 432 /* 433 * Don't allow override higher than 434 * the next higher trip point 435 */ 436 tz->trips.active[i - 1].temperature = 437 (tz->trips.active[i - 2].temperature < 438 CELSIUS_TO_KELVIN(act) ? 439 tz->trips.active[i - 2].temperature : 440 CELSIUS_TO_KELVIN(act)); 441 break; 442 } else { 443 tz->trips.active[i].temperature = tmp; 444 tz->trips.active[i].flags.valid = 1; 445 } 446 } 447 448 name[2] = 'L'; 449 if ((flag & ACPI_TRIPS_DEVICES) && tz->trips.active[i].flags.valid ) { 450 memset(&devices, 0, sizeof(struct acpi_handle_list)); 451 status = acpi_evaluate_reference(tz->device->handle, 452 name, NULL, &devices); 453 if (ACPI_FAILURE(status)) { 454 pr_warn(PREFIX "Invalid active%d threshold\n", 455 i); 456 tz->trips.active[i].flags.valid = 0; 457 } 458 else 459 tz->trips.active[i].flags.valid = 1; 460 461 if (memcmp(&tz->trips.active[i].devices, &devices, 462 sizeof(struct acpi_handle_list))) { 463 memcpy(&tz->trips.active[i].devices, &devices, 464 sizeof(struct acpi_handle_list)); 465 ACPI_THERMAL_TRIPS_EXCEPTION(flag, "device"); 466 } 467 } 468 if ((flag & ACPI_TRIPS_ACTIVE) || (flag & ACPI_TRIPS_DEVICES)) 469 if (valid != tz->trips.active[i].flags.valid) 470 ACPI_THERMAL_TRIPS_EXCEPTION(flag, "state"); 471 472 if (!tz->trips.active[i].flags.valid) 473 break; 474 } 475 476 if ((flag & ACPI_TRIPS_DEVICES) 477 && acpi_has_method(tz->device->handle, "_TZD")) { 478 memset(&devices, 0, sizeof(devices)); 479 status = acpi_evaluate_reference(tz->device->handle, "_TZD", 480 NULL, &devices); 481 if (ACPI_SUCCESS(status) 482 && memcmp(&tz->devices, &devices, sizeof(devices))) { 483 tz->devices = devices; 484 ACPI_THERMAL_TRIPS_EXCEPTION(flag, "device"); 485 } 486 } 487 488 return 0; 489 } 490 491 static int acpi_thermal_get_trip_points(struct acpi_thermal *tz) 492 { 493 int i, valid, ret = acpi_thermal_trips_update(tz, ACPI_TRIPS_INIT); 494 495 if (ret) 496 return ret; 497 498 valid = tz->trips.critical.flags.valid | 499 tz->trips.hot.flags.valid | 500 tz->trips.passive.flags.valid; 501 502 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) 503 valid |= tz->trips.active[i].flags.valid; 504 505 if (!valid) { 506 pr_warn(FW_BUG "No valid trip found\n"); 507 return -ENODEV; 508 } 509 return 0; 510 } 511 512 static void acpi_thermal_check(void *data) 513 { 514 struct acpi_thermal *tz = data; 515 516 if (!tz->tz_enabled) 517 return; 518 519 thermal_zone_device_update(tz->thermal_zone); 520 } 521 522 /* sys I/F for generic thermal sysfs support */ 523 #define KELVIN_TO_MILLICELSIUS(t, off) (((t) - (off)) * 100) 524 525 static int thermal_get_temp(struct thermal_zone_device *thermal, 526 unsigned long *temp) 527 { 528 struct acpi_thermal *tz = thermal->devdata; 529 int result; 530 531 if (!tz) 532 return -EINVAL; 533 534 result = acpi_thermal_get_temperature(tz); 535 if (result) 536 return result; 537 538 *temp = KELVIN_TO_MILLICELSIUS(tz->temperature, tz->kelvin_offset); 539 return 0; 540 } 541 542 static int thermal_get_mode(struct thermal_zone_device *thermal, 543 enum thermal_device_mode *mode) 544 { 545 struct acpi_thermal *tz = thermal->devdata; 546 547 if (!tz) 548 return -EINVAL; 549 550 *mode = tz->tz_enabled ? THERMAL_DEVICE_ENABLED : 551 THERMAL_DEVICE_DISABLED; 552 553 return 0; 554 } 555 556 static int thermal_set_mode(struct thermal_zone_device *thermal, 557 enum thermal_device_mode mode) 558 { 559 struct acpi_thermal *tz = thermal->devdata; 560 int enable; 561 562 if (!tz) 563 return -EINVAL; 564 565 /* 566 * enable/disable thermal management from ACPI thermal driver 567 */ 568 if (mode == THERMAL_DEVICE_ENABLED) 569 enable = 1; 570 else if (mode == THERMAL_DEVICE_DISABLED) { 571 enable = 0; 572 pr_warn("thermal zone will be disabled\n"); 573 } else 574 return -EINVAL; 575 576 if (enable != tz->tz_enabled) { 577 tz->tz_enabled = enable; 578 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 579 "%s kernel ACPI thermal control\n", 580 tz->tz_enabled ? "Enable" : "Disable")); 581 acpi_thermal_check(tz); 582 } 583 return 0; 584 } 585 586 static int thermal_get_trip_type(struct thermal_zone_device *thermal, 587 int trip, enum thermal_trip_type *type) 588 { 589 struct acpi_thermal *tz = thermal->devdata; 590 int i; 591 592 if (!tz || trip < 0) 593 return -EINVAL; 594 595 if (tz->trips.critical.flags.valid) { 596 if (!trip) { 597 *type = THERMAL_TRIP_CRITICAL; 598 return 0; 599 } 600 trip--; 601 } 602 603 if (tz->trips.hot.flags.valid) { 604 if (!trip) { 605 *type = THERMAL_TRIP_HOT; 606 return 0; 607 } 608 trip--; 609 } 610 611 if (tz->trips.passive.flags.valid) { 612 if (!trip) { 613 *type = THERMAL_TRIP_PASSIVE; 614 return 0; 615 } 616 trip--; 617 } 618 619 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE && 620 tz->trips.active[i].flags.valid; i++) { 621 if (!trip) { 622 *type = THERMAL_TRIP_ACTIVE; 623 return 0; 624 } 625 trip--; 626 } 627 628 return -EINVAL; 629 } 630 631 static int thermal_get_trip_temp(struct thermal_zone_device *thermal, 632 int trip, unsigned long *temp) 633 { 634 struct acpi_thermal *tz = thermal->devdata; 635 int i; 636 637 if (!tz || trip < 0) 638 return -EINVAL; 639 640 if (tz->trips.critical.flags.valid) { 641 if (!trip) { 642 *temp = KELVIN_TO_MILLICELSIUS( 643 tz->trips.critical.temperature, 644 tz->kelvin_offset); 645 return 0; 646 } 647 trip--; 648 } 649 650 if (tz->trips.hot.flags.valid) { 651 if (!trip) { 652 *temp = KELVIN_TO_MILLICELSIUS( 653 tz->trips.hot.temperature, 654 tz->kelvin_offset); 655 return 0; 656 } 657 trip--; 658 } 659 660 if (tz->trips.passive.flags.valid) { 661 if (!trip) { 662 *temp = KELVIN_TO_MILLICELSIUS( 663 tz->trips.passive.temperature, 664 tz->kelvin_offset); 665 return 0; 666 } 667 trip--; 668 } 669 670 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE && 671 tz->trips.active[i].flags.valid; i++) { 672 if (!trip) { 673 *temp = KELVIN_TO_MILLICELSIUS( 674 tz->trips.active[i].temperature, 675 tz->kelvin_offset); 676 return 0; 677 } 678 trip--; 679 } 680 681 return -EINVAL; 682 } 683 684 static int thermal_get_crit_temp(struct thermal_zone_device *thermal, 685 unsigned long *temperature) { 686 struct acpi_thermal *tz = thermal->devdata; 687 688 if (tz->trips.critical.flags.valid) { 689 *temperature = KELVIN_TO_MILLICELSIUS( 690 tz->trips.critical.temperature, 691 tz->kelvin_offset); 692 return 0; 693 } else 694 return -EINVAL; 695 } 696 697 static int thermal_get_trend(struct thermal_zone_device *thermal, 698 int trip, enum thermal_trend *trend) 699 { 700 struct acpi_thermal *tz = thermal->devdata; 701 enum thermal_trip_type type; 702 int i; 703 704 if (thermal_get_trip_type(thermal, trip, &type)) 705 return -EINVAL; 706 707 if (type == THERMAL_TRIP_ACTIVE) { 708 unsigned long trip_temp; 709 unsigned long temp = KELVIN_TO_MILLICELSIUS(tz->temperature, 710 tz->kelvin_offset); 711 if (thermal_get_trip_temp(thermal, trip, &trip_temp)) 712 return -EINVAL; 713 714 if (temp > trip_temp) { 715 *trend = THERMAL_TREND_RAISING; 716 return 0; 717 } else { 718 /* Fall back on default trend */ 719 return -EINVAL; 720 } 721 } 722 723 /* 724 * tz->temperature has already been updated by generic thermal layer, 725 * before this callback being invoked 726 */ 727 i = (tz->trips.passive.tc1 * (tz->temperature - tz->last_temperature)) 728 + (tz->trips.passive.tc2 729 * (tz->temperature - tz->trips.passive.temperature)); 730 731 if (i > 0) 732 *trend = THERMAL_TREND_RAISING; 733 else if (i < 0) 734 *trend = THERMAL_TREND_DROPPING; 735 else 736 *trend = THERMAL_TREND_STABLE; 737 return 0; 738 } 739 740 741 static int thermal_notify(struct thermal_zone_device *thermal, int trip, 742 enum thermal_trip_type trip_type) 743 { 744 u8 type = 0; 745 struct acpi_thermal *tz = thermal->devdata; 746 747 if (trip_type == THERMAL_TRIP_CRITICAL) 748 type = ACPI_THERMAL_NOTIFY_CRITICAL; 749 else if (trip_type == THERMAL_TRIP_HOT) 750 type = ACPI_THERMAL_NOTIFY_HOT; 751 else 752 return 0; 753 754 acpi_bus_generate_netlink_event(tz->device->pnp.device_class, 755 dev_name(&tz->device->dev), type, 1); 756 757 if (trip_type == THERMAL_TRIP_CRITICAL && nocrt) 758 return 1; 759 760 return 0; 761 } 762 763 static int acpi_thermal_cooling_device_cb(struct thermal_zone_device *thermal, 764 struct thermal_cooling_device *cdev, 765 bool bind) 766 { 767 struct acpi_device *device = cdev->devdata; 768 struct acpi_thermal *tz = thermal->devdata; 769 struct acpi_device *dev; 770 acpi_status status; 771 acpi_handle handle; 772 int i; 773 int j; 774 int trip = -1; 775 int result = 0; 776 777 if (tz->trips.critical.flags.valid) 778 trip++; 779 780 if (tz->trips.hot.flags.valid) 781 trip++; 782 783 if (tz->trips.passive.flags.valid) { 784 trip++; 785 for (i = 0; i < tz->trips.passive.devices.count; 786 i++) { 787 handle = tz->trips.passive.devices.handles[i]; 788 status = acpi_bus_get_device(handle, &dev); 789 if (ACPI_FAILURE(status) || dev != device) 790 continue; 791 if (bind) 792 result = 793 thermal_zone_bind_cooling_device 794 (thermal, trip, cdev, 795 THERMAL_NO_LIMIT, THERMAL_NO_LIMIT); 796 else 797 result = 798 thermal_zone_unbind_cooling_device 799 (thermal, trip, cdev); 800 if (result) 801 goto failed; 802 } 803 } 804 805 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { 806 if (!tz->trips.active[i].flags.valid) 807 break; 808 trip++; 809 for (j = 0; 810 j < tz->trips.active[i].devices.count; 811 j++) { 812 handle = tz->trips.active[i].devices.handles[j]; 813 status = acpi_bus_get_device(handle, &dev); 814 if (ACPI_FAILURE(status) || dev != device) 815 continue; 816 if (bind) 817 result = thermal_zone_bind_cooling_device 818 (thermal, trip, cdev, 819 THERMAL_NO_LIMIT, THERMAL_NO_LIMIT); 820 else 821 result = thermal_zone_unbind_cooling_device 822 (thermal, trip, cdev); 823 if (result) 824 goto failed; 825 } 826 } 827 828 for (i = 0; i < tz->devices.count; i++) { 829 handle = tz->devices.handles[i]; 830 status = acpi_bus_get_device(handle, &dev); 831 if (ACPI_SUCCESS(status) && (dev == device)) { 832 if (bind) 833 result = thermal_zone_bind_cooling_device 834 (thermal, THERMAL_TRIPS_NONE, 835 cdev, THERMAL_NO_LIMIT, 836 THERMAL_NO_LIMIT); 837 else 838 result = thermal_zone_unbind_cooling_device 839 (thermal, THERMAL_TRIPS_NONE, 840 cdev); 841 if (result) 842 goto failed; 843 } 844 } 845 846 failed: 847 return result; 848 } 849 850 static int 851 acpi_thermal_bind_cooling_device(struct thermal_zone_device *thermal, 852 struct thermal_cooling_device *cdev) 853 { 854 return acpi_thermal_cooling_device_cb(thermal, cdev, true); 855 } 856 857 static int 858 acpi_thermal_unbind_cooling_device(struct thermal_zone_device *thermal, 859 struct thermal_cooling_device *cdev) 860 { 861 return acpi_thermal_cooling_device_cb(thermal, cdev, false); 862 } 863 864 static struct thermal_zone_device_ops acpi_thermal_zone_ops = { 865 .bind = acpi_thermal_bind_cooling_device, 866 .unbind = acpi_thermal_unbind_cooling_device, 867 .get_temp = thermal_get_temp, 868 .get_mode = thermal_get_mode, 869 .set_mode = thermal_set_mode, 870 .get_trip_type = thermal_get_trip_type, 871 .get_trip_temp = thermal_get_trip_temp, 872 .get_crit_temp = thermal_get_crit_temp, 873 .get_trend = thermal_get_trend, 874 .notify = thermal_notify, 875 }; 876 877 static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz) 878 { 879 int trips = 0; 880 int result; 881 acpi_status status; 882 int i; 883 884 if (tz->trips.critical.flags.valid) 885 trips++; 886 887 if (tz->trips.hot.flags.valid) 888 trips++; 889 890 if (tz->trips.passive.flags.valid) 891 trips++; 892 893 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE && 894 tz->trips.active[i].flags.valid; i++, trips++); 895 896 if (tz->trips.passive.flags.valid) 897 tz->thermal_zone = 898 thermal_zone_device_register("acpitz", trips, 0, tz, 899 &acpi_thermal_zone_ops, NULL, 900 tz->trips.passive.tsp*100, 901 tz->polling_frequency*100); 902 else 903 tz->thermal_zone = 904 thermal_zone_device_register("acpitz", trips, 0, tz, 905 &acpi_thermal_zone_ops, NULL, 906 0, tz->polling_frequency*100); 907 if (IS_ERR(tz->thermal_zone)) 908 return -ENODEV; 909 910 result = sysfs_create_link(&tz->device->dev.kobj, 911 &tz->thermal_zone->device.kobj, "thermal_zone"); 912 if (result) 913 return result; 914 915 result = sysfs_create_link(&tz->thermal_zone->device.kobj, 916 &tz->device->dev.kobj, "device"); 917 if (result) 918 return result; 919 920 status = acpi_attach_data(tz->device->handle, 921 acpi_bus_private_data_handler, 922 tz->thermal_zone); 923 if (ACPI_FAILURE(status)) { 924 pr_err(PREFIX "Error attaching device data\n"); 925 return -ENODEV; 926 } 927 928 tz->tz_enabled = 1; 929 930 dev_info(&tz->device->dev, "registered as thermal_zone%d\n", 931 tz->thermal_zone->id); 932 return 0; 933 } 934 935 static void acpi_thermal_unregister_thermal_zone(struct acpi_thermal *tz) 936 { 937 sysfs_remove_link(&tz->device->dev.kobj, "thermal_zone"); 938 sysfs_remove_link(&tz->thermal_zone->device.kobj, "device"); 939 thermal_zone_device_unregister(tz->thermal_zone); 940 tz->thermal_zone = NULL; 941 acpi_detach_data(tz->device->handle, acpi_bus_private_data_handler); 942 } 943 944 945 /* -------------------------------------------------------------------------- 946 Driver Interface 947 -------------------------------------------------------------------------- */ 948 949 static void acpi_thermal_notify(struct acpi_device *device, u32 event) 950 { 951 struct acpi_thermal *tz = acpi_driver_data(device); 952 953 954 if (!tz) 955 return; 956 957 switch (event) { 958 case ACPI_THERMAL_NOTIFY_TEMPERATURE: 959 acpi_thermal_check(tz); 960 break; 961 case ACPI_THERMAL_NOTIFY_THRESHOLDS: 962 acpi_thermal_trips_update(tz, ACPI_TRIPS_REFRESH_THRESHOLDS); 963 acpi_thermal_check(tz); 964 acpi_bus_generate_netlink_event(device->pnp.device_class, 965 dev_name(&device->dev), event, 0); 966 break; 967 case ACPI_THERMAL_NOTIFY_DEVICES: 968 acpi_thermal_trips_update(tz, ACPI_TRIPS_REFRESH_DEVICES); 969 acpi_thermal_check(tz); 970 acpi_bus_generate_netlink_event(device->pnp.device_class, 971 dev_name(&device->dev), event, 0); 972 break; 973 default: 974 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 975 "Unsupported event [0x%x]\n", event)); 976 break; 977 } 978 } 979 980 /* 981 * On some platforms, the AML code has dependency about 982 * the evaluating order of _TMP and _CRT/_HOT/_PSV/_ACx. 983 * 1. On HP Pavilion G4-1016tx, _TMP must be invoked after 984 * /_CRT/_HOT/_PSV/_ACx, or else system will be power off. 985 * 2. On HP Compaq 6715b/6715s, the return value of _PSV is 0 986 * if _TMP has never been evaluated. 987 * 988 * As this dependency is totally transparent to OS, evaluate 989 * all of them once, in the order of _CRT/_HOT/_PSV/_ACx, 990 * _TMP, before they are actually used. 991 */ 992 static void acpi_thermal_aml_dependency_fix(struct acpi_thermal *tz) 993 { 994 acpi_handle handle = tz->device->handle; 995 unsigned long long value; 996 int i; 997 998 acpi_evaluate_integer(handle, "_CRT", NULL, &value); 999 acpi_evaluate_integer(handle, "_HOT", NULL, &value); 1000 acpi_evaluate_integer(handle, "_PSV", NULL, &value); 1001 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { 1002 char name[5] = { '_', 'A', 'C', ('0' + i), '\0' }; 1003 acpi_status status; 1004 1005 status = acpi_evaluate_integer(handle, name, NULL, &value); 1006 if (status == AE_NOT_FOUND) 1007 break; 1008 } 1009 acpi_evaluate_integer(handle, "_TMP", NULL, &value); 1010 } 1011 1012 static int acpi_thermal_get_info(struct acpi_thermal *tz) 1013 { 1014 int result = 0; 1015 1016 1017 if (!tz) 1018 return -EINVAL; 1019 1020 acpi_thermal_aml_dependency_fix(tz); 1021 1022 /* Get trip points [_CRT, _PSV, etc.] (required) */ 1023 result = acpi_thermal_get_trip_points(tz); 1024 if (result) 1025 return result; 1026 1027 /* Get temperature [_TMP] (required) */ 1028 result = acpi_thermal_get_temperature(tz); 1029 if (result) 1030 return result; 1031 1032 /* Set the cooling mode [_SCP] to active cooling (default) */ 1033 result = acpi_thermal_set_cooling_mode(tz, ACPI_THERMAL_MODE_ACTIVE); 1034 if (!result) 1035 tz->flags.cooling_mode = 1; 1036 1037 /* Get default polling frequency [_TZP] (optional) */ 1038 if (tzp) 1039 tz->polling_frequency = tzp; 1040 else 1041 acpi_thermal_get_polling_frequency(tz); 1042 1043 return 0; 1044 } 1045 1046 /* 1047 * The exact offset between Kelvin and degree Celsius is 273.15. However ACPI 1048 * handles temperature values with a single decimal place. As a consequence, 1049 * some implementations use an offset of 273.1 and others use an offset of 1050 * 273.2. Try to find out which one is being used, to present the most 1051 * accurate and visually appealing number. 1052 * 1053 * The heuristic below should work for all ACPI thermal zones which have a 1054 * critical trip point with a value being a multiple of 0.5 degree Celsius. 1055 */ 1056 static void acpi_thermal_guess_offset(struct acpi_thermal *tz) 1057 { 1058 if (tz->trips.critical.flags.valid && 1059 (tz->trips.critical.temperature % 5) == 1) 1060 tz->kelvin_offset = 2731; 1061 else 1062 tz->kelvin_offset = 2732; 1063 } 1064 1065 static int acpi_thermal_add(struct acpi_device *device) 1066 { 1067 int result = 0; 1068 struct acpi_thermal *tz = NULL; 1069 1070 1071 if (!device) 1072 return -EINVAL; 1073 1074 tz = kzalloc(sizeof(struct acpi_thermal), GFP_KERNEL); 1075 if (!tz) 1076 return -ENOMEM; 1077 1078 tz->device = device; 1079 strcpy(tz->name, device->pnp.bus_id); 1080 strcpy(acpi_device_name(device), ACPI_THERMAL_DEVICE_NAME); 1081 strcpy(acpi_device_class(device), ACPI_THERMAL_CLASS); 1082 device->driver_data = tz; 1083 1084 result = acpi_thermal_get_info(tz); 1085 if (result) 1086 goto free_memory; 1087 1088 acpi_thermal_guess_offset(tz); 1089 1090 result = acpi_thermal_register_thermal_zone(tz); 1091 if (result) 1092 goto free_memory; 1093 1094 pr_info(PREFIX "%s [%s] (%ld C)\n", acpi_device_name(device), 1095 acpi_device_bid(device), KELVIN_TO_CELSIUS(tz->temperature)); 1096 goto end; 1097 1098 free_memory: 1099 kfree(tz); 1100 end: 1101 return result; 1102 } 1103 1104 static int acpi_thermal_remove(struct acpi_device *device) 1105 { 1106 struct acpi_thermal *tz = NULL; 1107 1108 if (!device || !acpi_driver_data(device)) 1109 return -EINVAL; 1110 1111 tz = acpi_driver_data(device); 1112 1113 acpi_thermal_unregister_thermal_zone(tz); 1114 kfree(tz); 1115 return 0; 1116 } 1117 1118 #ifdef CONFIG_PM_SLEEP 1119 static int acpi_thermal_resume(struct device *dev) 1120 { 1121 struct acpi_thermal *tz; 1122 int i, j, power_state, result; 1123 1124 if (!dev) 1125 return -EINVAL; 1126 1127 tz = acpi_driver_data(to_acpi_device(dev)); 1128 if (!tz) 1129 return -EINVAL; 1130 1131 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { 1132 if (!(&tz->trips.active[i])) 1133 break; 1134 if (!tz->trips.active[i].flags.valid) 1135 break; 1136 tz->trips.active[i].flags.enabled = 1; 1137 for (j = 0; j < tz->trips.active[i].devices.count; j++) { 1138 result = acpi_bus_update_power( 1139 tz->trips.active[i].devices.handles[j], 1140 &power_state); 1141 if (result || (power_state != ACPI_STATE_D0)) { 1142 tz->trips.active[i].flags.enabled = 0; 1143 break; 1144 } 1145 } 1146 tz->state.active |= tz->trips.active[i].flags.enabled; 1147 } 1148 1149 acpi_thermal_check(tz); 1150 1151 return AE_OK; 1152 } 1153 #endif 1154 1155 static int thermal_act(const struct dmi_system_id *d) { 1156 1157 if (act == 0) { 1158 pr_notice(PREFIX "%s detected: " 1159 "disabling all active thermal trip points\n", d->ident); 1160 act = -1; 1161 } 1162 return 0; 1163 } 1164 static int thermal_nocrt(const struct dmi_system_id *d) { 1165 1166 pr_notice(PREFIX "%s detected: " 1167 "disabling all critical thermal trip point actions.\n", d->ident); 1168 nocrt = 1; 1169 return 0; 1170 } 1171 static int thermal_tzp(const struct dmi_system_id *d) { 1172 1173 if (tzp == 0) { 1174 pr_notice(PREFIX "%s detected: " 1175 "enabling thermal zone polling\n", d->ident); 1176 tzp = 300; /* 300 dS = 30 Seconds */ 1177 } 1178 return 0; 1179 } 1180 static int thermal_psv(const struct dmi_system_id *d) { 1181 1182 if (psv == 0) { 1183 pr_notice(PREFIX "%s detected: " 1184 "disabling all passive thermal trip points\n", d->ident); 1185 psv = -1; 1186 } 1187 return 0; 1188 } 1189 1190 static struct dmi_system_id thermal_dmi_table[] __initdata = { 1191 /* 1192 * Award BIOS on this AOpen makes thermal control almost worthless. 1193 * http://bugzilla.kernel.org/show_bug.cgi?id=8842 1194 */ 1195 { 1196 .callback = thermal_act, 1197 .ident = "AOpen i915GMm-HFS", 1198 .matches = { 1199 DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"), 1200 DMI_MATCH(DMI_BOARD_NAME, "i915GMm-HFS"), 1201 }, 1202 }, 1203 { 1204 .callback = thermal_psv, 1205 .ident = "AOpen i915GMm-HFS", 1206 .matches = { 1207 DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"), 1208 DMI_MATCH(DMI_BOARD_NAME, "i915GMm-HFS"), 1209 }, 1210 }, 1211 { 1212 .callback = thermal_tzp, 1213 .ident = "AOpen i915GMm-HFS", 1214 .matches = { 1215 DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"), 1216 DMI_MATCH(DMI_BOARD_NAME, "i915GMm-HFS"), 1217 }, 1218 }, 1219 { 1220 .callback = thermal_nocrt, 1221 .ident = "Gigabyte GA-7ZX", 1222 .matches = { 1223 DMI_MATCH(DMI_BOARD_VENDOR, "Gigabyte Technology Co., Ltd."), 1224 DMI_MATCH(DMI_BOARD_NAME, "7ZX"), 1225 }, 1226 }, 1227 {} 1228 }; 1229 1230 static int __init acpi_thermal_init(void) 1231 { 1232 int result = 0; 1233 1234 dmi_check_system(thermal_dmi_table); 1235 1236 if (off) { 1237 pr_notice(PREFIX "thermal control disabled\n"); 1238 return -ENODEV; 1239 } 1240 1241 result = acpi_bus_register_driver(&acpi_thermal_driver); 1242 if (result < 0) 1243 return -ENODEV; 1244 1245 return 0; 1246 } 1247 1248 static void __exit acpi_thermal_exit(void) 1249 { 1250 1251 acpi_bus_unregister_driver(&acpi_thermal_driver); 1252 1253 return; 1254 } 1255 1256 module_init(acpi_thermal_init); 1257 module_exit(acpi_thermal_exit); 1258