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 device *parent = cdev->device.parent; 568 acpi_handle parent_handle; 569 int i; 570 571 /* Skip critical and hot trips and parentless cooling devices. */ 572 if (!acpi_trip || !parent) 573 return false; 574 575 parent_handle = ACPI_HANDLE(parent); 576 if (!parent_handle) 577 return false; 578 579 for (i = 0; i < acpi_trip->devices.count; i++) { 580 if (acpi_trip->devices.handles[i] == parent_handle) 581 return true; 582 } 583 584 return false; 585 } 586 587 static const struct thermal_zone_device_ops acpi_thermal_zone_ops = { 588 .should_bind = acpi_thermal_should_bind_cdev, 589 .get_temp = thermal_get_temp, 590 .get_trend = thermal_get_trend, 591 .hot = acpi_thermal_zone_device_hot, 592 .critical = acpi_thermal_zone_device_critical, 593 }; 594 595 static int acpi_thermal_zone_sysfs_add(struct acpi_thermal *tz) 596 { 597 struct device *tzdev = thermal_zone_device(tz->thermal_zone); 598 int ret; 599 600 ret = sysfs_create_link(&tz->device->dev.kobj, 601 &tzdev->kobj, "thermal_zone"); 602 if (ret) 603 return ret; 604 605 ret = sysfs_create_link(&tzdev->kobj, 606 &tz->device->dev.kobj, "device"); 607 if (ret) 608 sysfs_remove_link(&tz->device->dev.kobj, "thermal_zone"); 609 610 return ret; 611 } 612 613 static void acpi_thermal_zone_sysfs_remove(struct acpi_thermal *tz) 614 { 615 struct device *tzdev = thermal_zone_device(tz->thermal_zone); 616 617 sysfs_remove_link(&tz->device->dev.kobj, "thermal_zone"); 618 sysfs_remove_link(&tzdev->kobj, "device"); 619 } 620 621 static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz, 622 const struct thermal_trip *trip_table, 623 unsigned int trip_count, 624 int passive_delay) 625 { 626 int result; 627 628 if (trip_count) 629 tz->thermal_zone = thermal_zone_device_register_with_trips( 630 "acpitz", trip_table, trip_count, tz, 631 &acpi_thermal_zone_ops, NULL, passive_delay, 632 tz->polling_frequency * 100); 633 else 634 tz->thermal_zone = thermal_tripless_zone_device_register( 635 "acpitz", tz, &acpi_thermal_zone_ops, NULL); 636 637 if (IS_ERR(tz->thermal_zone)) 638 return PTR_ERR(tz->thermal_zone); 639 640 result = acpi_thermal_zone_sysfs_add(tz); 641 if (result) 642 goto unregister_tzd; 643 644 result = thermal_zone_device_enable(tz->thermal_zone); 645 if (result) 646 goto remove_links; 647 648 dev_info(&tz->device->dev, "registered as thermal_zone%d\n", 649 thermal_zone_device_id(tz->thermal_zone)); 650 651 return 0; 652 653 remove_links: 654 acpi_thermal_zone_sysfs_remove(tz); 655 unregister_tzd: 656 thermal_zone_device_unregister(tz->thermal_zone); 657 658 return result; 659 } 660 661 static void acpi_thermal_zone_unregister(void *data) 662 { 663 struct acpi_thermal *tz = data; 664 665 flush_workqueue(acpi_thermal_pm_queue); 666 667 thermal_zone_device_disable(tz->thermal_zone); 668 acpi_thermal_zone_sysfs_remove(tz); 669 thermal_zone_device_unregister(tz->thermal_zone); 670 tz->thermal_zone = NULL; 671 } 672 673 674 /* -------------------------------------------------------------------------- 675 Driver Interface 676 -------------------------------------------------------------------------- */ 677 678 static void acpi_thermal_notify(acpi_handle handle, u32 event, void *data) 679 { 680 struct acpi_thermal *tz = data; 681 682 if (!tz) 683 return; 684 685 switch (event) { 686 case ACPI_THERMAL_NOTIFY_TEMPERATURE: 687 acpi_queue_thermal_check(tz); 688 break; 689 case ACPI_THERMAL_NOTIFY_THRESHOLDS: 690 case ACPI_THERMAL_NOTIFY_DEVICES: 691 acpi_thermal_trips_update(tz, event); 692 break; 693 default: 694 acpi_handle_debug(tz->device->handle, 695 "Unsupported event [0x%x]\n", event); 696 break; 697 } 698 } 699 700 /* 701 * On some platforms, the AML code has dependency about 702 * the evaluating order of _TMP and _CRT/_HOT/_PSV/_ACx. 703 * 1. On HP Pavilion G4-1016tx, _TMP must be invoked after 704 * /_CRT/_HOT/_PSV/_ACx, or else system will be power off. 705 * 2. On HP Compaq 6715b/6715s, the return value of _PSV is 0 706 * if _TMP has never been evaluated. 707 * 708 * As this dependency is totally transparent to OS, evaluate 709 * all of them once, in the order of _CRT/_HOT/_PSV/_ACx, 710 * _TMP, before they are actually used. 711 */ 712 static void acpi_thermal_aml_dependency_fix(struct acpi_thermal *tz) 713 { 714 acpi_handle handle = tz->device->handle; 715 unsigned long long value; 716 int i; 717 718 acpi_evaluate_integer(handle, "_CRT", NULL, &value); 719 acpi_evaluate_integer(handle, "_HOT", NULL, &value); 720 acpi_evaluate_integer(handle, "_PSV", NULL, &value); 721 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { 722 char name[5] = { '_', 'A', 'C', ('0' + i), '\0' }; 723 acpi_status status; 724 725 status = acpi_evaluate_integer(handle, name, NULL, &value); 726 if (status == AE_NOT_FOUND) 727 break; 728 } 729 acpi_evaluate_integer(handle, "_TMP", NULL, &value); 730 } 731 732 /* 733 * The exact offset between Kelvin and degree Celsius is 273.15. However ACPI 734 * handles temperature values with a single decimal place. As a consequence, 735 * some implementations use an offset of 273.1 and others use an offset of 736 * 273.2. Try to find out which one is being used, to present the most 737 * accurate and visually appealing number. 738 * 739 * The heuristic below should work for all ACPI thermal zones which have a 740 * critical trip point with a value being a multiple of 0.5 degree Celsius. 741 */ 742 static void acpi_thermal_guess_offset(struct acpi_thermal *tz, long crit_temp) 743 { 744 if (crit_temp != THERMAL_TEMP_INVALID && crit_temp % 5 == 0) 745 tz->kelvin_offset = 273000; 746 else if (crit_temp != THERMAL_TEMP_INVALID && crit_temp % 5 == 1) 747 tz->kelvin_offset = 273100; 748 else 749 tz->kelvin_offset = 273200; 750 } 751 752 static void acpi_thermal_check_fn(struct work_struct *work) 753 { 754 struct acpi_thermal *tz = container_of(work, struct acpi_thermal, 755 thermal_check_work); 756 757 /* 758 * In general, it is not sufficient to check the pending bit, because 759 * subsequent instances of this function may be queued after one of them 760 * has started running (e.g. if _TMP sleeps). Avoid bailing out if just 761 * one of them is running, though, because it may have done the actual 762 * check some time ago, so allow at least one of them to block on the 763 * mutex while another one is running the update. 764 */ 765 if (!refcount_dec_not_one(&tz->thermal_check_count)) 766 return; 767 768 mutex_lock(&tz->thermal_check_lock); 769 770 thermal_zone_device_update(tz->thermal_zone, THERMAL_EVENT_UNSPECIFIED); 771 772 refcount_inc(&tz->thermal_check_count); 773 774 mutex_unlock(&tz->thermal_check_lock); 775 } 776 777 static void acpi_thermal_zone_free(void *data) 778 { 779 struct acpi_thermal *tz = data; 780 int i; 781 782 acpi_handle_list_free(&tz->trips.passive.trip.devices); 783 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) 784 acpi_handle_list_free(&tz->trips.active[i].trip.devices); 785 786 kfree(tz); 787 } 788 789 static int acpi_thermal_probe(struct platform_device *pdev) 790 { 791 struct thermal_trip trip_table[ACPI_THERMAL_MAX_NR_TRIPS] = { 0 }; 792 struct device *dev = &pdev->dev; 793 struct acpi_device *device = ACPI_COMPANION(dev); 794 struct acpi_thermal_trip *acpi_trip; 795 struct thermal_trip *trip; 796 struct acpi_thermal *tz; 797 int crit_temp, hot_temp; 798 int passive_delay = 0; 799 int result; 800 int i; 801 802 if (!device) 803 return -ENODEV; 804 805 tz = kzalloc_obj(struct acpi_thermal); 806 if (!tz) 807 return -ENOMEM; 808 809 result = devm_add_action_or_reset(dev, acpi_thermal_zone_free, tz); 810 if (result) 811 return result; 812 813 platform_set_drvdata(pdev, tz); 814 815 tz->device = device; 816 strscpy(tz->name, device->pnp.bus_id); 817 818 acpi_thermal_aml_dependency_fix(tz); 819 820 /* 821 * Set the cooling mode [_SCP] to active cooling. This needs to happen before 822 * we retrieve the trip point values. 823 */ 824 acpi_execute_simple_method(tz->device->handle, "_SCP", ACPI_THERMAL_MODE_ACTIVE); 825 826 /* Get trip points [_ACi, _PSV, etc.] (required). */ 827 acpi_thermal_get_trip_points(tz); 828 829 crit_temp = acpi_thermal_get_critical_trip(tz); 830 hot_temp = acpi_thermal_get_hot_trip(tz); 831 832 /* Get temperature [_TMP] (required). */ 833 result = acpi_thermal_get_temperature(tz); 834 if (result) 835 return result; 836 837 /* Determine the default polling frequency [_TZP]. */ 838 if (tzp) 839 tz->polling_frequency = tzp; 840 else 841 acpi_thermal_get_polling_frequency(tz); 842 843 acpi_thermal_guess_offset(tz, crit_temp); 844 845 trip = trip_table; 846 847 if (crit_temp != THERMAL_TEMP_INVALID) { 848 trip->type = THERMAL_TRIP_CRITICAL; 849 trip->temperature = acpi_thermal_temp(tz, crit_temp); 850 trip++; 851 } 852 853 if (hot_temp != THERMAL_TEMP_INVALID) { 854 trip->type = THERMAL_TRIP_HOT; 855 trip->temperature = acpi_thermal_temp(tz, hot_temp); 856 trip++; 857 } 858 859 acpi_trip = &tz->trips.passive.trip; 860 if (acpi_thermal_trip_valid(acpi_trip)) { 861 passive_delay = tz->trips.passive.delay; 862 863 trip->type = THERMAL_TRIP_PASSIVE; 864 trip->temperature = acpi_thermal_temp(tz, acpi_trip->temp_dk); 865 trip->priv = acpi_trip; 866 trip++; 867 } 868 869 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { 870 acpi_trip = &tz->trips.active[i].trip; 871 872 if (!acpi_thermal_trip_valid(acpi_trip)) 873 break; 874 875 trip->type = THERMAL_TRIP_ACTIVE; 876 trip->temperature = acpi_thermal_temp(tz, acpi_trip->temp_dk); 877 trip->priv = acpi_trip; 878 trip++; 879 } 880 881 if (trip == trip_table) 882 pr_warn(FW_BUG "No valid trip points!\n"); 883 884 result = acpi_thermal_register_thermal_zone(tz, trip_table, 885 trip - trip_table, 886 passive_delay); 887 if (result) 888 return result; 889 890 result = devm_add_action_or_reset(dev, acpi_thermal_zone_unregister, tz); 891 if (result) 892 return result; 893 894 refcount_set(&tz->thermal_check_count, 3); 895 mutex_init(&tz->thermal_check_lock); 896 INIT_WORK(&tz->thermal_check_work, acpi_thermal_check_fn); 897 898 pr_info("Thermal Zone [%s] (%ld C)\n", acpi_device_bid(device), 899 deci_kelvin_to_celsius(tz->temp_dk)); 900 901 return devm_acpi_install_notify_handler(dev, ACPI_DEVICE_NOTIFY, 902 acpi_thermal_notify, tz); 903 } 904 905 #ifdef CONFIG_PM_SLEEP 906 static int acpi_thermal_prepare(struct device *dev) 907 { 908 /* Make sure the previously queued thermal check work has been done */ 909 flush_workqueue(acpi_thermal_pm_queue); 910 return 0; 911 } 912 913 static void acpi_thermal_complete(struct device *dev) 914 { 915 acpi_queue_thermal_check(dev_get_drvdata(dev)); 916 } 917 918 static const struct dev_pm_ops acpi_thermal_pm_ops = { 919 .prepare = acpi_thermal_prepare, 920 .complete = acpi_thermal_complete, 921 }; 922 #define ACPI_THERMAL_PM &acpi_thermal_pm_ops 923 #else /* !CONFIG_PM_SLEEP */ 924 #define ACPI_THERMAL_PM NULL 925 #endif /* CONFIG_PM_SLEEP */ 926 927 static const struct acpi_device_id thermal_device_ids[] = { 928 {ACPI_THERMAL_HID, 0}, 929 {"", 0}, 930 }; 931 MODULE_DEVICE_TABLE(acpi, thermal_device_ids); 932 933 static struct platform_driver acpi_thermal_driver = { 934 .probe = acpi_thermal_probe, 935 .driver = { 936 .name = "acpi-thermal", 937 .acpi_match_table = thermal_device_ids, 938 .pm = ACPI_THERMAL_PM, 939 }, 940 }; 941 942 static int thermal_act(const struct dmi_system_id *d) 943 { 944 if (act == 0) { 945 pr_notice("%s detected: disabling all active thermal trip points\n", 946 d->ident); 947 act = -1; 948 } 949 return 0; 950 } 951 952 static int thermal_nocrt(const struct dmi_system_id *d) 953 { 954 pr_notice("%s detected: disabling all critical thermal trip point actions.\n", 955 d->ident); 956 crt = -1; 957 return 0; 958 } 959 960 static int thermal_tzp(const struct dmi_system_id *d) 961 { 962 if (tzp == 0) { 963 pr_notice("%s detected: enabling thermal zone polling\n", 964 d->ident); 965 tzp = 300; /* 300 dS = 30 Seconds */ 966 } 967 return 0; 968 } 969 970 static int thermal_psv(const struct dmi_system_id *d) 971 { 972 if (psv == 0) { 973 pr_notice("%s detected: disabling all passive thermal trip points\n", 974 d->ident); 975 psv = -1; 976 } 977 return 0; 978 } 979 980 static const struct dmi_system_id thermal_dmi_table[] __initconst = { 981 /* 982 * Award BIOS on this AOpen makes thermal control almost worthless. 983 * http://bugzilla.kernel.org/show_bug.cgi?id=8842 984 */ 985 { 986 .callback = thermal_act, 987 .ident = "AOpen i915GMm-HFS", 988 .matches = { 989 DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"), 990 DMI_MATCH(DMI_BOARD_NAME, "i915GMm-HFS"), 991 }, 992 }, 993 { 994 .callback = thermal_psv, 995 .ident = "AOpen i915GMm-HFS", 996 .matches = { 997 DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"), 998 DMI_MATCH(DMI_BOARD_NAME, "i915GMm-HFS"), 999 }, 1000 }, 1001 { 1002 .callback = thermal_tzp, 1003 .ident = "AOpen i915GMm-HFS", 1004 .matches = { 1005 DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"), 1006 DMI_MATCH(DMI_BOARD_NAME, "i915GMm-HFS"), 1007 }, 1008 }, 1009 { 1010 .callback = thermal_nocrt, 1011 .ident = "Gigabyte GA-7ZX", 1012 .matches = { 1013 DMI_MATCH(DMI_BOARD_VENDOR, "Gigabyte Technology Co., Ltd."), 1014 DMI_MATCH(DMI_BOARD_NAME, "7ZX"), 1015 }, 1016 }, 1017 {} 1018 }; 1019 1020 static int __init acpi_thermal_init(void) 1021 { 1022 int result; 1023 1024 dmi_check_system(thermal_dmi_table); 1025 1026 if (off) { 1027 pr_notice("thermal control disabled\n"); 1028 return -ENODEV; 1029 } 1030 1031 acpi_thermal_pm_queue = alloc_workqueue("acpi_thermal_pm", 1032 WQ_HIGHPRI | WQ_MEM_RECLAIM | WQ_PERCPU, 1033 0); 1034 if (!acpi_thermal_pm_queue) 1035 return -ENODEV; 1036 1037 result = platform_driver_register(&acpi_thermal_driver); 1038 if (result < 0) { 1039 destroy_workqueue(acpi_thermal_pm_queue); 1040 return -ENODEV; 1041 } 1042 1043 return 0; 1044 } 1045 1046 static void __exit acpi_thermal_exit(void) 1047 { 1048 platform_driver_unregister(&acpi_thermal_driver); 1049 destroy_workqueue(acpi_thermal_pm_queue); 1050 } 1051 1052 module_init(acpi_thermal_init); 1053 module_exit(acpi_thermal_exit); 1054 1055 MODULE_IMPORT_NS("ACPI_THERMAL"); 1056 MODULE_AUTHOR("Paul Diefenbaugh"); 1057 MODULE_DESCRIPTION("ACPI Thermal Zone Driver"); 1058 MODULE_LICENSE("GPL"); 1059