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