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