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 #define pr_fmt(fmt) "ACPI: thermal: " fmt 17 18 #include <linux/kernel.h> 19 #include <linux/module.h> 20 #include <linux/dmi.h> 21 #include <linux/init.h> 22 #include <linux/slab.h> 23 #include <linux/types.h> 24 #include <linux/jiffies.h> 25 #include <linux/kmod.h> 26 #include <linux/reboot.h> 27 #include <linux/device.h> 28 #include <linux/platform_device.h> 29 #include <linux/thermal.h> 30 #include <linux/acpi.h> 31 #include <linux/workqueue.h> 32 #include <linux/uaccess.h> 33 #include <linux/units.h> 34 35 #include "internal.h" 36 37 #define ACPI_THERMAL_CLASS "thermal_zone" 38 #define ACPI_THERMAL_NOTIFY_TEMPERATURE 0x80 39 #define ACPI_THERMAL_NOTIFY_THRESHOLDS 0x81 40 #define ACPI_THERMAL_NOTIFY_DEVICES 0x82 41 #define ACPI_THERMAL_NOTIFY_CRITICAL 0xF0 42 #define ACPI_THERMAL_NOTIFY_HOT 0xF1 43 #define ACPI_THERMAL_MODE_ACTIVE 0x00 44 45 #define ACPI_THERMAL_MAX_ACTIVE 10 46 #define ACPI_THERMAL_MAX_LIMIT_STR_LEN 65 47 48 #define ACPI_THERMAL_TRIP_PASSIVE (-1) 49 50 #define ACPI_THERMAL_MAX_NR_TRIPS (ACPI_THERMAL_MAX_ACTIVE + 3) 51 52 /* 53 * This exception is thrown out in two cases: 54 * 1.An invalid trip point becomes invalid or a valid trip point becomes invalid 55 * when re-evaluating the AML code. 56 * 2.TODO: Devices listed in _PSL, _ALx, _TZD may change. 57 * We need to re-bind the cooling devices of a thermal zone when this occurs. 58 */ 59 #define ACPI_THERMAL_TRIPS_EXCEPTION(tz, str) \ 60 do { \ 61 acpi_handle_info(tz->device->handle, \ 62 "ACPI thermal trip point %s changed\n" \ 63 "Please report to linux-acpi@vger.kernel.org\n", str); \ 64 } while (0) 65 66 static int act; 67 module_param(act, int, 0644); 68 MODULE_PARM_DESC(act, "Disable or override all lowest active trip points."); 69 70 static int crt; 71 module_param(crt, int, 0644); 72 MODULE_PARM_DESC(crt, "Disable or lower all critical trip points."); 73 74 static int tzp; 75 module_param(tzp, int, 0444); 76 MODULE_PARM_DESC(tzp, "Thermal zone polling frequency, in 1/10 seconds."); 77 78 static int off; 79 module_param(off, int, 0); 80 MODULE_PARM_DESC(off, "Set to disable ACPI thermal support."); 81 82 static int psv; 83 module_param(psv, int, 0644); 84 MODULE_PARM_DESC(psv, "Disable or override all passive trip points."); 85 86 static struct workqueue_struct *acpi_thermal_pm_queue; 87 88 struct acpi_thermal_trip { 89 unsigned long temp_dk; 90 struct acpi_handle_list devices; 91 }; 92 93 struct acpi_thermal_passive { 94 struct acpi_thermal_trip trip; 95 unsigned long tc1; 96 unsigned long tc2; 97 unsigned long delay; 98 }; 99 100 struct acpi_thermal_active { 101 struct acpi_thermal_trip trip; 102 }; 103 104 struct acpi_thermal_trips { 105 struct acpi_thermal_passive passive; 106 struct acpi_thermal_active active[ACPI_THERMAL_MAX_ACTIVE]; 107 }; 108 109 struct acpi_thermal { 110 struct acpi_device *device; 111 acpi_bus_id name; 112 unsigned long temp_dk; 113 unsigned long last_temp_dk; 114 unsigned long polling_frequency; 115 volatile u8 zombie; 116 struct acpi_thermal_trips trips; 117 struct thermal_zone_device *thermal_zone; 118 int kelvin_offset; /* in millidegrees */ 119 struct work_struct thermal_check_work; 120 struct mutex thermal_check_lock; 121 refcount_t thermal_check_count; 122 }; 123 124 /* -------------------------------------------------------------------------- 125 Thermal Zone Management 126 -------------------------------------------------------------------------- */ 127 128 static int acpi_thermal_get_temperature(struct acpi_thermal *tz) 129 { 130 acpi_status status = AE_OK; 131 unsigned long long tmp; 132 133 if (!tz) 134 return -EINVAL; 135 136 tz->last_temp_dk = tz->temp_dk; 137 138 status = acpi_evaluate_integer(tz->device->handle, "_TMP", NULL, &tmp); 139 if (ACPI_FAILURE(status)) 140 return -ENODEV; 141 142 tz->temp_dk = tmp; 143 144 acpi_handle_debug(tz->device->handle, "Temperature is %lu dK\n", 145 tz->temp_dk); 146 147 return 0; 148 } 149 150 static int acpi_thermal_get_polling_frequency(struct acpi_thermal *tz) 151 { 152 acpi_status status = AE_OK; 153 unsigned long long tmp; 154 155 if (!tz) 156 return -EINVAL; 157 158 status = acpi_evaluate_integer(tz->device->handle, "_TZP", NULL, &tmp); 159 if (ACPI_FAILURE(status)) 160 return -ENODEV; 161 162 tz->polling_frequency = tmp; 163 acpi_handle_debug(tz->device->handle, "Polling frequency is %lu dS\n", 164 tz->polling_frequency); 165 166 return 0; 167 } 168 169 static int acpi_thermal_temp(struct acpi_thermal *tz, int temp_deci_k) 170 { 171 int temp; 172 173 if (temp_deci_k == THERMAL_TEMP_INVALID) 174 return THERMAL_TEMP_INVALID; 175 176 temp = deci_kelvin_to_millicelsius_with_offset(temp_deci_k, 177 tz->kelvin_offset); 178 if (temp <= 0) 179 return THERMAL_TEMP_INVALID; 180 181 return temp; 182 } 183 184 static bool acpi_thermal_trip_valid(struct acpi_thermal_trip *acpi_trip) 185 { 186 return acpi_trip->temp_dk != THERMAL_TEMP_INVALID; 187 } 188 189 static int active_trip_index(struct acpi_thermal *tz, 190 struct acpi_thermal_trip *acpi_trip) 191 { 192 struct acpi_thermal_active *active; 193 194 active = container_of(acpi_trip, struct acpi_thermal_active, trip); 195 return active - tz->trips.active; 196 } 197 198 static long get_passive_temp(struct acpi_thermal *tz) 199 { 200 int temp; 201 202 if (acpi_passive_trip_temp(tz->device, &temp)) 203 return THERMAL_TEMP_INVALID; 204 205 return temp; 206 } 207 208 static long get_active_temp(struct acpi_thermal *tz, int index) 209 { 210 int temp; 211 212 if (acpi_active_trip_temp(tz->device, index, &temp)) 213 return THERMAL_TEMP_INVALID; 214 215 /* 216 * If an override has been provided, apply it so there are no active 217 * trips with thresholds greater than the override. 218 */ 219 if (act > 0) { 220 unsigned long long override = celsius_to_deci_kelvin(act); 221 222 if (temp > override) 223 return override; 224 } 225 return temp; 226 } 227 228 static void acpi_thermal_update_trip(struct acpi_thermal *tz, 229 const struct thermal_trip *trip) 230 { 231 struct acpi_thermal_trip *acpi_trip = trip->priv; 232 233 if (trip->type == THERMAL_TRIP_PASSIVE) { 234 if (psv > 0) 235 return; 236 237 acpi_trip->temp_dk = get_passive_temp(tz); 238 } else { 239 int index = active_trip_index(tz, acpi_trip); 240 241 acpi_trip->temp_dk = get_active_temp(tz, index); 242 } 243 244 if (!acpi_thermal_trip_valid(acpi_trip)) 245 ACPI_THERMAL_TRIPS_EXCEPTION(tz, "state"); 246 } 247 248 static bool update_trip_devices(struct acpi_thermal *tz, 249 struct acpi_thermal_trip *acpi_trip, 250 int index, bool compare) 251 { 252 struct acpi_handle_list devices = { 0 }; 253 char method[] = "_PSL"; 254 255 if (index != ACPI_THERMAL_TRIP_PASSIVE) { 256 method[1] = 'A'; 257 method[2] = 'L'; 258 method[3] = '0' + index; 259 } 260 261 if (!acpi_evaluate_reference(tz->device->handle, method, NULL, &devices)) { 262 acpi_handle_info(tz->device->handle, "%s evaluation failure\n", method); 263 return false; 264 } 265 266 if (acpi_handle_list_equal(&acpi_trip->devices, &devices)) { 267 acpi_handle_list_free(&devices); 268 return true; 269 } 270 271 if (compare) 272 ACPI_THERMAL_TRIPS_EXCEPTION(tz, "device"); 273 274 acpi_handle_list_replace(&acpi_trip->devices, &devices); 275 return true; 276 } 277 278 static void acpi_thermal_update_trip_devices(struct acpi_thermal *tz, 279 const struct thermal_trip *trip) 280 { 281 struct acpi_thermal_trip *acpi_trip = trip->priv; 282 int index = trip->type == THERMAL_TRIP_PASSIVE ? 283 ACPI_THERMAL_TRIP_PASSIVE : active_trip_index(tz, acpi_trip); 284 285 if (update_trip_devices(tz, acpi_trip, index, true)) 286 return; 287 288 acpi_trip->temp_dk = THERMAL_TEMP_INVALID; 289 ACPI_THERMAL_TRIPS_EXCEPTION(tz, "state"); 290 } 291 292 struct adjust_trip_data { 293 struct acpi_thermal *tz; 294 u32 event; 295 }; 296 297 static int acpi_thermal_adjust_trip(struct thermal_trip *trip, void *data) 298 { 299 struct acpi_thermal_trip *acpi_trip = trip->priv; 300 struct adjust_trip_data *atd = data; 301 struct acpi_thermal *tz = atd->tz; 302 int temp; 303 304 if (!acpi_trip || !acpi_thermal_trip_valid(acpi_trip)) 305 return 0; 306 307 if (atd->event == ACPI_THERMAL_NOTIFY_THRESHOLDS) 308 acpi_thermal_update_trip(tz, trip); 309 else 310 acpi_thermal_update_trip_devices(tz, trip); 311 312 if (acpi_thermal_trip_valid(acpi_trip)) 313 temp = acpi_thermal_temp(tz, acpi_trip->temp_dk); 314 else 315 temp = THERMAL_TEMP_INVALID; 316 317 thermal_zone_set_trip_temp(tz->thermal_zone, trip, temp); 318 319 return 0; 320 } 321 322 static void acpi_queue_thermal_check(struct acpi_thermal *tz) 323 { 324 if (!work_pending(&tz->thermal_check_work)) 325 queue_work(acpi_thermal_pm_queue, &tz->thermal_check_work); 326 } 327 328 static void acpi_thermal_trips_update(struct acpi_thermal *tz, u32 event) 329 { 330 struct adjust_trip_data atd = { .tz = tz, .event = event }; 331 struct acpi_device *adev = tz->device; 332 333 /* 334 * Use thermal_zone_for_each_trip() to carry out the trip points 335 * update, so as to protect thermal_get_trend() from getting stale 336 * trip point temperatures and to prevent thermal_zone_device_update() 337 * invoked from acpi_thermal_check_fn() from producing inconsistent 338 * results. 339 */ 340 thermal_zone_for_each_trip(tz->thermal_zone, 341 acpi_thermal_adjust_trip, &atd); 342 acpi_queue_thermal_check(tz); 343 acpi_bus_generate_netlink_event(ACPI_THERMAL_CLASS, 344 dev_name(&adev->dev), event, 0); 345 } 346 347 static int acpi_thermal_get_critical_trip(struct acpi_thermal *tz) 348 { 349 int temp; 350 351 if (crt > 0) { 352 temp = celsius_to_deci_kelvin(crt); 353 goto set; 354 } 355 if (crt == -1) { 356 acpi_handle_debug(tz->device->handle, "Critical threshold disabled\n"); 357 return THERMAL_TEMP_INVALID; 358 } 359 360 if (acpi_critical_trip_temp(tz->device, &temp)) 361 return THERMAL_TEMP_INVALID; 362 363 if (temp <= 2732) { 364 /* 365 * Below zero (Celsius) values clearly aren't right for sure, 366 * so discard them as invalid. 367 */ 368 pr_info(FW_BUG "Invalid critical threshold (%d)\n", temp); 369 return THERMAL_TEMP_INVALID; 370 } 371 372 set: 373 acpi_handle_debug(tz->device->handle, "Critical threshold [%d]\n", temp); 374 return temp; 375 } 376 377 static int acpi_thermal_get_hot_trip(struct acpi_thermal *tz) 378 { 379 int temp; 380 381 if (acpi_hot_trip_temp(tz->device, &temp) || temp == THERMAL_TEMP_INVALID) { 382 acpi_handle_debug(tz->device->handle, "No hot threshold\n"); 383 return THERMAL_TEMP_INVALID; 384 } 385 386 acpi_handle_debug(tz->device->handle, "Hot threshold [%d]\n", temp); 387 return temp; 388 } 389 390 static bool passive_trip_params_init(struct acpi_thermal *tz) 391 { 392 unsigned long long tmp; 393 acpi_status status; 394 395 status = acpi_evaluate_integer(tz->device->handle, "_TC1", NULL, &tmp); 396 if (ACPI_FAILURE(status)) 397 return false; 398 399 tz->trips.passive.tc1 = tmp; 400 401 status = acpi_evaluate_integer(tz->device->handle, "_TC2", NULL, &tmp); 402 if (ACPI_FAILURE(status)) 403 return false; 404 405 tz->trips.passive.tc2 = tmp; 406 407 status = acpi_evaluate_integer(tz->device->handle, "_TFP", NULL, &tmp); 408 if (ACPI_SUCCESS(status)) { 409 tz->trips.passive.delay = tmp; 410 return true; 411 } 412 413 status = acpi_evaluate_integer(tz->device->handle, "_TSP", NULL, &tmp); 414 if (ACPI_FAILURE(status)) 415 return false; 416 417 tz->trips.passive.delay = tmp * 100; 418 419 return true; 420 } 421 422 static bool acpi_thermal_init_trip(struct acpi_thermal *tz, int index) 423 { 424 struct acpi_thermal_trip *acpi_trip; 425 long temp; 426 427 if (index == ACPI_THERMAL_TRIP_PASSIVE) { 428 acpi_trip = &tz->trips.passive.trip; 429 430 if (psv == -1) 431 goto fail; 432 433 if (!passive_trip_params_init(tz)) 434 goto fail; 435 436 temp = psv > 0 ? celsius_to_deci_kelvin(psv) : 437 get_passive_temp(tz); 438 } else { 439 acpi_trip = &tz->trips.active[index].trip; 440 441 if (act == -1) 442 goto fail; 443 444 temp = get_active_temp(tz, index); 445 } 446 447 if (temp == THERMAL_TEMP_INVALID) 448 goto fail; 449 450 if (!update_trip_devices(tz, acpi_trip, index, false)) 451 goto fail; 452 453 acpi_trip->temp_dk = temp; 454 return true; 455 456 fail: 457 acpi_trip->temp_dk = THERMAL_TEMP_INVALID; 458 return false; 459 } 460 461 static void acpi_thermal_get_trip_points(struct acpi_thermal *tz) 462 { 463 int i; 464 465 acpi_thermal_init_trip(tz, ACPI_THERMAL_TRIP_PASSIVE); 466 467 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { 468 if (!acpi_thermal_init_trip(tz, i)) 469 break; 470 } 471 472 while (++i < ACPI_THERMAL_MAX_ACTIVE) 473 tz->trips.active[i].trip.temp_dk = THERMAL_TEMP_INVALID; 474 } 475 476 /* sys I/F for generic thermal sysfs support */ 477 478 static int thermal_get_temp(struct thermal_zone_device *thermal, int *temp) 479 { 480 struct acpi_thermal *tz = thermal_zone_device_priv(thermal); 481 int result; 482 483 if (!tz) 484 return -EINVAL; 485 486 result = acpi_thermal_get_temperature(tz); 487 if (result) 488 return result; 489 490 *temp = deci_kelvin_to_millicelsius_with_offset(tz->temp_dk, 491 tz->kelvin_offset); 492 return 0; 493 } 494 495 static int thermal_get_trend(struct thermal_zone_device *thermal, 496 const struct thermal_trip *trip, 497 enum thermal_trend *trend) 498 { 499 struct acpi_thermal *tz = thermal_zone_device_priv(thermal); 500 struct acpi_thermal_trip *acpi_trip; 501 int t; 502 503 if (!tz || !trip) 504 return -EINVAL; 505 506 acpi_trip = trip->priv; 507 if (!acpi_trip || !acpi_thermal_trip_valid(acpi_trip)) 508 return -EINVAL; 509 510 switch (trip->type) { 511 case THERMAL_TRIP_PASSIVE: 512 t = tz->trips.passive.tc1 * (tz->temp_dk - 513 tz->last_temp_dk) + 514 tz->trips.passive.tc2 * (tz->temp_dk - 515 acpi_trip->temp_dk); 516 if (t > 0) 517 *trend = THERMAL_TREND_RAISING; 518 else if (t < 0) 519 *trend = THERMAL_TREND_DROPPING; 520 else 521 *trend = THERMAL_TREND_STABLE; 522 523 return 0; 524 525 case THERMAL_TRIP_ACTIVE: 526 t = acpi_thermal_temp(tz, tz->temp_dk); 527 if (t <= trip->temperature) 528 break; 529 530 *trend = THERMAL_TREND_RAISING; 531 532 return 0; 533 534 default: 535 break; 536 } 537 538 return -EINVAL; 539 } 540 541 static void acpi_thermal_zone_device_hot(struct thermal_zone_device *thermal) 542 { 543 struct acpi_thermal *tz = thermal_zone_device_priv(thermal); 544 545 acpi_bus_generate_netlink_event(ACPI_THERMAL_CLASS, 546 dev_name(&tz->device->dev), 547 ACPI_THERMAL_NOTIFY_HOT, 1); 548 } 549 550 static void acpi_thermal_zone_device_critical(struct thermal_zone_device *thermal) 551 { 552 struct acpi_thermal *tz = thermal_zone_device_priv(thermal); 553 554 acpi_bus_generate_netlink_event(ACPI_THERMAL_CLASS, 555 dev_name(&tz->device->dev), 556 ACPI_THERMAL_NOTIFY_CRITICAL, 1); 557 558 thermal_zone_device_critical(thermal); 559 } 560 561 static bool acpi_thermal_should_bind_cdev(struct thermal_zone_device *thermal, 562 const struct thermal_trip *trip, 563 struct thermal_cooling_device *cdev, 564 struct cooling_spec *c) 565 { 566 struct acpi_thermal_trip *acpi_trip = trip->priv; 567 struct acpi_device *cdev_adev = cdev->devdata; 568 int i; 569 570 /* Skip critical and hot trips. */ 571 if (!acpi_trip) 572 return false; 573 574 for (i = 0; i < acpi_trip->devices.count; i++) { 575 acpi_handle handle = acpi_trip->devices.handles[i]; 576 577 if (acpi_fetch_acpi_dev(handle) == cdev_adev) 578 return true; 579 } 580 581 return false; 582 } 583 584 static const struct thermal_zone_device_ops acpi_thermal_zone_ops = { 585 .should_bind = acpi_thermal_should_bind_cdev, 586 .get_temp = thermal_get_temp, 587 .get_trend = thermal_get_trend, 588 .hot = acpi_thermal_zone_device_hot, 589 .critical = acpi_thermal_zone_device_critical, 590 }; 591 592 static int acpi_thermal_zone_sysfs_add(struct acpi_thermal *tz) 593 { 594 struct device *tzdev = thermal_zone_device(tz->thermal_zone); 595 int ret; 596 597 ret = sysfs_create_link(&tz->device->dev.kobj, 598 &tzdev->kobj, "thermal_zone"); 599 if (ret) 600 return ret; 601 602 ret = sysfs_create_link(&tzdev->kobj, 603 &tz->device->dev.kobj, "device"); 604 if (ret) 605 sysfs_remove_link(&tz->device->dev.kobj, "thermal_zone"); 606 607 return ret; 608 } 609 610 static void acpi_thermal_zone_sysfs_remove(struct acpi_thermal *tz) 611 { 612 struct device *tzdev = thermal_zone_device(tz->thermal_zone); 613 614 sysfs_remove_link(&tz->device->dev.kobj, "thermal_zone"); 615 sysfs_remove_link(&tzdev->kobj, "device"); 616 } 617 618 static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz, 619 const struct thermal_trip *trip_table, 620 unsigned int trip_count, 621 int passive_delay) 622 { 623 int result; 624 625 if (trip_count) 626 tz->thermal_zone = thermal_zone_device_register_with_trips( 627 "acpitz", trip_table, trip_count, tz, 628 &acpi_thermal_zone_ops, NULL, passive_delay, 629 tz->polling_frequency * 100); 630 else 631 tz->thermal_zone = thermal_tripless_zone_device_register( 632 "acpitz", tz, &acpi_thermal_zone_ops, NULL); 633 634 if (IS_ERR(tz->thermal_zone)) 635 return PTR_ERR(tz->thermal_zone); 636 637 result = acpi_thermal_zone_sysfs_add(tz); 638 if (result) 639 goto unregister_tzd; 640 641 result = thermal_zone_device_enable(tz->thermal_zone); 642 if (result) 643 goto remove_links; 644 645 dev_info(&tz->device->dev, "registered as thermal_zone%d\n", 646 thermal_zone_device_id(tz->thermal_zone)); 647 648 return 0; 649 650 remove_links: 651 acpi_thermal_zone_sysfs_remove(tz); 652 unregister_tzd: 653 thermal_zone_device_unregister(tz->thermal_zone); 654 655 return result; 656 } 657 658 static void acpi_thermal_zone_unregister(void *data) 659 { 660 struct acpi_thermal *tz = data; 661 662 flush_workqueue(acpi_thermal_pm_queue); 663 664 thermal_zone_device_disable(tz->thermal_zone); 665 acpi_thermal_zone_sysfs_remove(tz); 666 thermal_zone_device_unregister(tz->thermal_zone); 667 tz->thermal_zone = NULL; 668 } 669 670 671 /* -------------------------------------------------------------------------- 672 Driver Interface 673 -------------------------------------------------------------------------- */ 674 675 static void acpi_thermal_notify(acpi_handle handle, u32 event, void *data) 676 { 677 struct acpi_thermal *tz = data; 678 679 if (!tz) 680 return; 681 682 switch (event) { 683 case ACPI_THERMAL_NOTIFY_TEMPERATURE: 684 acpi_queue_thermal_check(tz); 685 break; 686 case ACPI_THERMAL_NOTIFY_THRESHOLDS: 687 case ACPI_THERMAL_NOTIFY_DEVICES: 688 acpi_thermal_trips_update(tz, event); 689 break; 690 default: 691 acpi_handle_debug(tz->device->handle, 692 "Unsupported event [0x%x]\n", event); 693 break; 694 } 695 } 696 697 /* 698 * On some platforms, the AML code has dependency about 699 * the evaluating order of _TMP and _CRT/_HOT/_PSV/_ACx. 700 * 1. On HP Pavilion G4-1016tx, _TMP must be invoked after 701 * /_CRT/_HOT/_PSV/_ACx, or else system will be power off. 702 * 2. On HP Compaq 6715b/6715s, the return value of _PSV is 0 703 * if _TMP has never been evaluated. 704 * 705 * As this dependency is totally transparent to OS, evaluate 706 * all of them once, in the order of _CRT/_HOT/_PSV/_ACx, 707 * _TMP, before they are actually used. 708 */ 709 static void acpi_thermal_aml_dependency_fix(struct acpi_thermal *tz) 710 { 711 acpi_handle handle = tz->device->handle; 712 unsigned long long value; 713 int i; 714 715 acpi_evaluate_integer(handle, "_CRT", NULL, &value); 716 acpi_evaluate_integer(handle, "_HOT", NULL, &value); 717 acpi_evaluate_integer(handle, "_PSV", NULL, &value); 718 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { 719 char name[5] = { '_', 'A', 'C', ('0' + i), '\0' }; 720 acpi_status status; 721 722 status = acpi_evaluate_integer(handle, name, NULL, &value); 723 if (status == AE_NOT_FOUND) 724 break; 725 } 726 acpi_evaluate_integer(handle, "_TMP", NULL, &value); 727 } 728 729 /* 730 * The exact offset between Kelvin and degree Celsius is 273.15. However ACPI 731 * handles temperature values with a single decimal place. As a consequence, 732 * some implementations use an offset of 273.1 and others use an offset of 733 * 273.2. Try to find out which one is being used, to present the most 734 * accurate and visually appealing number. 735 * 736 * The heuristic below should work for all ACPI thermal zones which have a 737 * critical trip point with a value being a multiple of 0.5 degree Celsius. 738 */ 739 static void acpi_thermal_guess_offset(struct acpi_thermal *tz, long crit_temp) 740 { 741 if (crit_temp != THERMAL_TEMP_INVALID && crit_temp % 5 == 1) 742 tz->kelvin_offset = 273100; 743 else 744 tz->kelvin_offset = 273200; 745 } 746 747 static void acpi_thermal_check_fn(struct work_struct *work) 748 { 749 struct acpi_thermal *tz = container_of(work, struct acpi_thermal, 750 thermal_check_work); 751 752 /* 753 * In general, it is not sufficient to check the pending bit, because 754 * subsequent instances of this function may be queued after one of them 755 * has started running (e.g. if _TMP sleeps). Avoid bailing out if just 756 * one of them is running, though, because it may have done the actual 757 * check some time ago, so allow at least one of them to block on the 758 * mutex while another one is running the update. 759 */ 760 if (!refcount_dec_not_one(&tz->thermal_check_count)) 761 return; 762 763 mutex_lock(&tz->thermal_check_lock); 764 765 thermal_zone_device_update(tz->thermal_zone, THERMAL_EVENT_UNSPECIFIED); 766 767 refcount_inc(&tz->thermal_check_count); 768 769 mutex_unlock(&tz->thermal_check_lock); 770 } 771 772 static void acpi_thermal_zone_free(void *data) 773 { 774 struct acpi_thermal *tz = data; 775 int i; 776 777 acpi_handle_list_free(&tz->trips.passive.trip.devices); 778 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) 779 acpi_handle_list_free(&tz->trips.active[i].trip.devices); 780 781 kfree(tz); 782 } 783 784 static int acpi_thermal_probe(struct platform_device *pdev) 785 { 786 struct thermal_trip trip_table[ACPI_THERMAL_MAX_NR_TRIPS] = { 0 }; 787 struct device *dev = &pdev->dev; 788 struct acpi_device *device = ACPI_COMPANION(dev); 789 struct acpi_thermal_trip *acpi_trip; 790 struct thermal_trip *trip; 791 struct acpi_thermal *tz; 792 int crit_temp, hot_temp; 793 int passive_delay = 0; 794 int result; 795 int i; 796 797 if (!device) 798 return -ENODEV; 799 800 tz = kzalloc_obj(struct acpi_thermal); 801 if (!tz) 802 return -ENOMEM; 803 804 result = devm_add_action_or_reset(dev, acpi_thermal_zone_free, tz); 805 if (result) 806 return result; 807 808 platform_set_drvdata(pdev, tz); 809 810 tz->device = device; 811 strscpy(tz->name, device->pnp.bus_id); 812 813 acpi_thermal_aml_dependency_fix(tz); 814 815 /* 816 * Set the cooling mode [_SCP] to active cooling. This needs to happen before 817 * we retrieve the trip point values. 818 */ 819 acpi_execute_simple_method(tz->device->handle, "_SCP", ACPI_THERMAL_MODE_ACTIVE); 820 821 /* Get trip points [_ACi, _PSV, etc.] (required). */ 822 acpi_thermal_get_trip_points(tz); 823 824 crit_temp = acpi_thermal_get_critical_trip(tz); 825 hot_temp = acpi_thermal_get_hot_trip(tz); 826 827 /* Get temperature [_TMP] (required). */ 828 result = acpi_thermal_get_temperature(tz); 829 if (result) 830 return result; 831 832 /* Determine the default polling frequency [_TZP]. */ 833 if (tzp) 834 tz->polling_frequency = tzp; 835 else 836 acpi_thermal_get_polling_frequency(tz); 837 838 acpi_thermal_guess_offset(tz, crit_temp); 839 840 trip = trip_table; 841 842 if (crit_temp != THERMAL_TEMP_INVALID) { 843 trip->type = THERMAL_TRIP_CRITICAL; 844 trip->temperature = acpi_thermal_temp(tz, crit_temp); 845 trip++; 846 } 847 848 if (hot_temp != THERMAL_TEMP_INVALID) { 849 trip->type = THERMAL_TRIP_HOT; 850 trip->temperature = acpi_thermal_temp(tz, hot_temp); 851 trip++; 852 } 853 854 acpi_trip = &tz->trips.passive.trip; 855 if (acpi_thermal_trip_valid(acpi_trip)) { 856 passive_delay = tz->trips.passive.delay; 857 858 trip->type = THERMAL_TRIP_PASSIVE; 859 trip->temperature = acpi_thermal_temp(tz, acpi_trip->temp_dk); 860 trip->priv = acpi_trip; 861 trip++; 862 } 863 864 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { 865 acpi_trip = &tz->trips.active[i].trip; 866 867 if (!acpi_thermal_trip_valid(acpi_trip)) 868 break; 869 870 trip->type = THERMAL_TRIP_ACTIVE; 871 trip->temperature = acpi_thermal_temp(tz, acpi_trip->temp_dk); 872 trip->priv = acpi_trip; 873 trip++; 874 } 875 876 if (trip == trip_table) 877 pr_warn(FW_BUG "No valid trip points!\n"); 878 879 result = acpi_thermal_register_thermal_zone(tz, trip_table, 880 trip - trip_table, 881 passive_delay); 882 if (result) 883 return result; 884 885 result = devm_add_action_or_reset(dev, acpi_thermal_zone_unregister, tz); 886 if (result) 887 return result; 888 889 refcount_set(&tz->thermal_check_count, 3); 890 mutex_init(&tz->thermal_check_lock); 891 INIT_WORK(&tz->thermal_check_work, acpi_thermal_check_fn); 892 893 pr_info("Thermal Zone [%s] (%ld C)\n", acpi_device_bid(device), 894 deci_kelvin_to_celsius(tz->temp_dk)); 895 896 return devm_acpi_install_notify_handler(dev, ACPI_DEVICE_NOTIFY, 897 acpi_thermal_notify, tz); 898 } 899 900 #ifdef CONFIG_PM_SLEEP 901 static int acpi_thermal_prepare(struct device *dev) 902 { 903 /* Make sure the previously queued thermal check work has been done */ 904 flush_workqueue(acpi_thermal_pm_queue); 905 return 0; 906 } 907 908 static void acpi_thermal_complete(struct device *dev) 909 { 910 acpi_queue_thermal_check(dev_get_drvdata(dev)); 911 } 912 913 static const struct dev_pm_ops acpi_thermal_pm_ops = { 914 .prepare = acpi_thermal_prepare, 915 .complete = acpi_thermal_complete, 916 }; 917 #define ACPI_THERMAL_PM &acpi_thermal_pm_ops 918 #else /* !CONFIG_PM_SLEEP */ 919 #define ACPI_THERMAL_PM NULL 920 #endif /* CONFIG_PM_SLEEP */ 921 922 static const struct acpi_device_id thermal_device_ids[] = { 923 {ACPI_THERMAL_HID, 0}, 924 {"", 0}, 925 }; 926 MODULE_DEVICE_TABLE(acpi, thermal_device_ids); 927 928 static struct platform_driver acpi_thermal_driver = { 929 .probe = acpi_thermal_probe, 930 .driver = { 931 .name = "acpi-thermal", 932 .acpi_match_table = thermal_device_ids, 933 .pm = ACPI_THERMAL_PM, 934 }, 935 }; 936 937 static int thermal_act(const struct dmi_system_id *d) 938 { 939 if (act == 0) { 940 pr_notice("%s detected: disabling all active thermal trip points\n", 941 d->ident); 942 act = -1; 943 } 944 return 0; 945 } 946 947 static int thermal_nocrt(const struct dmi_system_id *d) 948 { 949 pr_notice("%s detected: disabling all critical thermal trip point actions.\n", 950 d->ident); 951 crt = -1; 952 return 0; 953 } 954 955 static int thermal_tzp(const struct dmi_system_id *d) 956 { 957 if (tzp == 0) { 958 pr_notice("%s detected: enabling thermal zone polling\n", 959 d->ident); 960 tzp = 300; /* 300 dS = 30 Seconds */ 961 } 962 return 0; 963 } 964 965 static int thermal_psv(const struct dmi_system_id *d) 966 { 967 if (psv == 0) { 968 pr_notice("%s detected: disabling all passive thermal trip points\n", 969 d->ident); 970 psv = -1; 971 } 972 return 0; 973 } 974 975 static const struct dmi_system_id thermal_dmi_table[] __initconst = { 976 /* 977 * Award BIOS on this AOpen makes thermal control almost worthless. 978 * http://bugzilla.kernel.org/show_bug.cgi?id=8842 979 */ 980 { 981 .callback = thermal_act, 982 .ident = "AOpen i915GMm-HFS", 983 .matches = { 984 DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"), 985 DMI_MATCH(DMI_BOARD_NAME, "i915GMm-HFS"), 986 }, 987 }, 988 { 989 .callback = thermal_psv, 990 .ident = "AOpen i915GMm-HFS", 991 .matches = { 992 DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"), 993 DMI_MATCH(DMI_BOARD_NAME, "i915GMm-HFS"), 994 }, 995 }, 996 { 997 .callback = thermal_tzp, 998 .ident = "AOpen i915GMm-HFS", 999 .matches = { 1000 DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"), 1001 DMI_MATCH(DMI_BOARD_NAME, "i915GMm-HFS"), 1002 }, 1003 }, 1004 { 1005 .callback = thermal_nocrt, 1006 .ident = "Gigabyte GA-7ZX", 1007 .matches = { 1008 DMI_MATCH(DMI_BOARD_VENDOR, "Gigabyte Technology Co., Ltd."), 1009 DMI_MATCH(DMI_BOARD_NAME, "7ZX"), 1010 }, 1011 }, 1012 {} 1013 }; 1014 1015 static int __init acpi_thermal_init(void) 1016 { 1017 int result; 1018 1019 dmi_check_system(thermal_dmi_table); 1020 1021 if (off) { 1022 pr_notice("thermal control disabled\n"); 1023 return -ENODEV; 1024 } 1025 1026 acpi_thermal_pm_queue = alloc_workqueue("acpi_thermal_pm", 1027 WQ_HIGHPRI | WQ_MEM_RECLAIM | WQ_PERCPU, 1028 0); 1029 if (!acpi_thermal_pm_queue) 1030 return -ENODEV; 1031 1032 result = platform_driver_register(&acpi_thermal_driver); 1033 if (result < 0) { 1034 destroy_workqueue(acpi_thermal_pm_queue); 1035 return -ENODEV; 1036 } 1037 1038 return 0; 1039 } 1040 1041 static void __exit acpi_thermal_exit(void) 1042 { 1043 platform_driver_unregister(&acpi_thermal_driver); 1044 destroy_workqueue(acpi_thermal_pm_queue); 1045 } 1046 1047 module_init(acpi_thermal_init); 1048 module_exit(acpi_thermal_exit); 1049 1050 MODULE_IMPORT_NS("ACPI_THERMAL"); 1051 MODULE_AUTHOR("Paul Diefenbaugh"); 1052 MODULE_DESCRIPTION("ACPI Thermal Zone Driver"); 1053 MODULE_LICENSE("GPL"); 1054