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