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/thermal.h> 29 #include <linux/acpi.h> 30 #include <linux/workqueue.h> 31 #include <linux/uaccess.h> 32 #include <linux/units.h> 33 34 #include "internal.h" 35 36 #define ACPI_THERMAL_CLASS "thermal_zone" 37 #define ACPI_THERMAL_DEVICE_NAME "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(adev->pnp.device_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(tz->device->pnp.device_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(tz->device->pnp.device_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_unregister_thermal_zone(struct acpi_thermal *tz) 659 { 660 thermal_zone_device_disable(tz->thermal_zone); 661 acpi_thermal_zone_sysfs_remove(tz); 662 thermal_zone_device_unregister(tz->thermal_zone); 663 tz->thermal_zone = NULL; 664 } 665 666 667 /* -------------------------------------------------------------------------- 668 Driver Interface 669 -------------------------------------------------------------------------- */ 670 671 static void acpi_thermal_notify(acpi_handle handle, u32 event, void *data) 672 { 673 struct acpi_device *device = data; 674 struct acpi_thermal *tz = acpi_driver_data(device); 675 676 if (!tz) 677 return; 678 679 switch (event) { 680 case ACPI_THERMAL_NOTIFY_TEMPERATURE: 681 acpi_queue_thermal_check(tz); 682 break; 683 case ACPI_THERMAL_NOTIFY_THRESHOLDS: 684 case ACPI_THERMAL_NOTIFY_DEVICES: 685 acpi_thermal_trips_update(tz, event); 686 break; 687 default: 688 acpi_handle_debug(device->handle, "Unsupported event [0x%x]\n", 689 event); 690 break; 691 } 692 } 693 694 /* 695 * On some platforms, the AML code has dependency about 696 * the evaluating order of _TMP and _CRT/_HOT/_PSV/_ACx. 697 * 1. On HP Pavilion G4-1016tx, _TMP must be invoked after 698 * /_CRT/_HOT/_PSV/_ACx, or else system will be power off. 699 * 2. On HP Compaq 6715b/6715s, the return value of _PSV is 0 700 * if _TMP has never been evaluated. 701 * 702 * As this dependency is totally transparent to OS, evaluate 703 * all of them once, in the order of _CRT/_HOT/_PSV/_ACx, 704 * _TMP, before they are actually used. 705 */ 706 static void acpi_thermal_aml_dependency_fix(struct acpi_thermal *tz) 707 { 708 acpi_handle handle = tz->device->handle; 709 unsigned long long value; 710 int i; 711 712 acpi_evaluate_integer(handle, "_CRT", NULL, &value); 713 acpi_evaluate_integer(handle, "_HOT", NULL, &value); 714 acpi_evaluate_integer(handle, "_PSV", NULL, &value); 715 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { 716 char name[5] = { '_', 'A', 'C', ('0' + i), '\0' }; 717 acpi_status status; 718 719 status = acpi_evaluate_integer(handle, name, NULL, &value); 720 if (status == AE_NOT_FOUND) 721 break; 722 } 723 acpi_evaluate_integer(handle, "_TMP", NULL, &value); 724 } 725 726 /* 727 * The exact offset between Kelvin and degree Celsius is 273.15. However ACPI 728 * handles temperature values with a single decimal place. As a consequence, 729 * some implementations use an offset of 273.1 and others use an offset of 730 * 273.2. Try to find out which one is being used, to present the most 731 * accurate and visually appealing number. 732 * 733 * The heuristic below should work for all ACPI thermal zones which have a 734 * critical trip point with a value being a multiple of 0.5 degree Celsius. 735 */ 736 static void acpi_thermal_guess_offset(struct acpi_thermal *tz, long crit_temp) 737 { 738 if (crit_temp != THERMAL_TEMP_INVALID && crit_temp % 5 == 1) 739 tz->kelvin_offset = 273100; 740 else 741 tz->kelvin_offset = 273200; 742 } 743 744 static void acpi_thermal_check_fn(struct work_struct *work) 745 { 746 struct acpi_thermal *tz = container_of(work, struct acpi_thermal, 747 thermal_check_work); 748 749 /* 750 * In general, it is not sufficient to check the pending bit, because 751 * subsequent instances of this function may be queued after one of them 752 * has started running (e.g. if _TMP sleeps). Avoid bailing out if just 753 * one of them is running, though, because it may have done the actual 754 * check some time ago, so allow at least one of them to block on the 755 * mutex while another one is running the update. 756 */ 757 if (!refcount_dec_not_one(&tz->thermal_check_count)) 758 return; 759 760 mutex_lock(&tz->thermal_check_lock); 761 762 thermal_zone_device_update(tz->thermal_zone, THERMAL_EVENT_UNSPECIFIED); 763 764 refcount_inc(&tz->thermal_check_count); 765 766 mutex_unlock(&tz->thermal_check_lock); 767 } 768 769 static void acpi_thermal_free_thermal_zone(struct acpi_thermal *tz) 770 { 771 int i; 772 773 acpi_handle_list_free(&tz->trips.passive.trip.devices); 774 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) 775 acpi_handle_list_free(&tz->trips.active[i].trip.devices); 776 777 kfree(tz); 778 } 779 780 static int acpi_thermal_add(struct acpi_device *device) 781 { 782 struct thermal_trip trip_table[ACPI_THERMAL_MAX_NR_TRIPS] = { 0 }; 783 struct acpi_thermal_trip *acpi_trip; 784 struct thermal_trip *trip; 785 struct acpi_thermal *tz; 786 int crit_temp, hot_temp; 787 int passive_delay = 0; 788 int result; 789 int i; 790 791 if (!device) 792 return -EINVAL; 793 794 tz = kzalloc(sizeof(struct acpi_thermal), GFP_KERNEL); 795 if (!tz) 796 return -ENOMEM; 797 798 tz->device = device; 799 strscpy(tz->name, device->pnp.bus_id); 800 strscpy(acpi_device_name(device), ACPI_THERMAL_DEVICE_NAME); 801 strscpy(acpi_device_class(device), ACPI_THERMAL_CLASS); 802 device->driver_data = tz; 803 804 acpi_thermal_aml_dependency_fix(tz); 805 806 /* Get trip points [_CRT, _PSV, etc.] (required). */ 807 acpi_thermal_get_trip_points(tz); 808 809 crit_temp = acpi_thermal_get_critical_trip(tz); 810 hot_temp = acpi_thermal_get_hot_trip(tz); 811 812 /* Get temperature [_TMP] (required). */ 813 result = acpi_thermal_get_temperature(tz); 814 if (result) 815 goto free_memory; 816 817 /* Set the cooling mode [_SCP] to active cooling. */ 818 acpi_execute_simple_method(tz->device->handle, "_SCP", 819 ACPI_THERMAL_MODE_ACTIVE); 820 821 /* Determine the default polling frequency [_TZP]. */ 822 if (tzp) 823 tz->polling_frequency = tzp; 824 else 825 acpi_thermal_get_polling_frequency(tz); 826 827 acpi_thermal_guess_offset(tz, crit_temp); 828 829 trip = trip_table; 830 831 if (crit_temp != THERMAL_TEMP_INVALID) { 832 trip->type = THERMAL_TRIP_CRITICAL; 833 trip->temperature = acpi_thermal_temp(tz, crit_temp); 834 trip++; 835 } 836 837 if (hot_temp != THERMAL_TEMP_INVALID) { 838 trip->type = THERMAL_TRIP_HOT; 839 trip->temperature = acpi_thermal_temp(tz, hot_temp); 840 trip++; 841 } 842 843 acpi_trip = &tz->trips.passive.trip; 844 if (acpi_thermal_trip_valid(acpi_trip)) { 845 passive_delay = tz->trips.passive.delay; 846 847 trip->type = THERMAL_TRIP_PASSIVE; 848 trip->temperature = acpi_thermal_temp(tz, acpi_trip->temp_dk); 849 trip->priv = acpi_trip; 850 trip++; 851 } 852 853 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { 854 acpi_trip = &tz->trips.active[i].trip; 855 856 if (!acpi_thermal_trip_valid(acpi_trip)) 857 break; 858 859 trip->type = THERMAL_TRIP_ACTIVE; 860 trip->temperature = acpi_thermal_temp(tz, acpi_trip->temp_dk); 861 trip->priv = acpi_trip; 862 trip++; 863 } 864 865 if (trip == trip_table) 866 pr_warn(FW_BUG "No valid trip points!\n"); 867 868 result = acpi_thermal_register_thermal_zone(tz, trip_table, 869 trip - trip_table, 870 passive_delay); 871 if (result) 872 goto free_memory; 873 874 refcount_set(&tz->thermal_check_count, 3); 875 mutex_init(&tz->thermal_check_lock); 876 INIT_WORK(&tz->thermal_check_work, acpi_thermal_check_fn); 877 878 pr_info("%s [%s] (%ld C)\n", acpi_device_name(device), 879 acpi_device_bid(device), deci_kelvin_to_celsius(tz->temp_dk)); 880 881 result = acpi_dev_install_notify_handler(device, ACPI_DEVICE_NOTIFY, 882 acpi_thermal_notify, device); 883 if (result) 884 goto flush_wq; 885 886 return 0; 887 888 flush_wq: 889 flush_workqueue(acpi_thermal_pm_queue); 890 acpi_thermal_unregister_thermal_zone(tz); 891 free_memory: 892 acpi_thermal_free_thermal_zone(tz); 893 894 return result; 895 } 896 897 static void acpi_thermal_remove(struct acpi_device *device) 898 { 899 struct acpi_thermal *tz; 900 901 if (!device || !acpi_driver_data(device)) 902 return; 903 904 tz = acpi_driver_data(device); 905 906 acpi_dev_remove_notify_handler(device, ACPI_DEVICE_NOTIFY, 907 acpi_thermal_notify); 908 909 flush_workqueue(acpi_thermal_pm_queue); 910 acpi_thermal_unregister_thermal_zone(tz); 911 acpi_thermal_free_thermal_zone(tz); 912 } 913 914 #ifdef CONFIG_PM_SLEEP 915 static int acpi_thermal_suspend(struct device *dev) 916 { 917 /* Make sure the previously queued thermal check work has been done */ 918 flush_workqueue(acpi_thermal_pm_queue); 919 return 0; 920 } 921 922 static int acpi_thermal_resume(struct device *dev) 923 { 924 struct acpi_thermal *tz; 925 int i, j, power_state; 926 927 if (!dev) 928 return -EINVAL; 929 930 tz = acpi_driver_data(to_acpi_device(dev)); 931 if (!tz) 932 return -EINVAL; 933 934 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { 935 struct acpi_thermal_trip *acpi_trip = &tz->trips.active[i].trip; 936 937 if (!acpi_thermal_trip_valid(acpi_trip)) 938 break; 939 940 for (j = 0; j < acpi_trip->devices.count; j++) { 941 acpi_bus_update_power(acpi_trip->devices.handles[j], 942 &power_state); 943 } 944 } 945 946 acpi_queue_thermal_check(tz); 947 948 return AE_OK; 949 } 950 #else 951 #define acpi_thermal_suspend NULL 952 #define acpi_thermal_resume NULL 953 #endif 954 static SIMPLE_DEV_PM_OPS(acpi_thermal_pm, acpi_thermal_suspend, acpi_thermal_resume); 955 956 static const struct acpi_device_id thermal_device_ids[] = { 957 {ACPI_THERMAL_HID, 0}, 958 {"", 0}, 959 }; 960 MODULE_DEVICE_TABLE(acpi, thermal_device_ids); 961 962 static struct acpi_driver acpi_thermal_driver = { 963 .name = "thermal", 964 .class = ACPI_THERMAL_CLASS, 965 .ids = thermal_device_ids, 966 .ops = { 967 .add = acpi_thermal_add, 968 .remove = acpi_thermal_remove, 969 }, 970 .drv.pm = &acpi_thermal_pm, 971 }; 972 973 static int thermal_act(const struct dmi_system_id *d) 974 { 975 if (act == 0) { 976 pr_notice("%s detected: disabling all active thermal trip points\n", 977 d->ident); 978 act = -1; 979 } 980 return 0; 981 } 982 983 static int thermal_nocrt(const struct dmi_system_id *d) 984 { 985 pr_notice("%s detected: disabling all critical thermal trip point actions.\n", 986 d->ident); 987 crt = -1; 988 return 0; 989 } 990 991 static int thermal_tzp(const struct dmi_system_id *d) 992 { 993 if (tzp == 0) { 994 pr_notice("%s detected: enabling thermal zone polling\n", 995 d->ident); 996 tzp = 300; /* 300 dS = 30 Seconds */ 997 } 998 return 0; 999 } 1000 1001 static int thermal_psv(const struct dmi_system_id *d) 1002 { 1003 if (psv == 0) { 1004 pr_notice("%s detected: disabling all passive thermal trip points\n", 1005 d->ident); 1006 psv = -1; 1007 } 1008 return 0; 1009 } 1010 1011 static const struct dmi_system_id thermal_dmi_table[] __initconst = { 1012 /* 1013 * Award BIOS on this AOpen makes thermal control almost worthless. 1014 * http://bugzilla.kernel.org/show_bug.cgi?id=8842 1015 */ 1016 { 1017 .callback = thermal_act, 1018 .ident = "AOpen i915GMm-HFS", 1019 .matches = { 1020 DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"), 1021 DMI_MATCH(DMI_BOARD_NAME, "i915GMm-HFS"), 1022 }, 1023 }, 1024 { 1025 .callback = thermal_psv, 1026 .ident = "AOpen i915GMm-HFS", 1027 .matches = { 1028 DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"), 1029 DMI_MATCH(DMI_BOARD_NAME, "i915GMm-HFS"), 1030 }, 1031 }, 1032 { 1033 .callback = thermal_tzp, 1034 .ident = "AOpen i915GMm-HFS", 1035 .matches = { 1036 DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"), 1037 DMI_MATCH(DMI_BOARD_NAME, "i915GMm-HFS"), 1038 }, 1039 }, 1040 { 1041 .callback = thermal_nocrt, 1042 .ident = "Gigabyte GA-7ZX", 1043 .matches = { 1044 DMI_MATCH(DMI_BOARD_VENDOR, "Gigabyte Technology Co., Ltd."), 1045 DMI_MATCH(DMI_BOARD_NAME, "7ZX"), 1046 }, 1047 }, 1048 {} 1049 }; 1050 1051 static int __init acpi_thermal_init(void) 1052 { 1053 int result; 1054 1055 dmi_check_system(thermal_dmi_table); 1056 1057 if (off) { 1058 pr_notice("thermal control disabled\n"); 1059 return -ENODEV; 1060 } 1061 1062 acpi_thermal_pm_queue = alloc_workqueue("acpi_thermal_pm", 1063 WQ_HIGHPRI | WQ_MEM_RECLAIM, 0); 1064 if (!acpi_thermal_pm_queue) 1065 return -ENODEV; 1066 1067 result = acpi_bus_register_driver(&acpi_thermal_driver); 1068 if (result < 0) { 1069 destroy_workqueue(acpi_thermal_pm_queue); 1070 return -ENODEV; 1071 } 1072 1073 return 0; 1074 } 1075 1076 static void __exit acpi_thermal_exit(void) 1077 { 1078 acpi_bus_unregister_driver(&acpi_thermal_driver); 1079 destroy_workqueue(acpi_thermal_pm_queue); 1080 } 1081 1082 module_init(acpi_thermal_init); 1083 module_exit(acpi_thermal_exit); 1084 1085 MODULE_IMPORT_NS(ACPI_THERMAL); 1086 MODULE_AUTHOR("Paul Diefenbaugh"); 1087 MODULE_DESCRIPTION("ACPI Thermal Zone Driver"); 1088 MODULE_LICENSE("GPL"); 1089