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