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 if (temp_deci_k == THERMAL_TEMP_INVALID) 172 return THERMAL_TEMP_INVALID; 173 174 return deci_kelvin_to_millicelsius_with_offset(temp_deci_k, 175 tz->kelvin_offset); 176 } 177 178 static bool acpi_thermal_trip_valid(struct acpi_thermal_trip *acpi_trip) 179 { 180 return acpi_trip->temp_dk != THERMAL_TEMP_INVALID; 181 } 182 183 static int active_trip_index(struct acpi_thermal *tz, 184 struct acpi_thermal_trip *acpi_trip) 185 { 186 struct acpi_thermal_active *active; 187 188 active = container_of(acpi_trip, struct acpi_thermal_active, trip); 189 return active - tz->trips.active; 190 } 191 192 static long get_passive_temp(struct acpi_thermal *tz) 193 { 194 int temp; 195 196 if (acpi_passive_trip_temp(tz->device, &temp)) 197 return THERMAL_TEMP_INVALID; 198 199 return temp; 200 } 201 202 static long get_active_temp(struct acpi_thermal *tz, int index) 203 { 204 int temp; 205 206 if (acpi_active_trip_temp(tz->device, index, &temp)) 207 return THERMAL_TEMP_INVALID; 208 209 /* 210 * If an override has been provided, apply it so there are no active 211 * trips with thresholds greater than the override. 212 */ 213 if (act > 0) { 214 unsigned long long override = celsius_to_deci_kelvin(act); 215 216 if (temp > override) 217 return override; 218 } 219 return temp; 220 } 221 222 static void acpi_thermal_update_trip(struct acpi_thermal *tz, 223 const struct thermal_trip *trip) 224 { 225 struct acpi_thermal_trip *acpi_trip = trip->priv; 226 227 if (trip->type == THERMAL_TRIP_PASSIVE) { 228 if (psv > 0) 229 return; 230 231 acpi_trip->temp_dk = get_passive_temp(tz); 232 } else { 233 int index = active_trip_index(tz, acpi_trip); 234 235 acpi_trip->temp_dk = get_active_temp(tz, index); 236 } 237 238 if (!acpi_thermal_trip_valid(acpi_trip)) 239 ACPI_THERMAL_TRIPS_EXCEPTION(tz, "state"); 240 } 241 242 static bool update_trip_devices(struct acpi_thermal *tz, 243 struct acpi_thermal_trip *acpi_trip, 244 int index, bool compare) 245 { 246 struct acpi_handle_list devices = { 0 }; 247 char method[] = "_PSL"; 248 249 if (index != ACPI_THERMAL_TRIP_PASSIVE) { 250 method[1] = 'A'; 251 method[2] = 'L'; 252 method[3] = '0' + index; 253 } 254 255 if (!acpi_evaluate_reference(tz->device->handle, method, NULL, &devices)) { 256 acpi_handle_info(tz->device->handle, "%s evaluation failure\n", method); 257 return false; 258 } 259 260 if (acpi_handle_list_equal(&acpi_trip->devices, &devices)) { 261 acpi_handle_list_free(&devices); 262 return true; 263 } 264 265 if (compare) 266 ACPI_THERMAL_TRIPS_EXCEPTION(tz, "device"); 267 268 acpi_handle_list_replace(&acpi_trip->devices, &devices); 269 return true; 270 } 271 272 static void acpi_thermal_update_trip_devices(struct acpi_thermal *tz, 273 const struct thermal_trip *trip) 274 { 275 struct acpi_thermal_trip *acpi_trip = trip->priv; 276 int index = trip->type == THERMAL_TRIP_PASSIVE ? 277 ACPI_THERMAL_TRIP_PASSIVE : active_trip_index(tz, acpi_trip); 278 279 if (update_trip_devices(tz, acpi_trip, index, true)) 280 return; 281 282 acpi_trip->temp_dk = THERMAL_TEMP_INVALID; 283 ACPI_THERMAL_TRIPS_EXCEPTION(tz, "state"); 284 } 285 286 struct adjust_trip_data { 287 struct acpi_thermal *tz; 288 u32 event; 289 }; 290 291 static int acpi_thermal_adjust_trip(struct thermal_trip *trip, void *data) 292 { 293 struct acpi_thermal_trip *acpi_trip = trip->priv; 294 struct adjust_trip_data *atd = data; 295 struct acpi_thermal *tz = atd->tz; 296 int temp; 297 298 if (!acpi_trip || !acpi_thermal_trip_valid(acpi_trip)) 299 return 0; 300 301 if (atd->event == ACPI_THERMAL_NOTIFY_THRESHOLDS) 302 acpi_thermal_update_trip(tz, trip); 303 else 304 acpi_thermal_update_trip_devices(tz, trip); 305 306 if (acpi_thermal_trip_valid(acpi_trip)) 307 temp = acpi_thermal_temp(tz, acpi_trip->temp_dk); 308 else 309 temp = THERMAL_TEMP_INVALID; 310 311 thermal_zone_set_trip_temp(tz->thermal_zone, trip, temp); 312 313 return 0; 314 } 315 316 static void acpi_queue_thermal_check(struct acpi_thermal *tz) 317 { 318 if (!work_pending(&tz->thermal_check_work)) 319 queue_work(acpi_thermal_pm_queue, &tz->thermal_check_work); 320 } 321 322 static void acpi_thermal_trips_update(struct acpi_thermal *tz, u32 event) 323 { 324 struct adjust_trip_data atd = { .tz = tz, .event = event }; 325 struct acpi_device *adev = tz->device; 326 327 /* 328 * Use thermal_zone_for_each_trip() to carry out the trip points 329 * update, so as to protect thermal_get_trend() from getting stale 330 * trip point temperatures and to prevent thermal_zone_device_update() 331 * invoked from acpi_thermal_check_fn() from producing inconsistent 332 * results. 333 */ 334 thermal_zone_for_each_trip(tz->thermal_zone, 335 acpi_thermal_adjust_trip, &atd); 336 acpi_queue_thermal_check(tz); 337 acpi_bus_generate_netlink_event(adev->pnp.device_class, 338 dev_name(&adev->dev), event, 0); 339 } 340 341 static int acpi_thermal_get_critical_trip(struct acpi_thermal *tz) 342 { 343 int temp; 344 345 if (crt > 0) { 346 temp = celsius_to_deci_kelvin(crt); 347 goto set; 348 } 349 if (crt == -1) { 350 acpi_handle_debug(tz->device->handle, "Critical threshold disabled\n"); 351 return THERMAL_TEMP_INVALID; 352 } 353 354 if (acpi_critical_trip_temp(tz->device, &temp)) 355 return THERMAL_TEMP_INVALID; 356 357 if (temp <= 2732) { 358 /* 359 * Below zero (Celsius) values clearly aren't right for sure, 360 * so discard them as invalid. 361 */ 362 pr_info(FW_BUG "Invalid critical threshold (%d)\n", temp); 363 return THERMAL_TEMP_INVALID; 364 } 365 366 set: 367 acpi_handle_debug(tz->device->handle, "Critical threshold [%d]\n", temp); 368 return temp; 369 } 370 371 static int acpi_thermal_get_hot_trip(struct acpi_thermal *tz) 372 { 373 int temp; 374 375 if (acpi_hot_trip_temp(tz->device, &temp) || temp == THERMAL_TEMP_INVALID) { 376 acpi_handle_debug(tz->device->handle, "No hot threshold\n"); 377 return THERMAL_TEMP_INVALID; 378 } 379 380 acpi_handle_debug(tz->device->handle, "Hot threshold [%d]\n", temp); 381 return temp; 382 } 383 384 static bool passive_trip_params_init(struct acpi_thermal *tz) 385 { 386 unsigned long long tmp; 387 acpi_status status; 388 389 status = acpi_evaluate_integer(tz->device->handle, "_TC1", NULL, &tmp); 390 if (ACPI_FAILURE(status)) 391 return false; 392 393 tz->trips.passive.tc1 = tmp; 394 395 status = acpi_evaluate_integer(tz->device->handle, "_TC2", NULL, &tmp); 396 if (ACPI_FAILURE(status)) 397 return false; 398 399 tz->trips.passive.tc2 = tmp; 400 401 status = acpi_evaluate_integer(tz->device->handle, "_TFP", NULL, &tmp); 402 if (ACPI_SUCCESS(status)) { 403 tz->trips.passive.delay = tmp; 404 return true; 405 } 406 407 status = acpi_evaluate_integer(tz->device->handle, "_TSP", NULL, &tmp); 408 if (ACPI_FAILURE(status)) 409 return false; 410 411 tz->trips.passive.delay = tmp * 100; 412 413 return true; 414 } 415 416 static bool acpi_thermal_init_trip(struct acpi_thermal *tz, int index) 417 { 418 struct acpi_thermal_trip *acpi_trip; 419 long temp; 420 421 if (index == ACPI_THERMAL_TRIP_PASSIVE) { 422 acpi_trip = &tz->trips.passive.trip; 423 424 if (psv == -1) 425 goto fail; 426 427 if (!passive_trip_params_init(tz)) 428 goto fail; 429 430 temp = psv > 0 ? celsius_to_deci_kelvin(psv) : 431 get_passive_temp(tz); 432 } else { 433 acpi_trip = &tz->trips.active[index].trip; 434 435 if (act == -1) 436 goto fail; 437 438 temp = get_active_temp(tz, index); 439 } 440 441 if (temp == THERMAL_TEMP_INVALID) 442 goto fail; 443 444 if (!update_trip_devices(tz, acpi_trip, index, false)) 445 goto fail; 446 447 acpi_trip->temp_dk = temp; 448 return true; 449 450 fail: 451 acpi_trip->temp_dk = THERMAL_TEMP_INVALID; 452 return false; 453 } 454 455 static void acpi_thermal_get_trip_points(struct acpi_thermal *tz) 456 { 457 int i; 458 459 acpi_thermal_init_trip(tz, ACPI_THERMAL_TRIP_PASSIVE); 460 461 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { 462 if (!acpi_thermal_init_trip(tz, i)) 463 break; 464 } 465 466 while (++i < ACPI_THERMAL_MAX_ACTIVE) 467 tz->trips.active[i].trip.temp_dk = THERMAL_TEMP_INVALID; 468 } 469 470 /* sys I/F for generic thermal sysfs support */ 471 472 static int thermal_get_temp(struct thermal_zone_device *thermal, int *temp) 473 { 474 struct acpi_thermal *tz = thermal_zone_device_priv(thermal); 475 int result; 476 477 if (!tz) 478 return -EINVAL; 479 480 result = acpi_thermal_get_temperature(tz); 481 if (result) 482 return result; 483 484 *temp = deci_kelvin_to_millicelsius_with_offset(tz->temp_dk, 485 tz->kelvin_offset); 486 return 0; 487 } 488 489 static int thermal_get_trend(struct thermal_zone_device *thermal, 490 const struct thermal_trip *trip, 491 enum thermal_trend *trend) 492 { 493 struct acpi_thermal *tz = thermal_zone_device_priv(thermal); 494 struct acpi_thermal_trip *acpi_trip; 495 int t; 496 497 if (!tz || !trip) 498 return -EINVAL; 499 500 acpi_trip = trip->priv; 501 if (!acpi_trip || !acpi_thermal_trip_valid(acpi_trip)) 502 return -EINVAL; 503 504 switch (trip->type) { 505 case THERMAL_TRIP_PASSIVE: 506 t = tz->trips.passive.tc1 * (tz->temp_dk - 507 tz->last_temp_dk) + 508 tz->trips.passive.tc2 * (tz->temp_dk - 509 acpi_trip->temp_dk); 510 if (t > 0) 511 *trend = THERMAL_TREND_RAISING; 512 else if (t < 0) 513 *trend = THERMAL_TREND_DROPPING; 514 else 515 *trend = THERMAL_TREND_STABLE; 516 517 return 0; 518 519 case THERMAL_TRIP_ACTIVE: 520 t = acpi_thermal_temp(tz, tz->temp_dk); 521 if (t <= trip->temperature) 522 break; 523 524 *trend = THERMAL_TREND_RAISING; 525 526 return 0; 527 528 default: 529 break; 530 } 531 532 return -EINVAL; 533 } 534 535 static void acpi_thermal_zone_device_hot(struct thermal_zone_device *thermal) 536 { 537 struct acpi_thermal *tz = thermal_zone_device_priv(thermal); 538 539 acpi_bus_generate_netlink_event(tz->device->pnp.device_class, 540 dev_name(&tz->device->dev), 541 ACPI_THERMAL_NOTIFY_HOT, 1); 542 } 543 544 static void acpi_thermal_zone_device_critical(struct thermal_zone_device *thermal) 545 { 546 struct acpi_thermal *tz = thermal_zone_device_priv(thermal); 547 548 acpi_bus_generate_netlink_event(tz->device->pnp.device_class, 549 dev_name(&tz->device->dev), 550 ACPI_THERMAL_NOTIFY_CRITICAL, 1); 551 552 thermal_zone_device_critical(thermal); 553 } 554 555 struct acpi_thermal_bind_data { 556 struct thermal_zone_device *thermal; 557 struct thermal_cooling_device *cdev; 558 bool bind; 559 }; 560 561 static int bind_unbind_cdev_cb(struct thermal_trip *trip, void *arg) 562 { 563 struct acpi_thermal_trip *acpi_trip = trip->priv; 564 struct acpi_thermal_bind_data *bd = arg; 565 struct thermal_zone_device *thermal = bd->thermal; 566 struct thermal_cooling_device *cdev = bd->cdev; 567 struct acpi_device *cdev_adev = cdev->devdata; 568 int i; 569 570 /* Skip critical and hot trips. */ 571 if (!acpi_trip) 572 return 0; 573 574 for (i = 0; i < acpi_trip->devices.count; i++) { 575 acpi_handle handle = acpi_trip->devices.handles[i]; 576 struct acpi_device *adev = acpi_fetch_acpi_dev(handle); 577 578 if (adev != cdev_adev) 579 continue; 580 581 if (bd->bind) { 582 int ret; 583 584 ret = thermal_bind_cdev_to_trip(thermal, trip, cdev, 585 THERMAL_NO_LIMIT, 586 THERMAL_NO_LIMIT, 587 THERMAL_WEIGHT_DEFAULT); 588 if (ret) 589 return ret; 590 } else { 591 thermal_unbind_cdev_from_trip(thermal, trip, cdev); 592 } 593 } 594 595 return 0; 596 } 597 598 static int acpi_thermal_bind_unbind_cdev(struct thermal_zone_device *thermal, 599 struct thermal_cooling_device *cdev, 600 bool bind) 601 { 602 struct acpi_thermal_bind_data bd = { 603 .thermal = thermal, .cdev = cdev, .bind = bind 604 }; 605 606 return for_each_thermal_trip(thermal, bind_unbind_cdev_cb, &bd); 607 } 608 609 static int 610 acpi_thermal_bind_cooling_device(struct thermal_zone_device *thermal, 611 struct thermal_cooling_device *cdev) 612 { 613 return acpi_thermal_bind_unbind_cdev(thermal, cdev, true); 614 } 615 616 static int 617 acpi_thermal_unbind_cooling_device(struct thermal_zone_device *thermal, 618 struct thermal_cooling_device *cdev) 619 { 620 return acpi_thermal_bind_unbind_cdev(thermal, cdev, false); 621 } 622 623 static const struct thermal_zone_device_ops acpi_thermal_zone_ops = { 624 .bind = acpi_thermal_bind_cooling_device, 625 .unbind = acpi_thermal_unbind_cooling_device, 626 .get_temp = thermal_get_temp, 627 .get_trend = thermal_get_trend, 628 .hot = acpi_thermal_zone_device_hot, 629 .critical = acpi_thermal_zone_device_critical, 630 }; 631 632 static int acpi_thermal_zone_sysfs_add(struct acpi_thermal *tz) 633 { 634 struct device *tzdev = thermal_zone_device(tz->thermal_zone); 635 int ret; 636 637 ret = sysfs_create_link(&tz->device->dev.kobj, 638 &tzdev->kobj, "thermal_zone"); 639 if (ret) 640 return ret; 641 642 ret = sysfs_create_link(&tzdev->kobj, 643 &tz->device->dev.kobj, "device"); 644 if (ret) 645 sysfs_remove_link(&tz->device->dev.kobj, "thermal_zone"); 646 647 return ret; 648 } 649 650 static void acpi_thermal_zone_sysfs_remove(struct acpi_thermal *tz) 651 { 652 struct device *tzdev = thermal_zone_device(tz->thermal_zone); 653 654 sysfs_remove_link(&tz->device->dev.kobj, "thermal_zone"); 655 sysfs_remove_link(&tzdev->kobj, "device"); 656 } 657 658 static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz, 659 const struct thermal_trip *trip_table, 660 unsigned int trip_count, 661 int passive_delay) 662 { 663 int result; 664 665 if (trip_count) 666 tz->thermal_zone = thermal_zone_device_register_with_trips( 667 "acpitz", trip_table, trip_count, tz, 668 &acpi_thermal_zone_ops, NULL, passive_delay, 669 tz->polling_frequency * 100); 670 else 671 tz->thermal_zone = thermal_tripless_zone_device_register( 672 "acpitz", tz, &acpi_thermal_zone_ops, NULL); 673 674 if (IS_ERR(tz->thermal_zone)) 675 return PTR_ERR(tz->thermal_zone); 676 677 result = acpi_thermal_zone_sysfs_add(tz); 678 if (result) 679 goto unregister_tzd; 680 681 result = thermal_zone_device_enable(tz->thermal_zone); 682 if (result) 683 goto remove_links; 684 685 dev_info(&tz->device->dev, "registered as thermal_zone%d\n", 686 thermal_zone_device_id(tz->thermal_zone)); 687 688 return 0; 689 690 remove_links: 691 acpi_thermal_zone_sysfs_remove(tz); 692 unregister_tzd: 693 thermal_zone_device_unregister(tz->thermal_zone); 694 695 return result; 696 } 697 698 static void acpi_thermal_unregister_thermal_zone(struct acpi_thermal *tz) 699 { 700 thermal_zone_device_disable(tz->thermal_zone); 701 acpi_thermal_zone_sysfs_remove(tz); 702 thermal_zone_device_unregister(tz->thermal_zone); 703 tz->thermal_zone = NULL; 704 } 705 706 707 /* -------------------------------------------------------------------------- 708 Driver Interface 709 -------------------------------------------------------------------------- */ 710 711 static void acpi_thermal_notify(acpi_handle handle, u32 event, void *data) 712 { 713 struct acpi_device *device = data; 714 struct acpi_thermal *tz = acpi_driver_data(device); 715 716 if (!tz) 717 return; 718 719 switch (event) { 720 case ACPI_THERMAL_NOTIFY_TEMPERATURE: 721 acpi_queue_thermal_check(tz); 722 break; 723 case ACPI_THERMAL_NOTIFY_THRESHOLDS: 724 case ACPI_THERMAL_NOTIFY_DEVICES: 725 acpi_thermal_trips_update(tz, event); 726 break; 727 default: 728 acpi_handle_debug(device->handle, "Unsupported event [0x%x]\n", 729 event); 730 break; 731 } 732 } 733 734 /* 735 * On some platforms, the AML code has dependency about 736 * the evaluating order of _TMP and _CRT/_HOT/_PSV/_ACx. 737 * 1. On HP Pavilion G4-1016tx, _TMP must be invoked after 738 * /_CRT/_HOT/_PSV/_ACx, or else system will be power off. 739 * 2. On HP Compaq 6715b/6715s, the return value of _PSV is 0 740 * if _TMP has never been evaluated. 741 * 742 * As this dependency is totally transparent to OS, evaluate 743 * all of them once, in the order of _CRT/_HOT/_PSV/_ACx, 744 * _TMP, before they are actually used. 745 */ 746 static void acpi_thermal_aml_dependency_fix(struct acpi_thermal *tz) 747 { 748 acpi_handle handle = tz->device->handle; 749 unsigned long long value; 750 int i; 751 752 acpi_evaluate_integer(handle, "_CRT", NULL, &value); 753 acpi_evaluate_integer(handle, "_HOT", NULL, &value); 754 acpi_evaluate_integer(handle, "_PSV", NULL, &value); 755 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { 756 char name[5] = { '_', 'A', 'C', ('0' + i), '\0' }; 757 acpi_status status; 758 759 status = acpi_evaluate_integer(handle, name, NULL, &value); 760 if (status == AE_NOT_FOUND) 761 break; 762 } 763 acpi_evaluate_integer(handle, "_TMP", NULL, &value); 764 } 765 766 /* 767 * The exact offset between Kelvin and degree Celsius is 273.15. However ACPI 768 * handles temperature values with a single decimal place. As a consequence, 769 * some implementations use an offset of 273.1 and others use an offset of 770 * 273.2. Try to find out which one is being used, to present the most 771 * accurate and visually appealing number. 772 * 773 * The heuristic below should work for all ACPI thermal zones which have a 774 * critical trip point with a value being a multiple of 0.5 degree Celsius. 775 */ 776 static void acpi_thermal_guess_offset(struct acpi_thermal *tz, long crit_temp) 777 { 778 if (crit_temp != THERMAL_TEMP_INVALID && crit_temp % 5 == 1) 779 tz->kelvin_offset = 273100; 780 else 781 tz->kelvin_offset = 273200; 782 } 783 784 static void acpi_thermal_check_fn(struct work_struct *work) 785 { 786 struct acpi_thermal *tz = container_of(work, struct acpi_thermal, 787 thermal_check_work); 788 789 /* 790 * In general, it is not sufficient to check the pending bit, because 791 * subsequent instances of this function may be queued after one of them 792 * has started running (e.g. if _TMP sleeps). Avoid bailing out if just 793 * one of them is running, though, because it may have done the actual 794 * check some time ago, so allow at least one of them to block on the 795 * mutex while another one is running the update. 796 */ 797 if (!refcount_dec_not_one(&tz->thermal_check_count)) 798 return; 799 800 mutex_lock(&tz->thermal_check_lock); 801 802 thermal_zone_device_update(tz->thermal_zone, THERMAL_EVENT_UNSPECIFIED); 803 804 refcount_inc(&tz->thermal_check_count); 805 806 mutex_unlock(&tz->thermal_check_lock); 807 } 808 809 static void acpi_thermal_free_thermal_zone(struct acpi_thermal *tz) 810 { 811 int i; 812 813 acpi_handle_list_free(&tz->trips.passive.trip.devices); 814 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) 815 acpi_handle_list_free(&tz->trips.active[i].trip.devices); 816 817 kfree(tz); 818 } 819 820 static int acpi_thermal_add(struct acpi_device *device) 821 { 822 struct thermal_trip trip_table[ACPI_THERMAL_MAX_NR_TRIPS] = { 0 }; 823 struct acpi_thermal_trip *acpi_trip; 824 struct thermal_trip *trip; 825 struct acpi_thermal *tz; 826 int crit_temp, hot_temp; 827 int passive_delay = 0; 828 int result; 829 int i; 830 831 if (!device) 832 return -EINVAL; 833 834 tz = kzalloc(sizeof(struct acpi_thermal), GFP_KERNEL); 835 if (!tz) 836 return -ENOMEM; 837 838 tz->device = device; 839 strcpy(tz->name, device->pnp.bus_id); 840 strcpy(acpi_device_name(device), ACPI_THERMAL_DEVICE_NAME); 841 strcpy(acpi_device_class(device), ACPI_THERMAL_CLASS); 842 device->driver_data = tz; 843 844 acpi_thermal_aml_dependency_fix(tz); 845 846 /* Get trip points [_CRT, _PSV, etc.] (required). */ 847 acpi_thermal_get_trip_points(tz); 848 849 crit_temp = acpi_thermal_get_critical_trip(tz); 850 hot_temp = acpi_thermal_get_hot_trip(tz); 851 852 /* Get temperature [_TMP] (required). */ 853 result = acpi_thermal_get_temperature(tz); 854 if (result) 855 goto free_memory; 856 857 /* Set the cooling mode [_SCP] to active cooling. */ 858 acpi_execute_simple_method(tz->device->handle, "_SCP", 859 ACPI_THERMAL_MODE_ACTIVE); 860 861 /* Determine the default polling frequency [_TZP]. */ 862 if (tzp) 863 tz->polling_frequency = tzp; 864 else 865 acpi_thermal_get_polling_frequency(tz); 866 867 acpi_thermal_guess_offset(tz, crit_temp); 868 869 trip = trip_table; 870 871 if (crit_temp != THERMAL_TEMP_INVALID) { 872 trip->type = THERMAL_TRIP_CRITICAL; 873 trip->temperature = acpi_thermal_temp(tz, crit_temp); 874 trip++; 875 } 876 877 if (hot_temp != THERMAL_TEMP_INVALID) { 878 trip->type = THERMAL_TRIP_HOT; 879 trip->temperature = acpi_thermal_temp(tz, hot_temp); 880 trip++; 881 } 882 883 acpi_trip = &tz->trips.passive.trip; 884 if (acpi_thermal_trip_valid(acpi_trip)) { 885 passive_delay = tz->trips.passive.delay; 886 887 trip->type = THERMAL_TRIP_PASSIVE; 888 trip->temperature = acpi_thermal_temp(tz, acpi_trip->temp_dk); 889 trip->priv = acpi_trip; 890 trip++; 891 } 892 893 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { 894 acpi_trip = &tz->trips.active[i].trip; 895 896 if (!acpi_thermal_trip_valid(acpi_trip)) 897 break; 898 899 trip->type = THERMAL_TRIP_ACTIVE; 900 trip->temperature = acpi_thermal_temp(tz, acpi_trip->temp_dk); 901 trip->priv = acpi_trip; 902 trip++; 903 } 904 905 if (trip == trip_table) 906 pr_warn(FW_BUG "No valid trip points!\n"); 907 908 result = acpi_thermal_register_thermal_zone(tz, trip_table, 909 trip - trip_table, 910 passive_delay); 911 if (result) 912 goto free_memory; 913 914 refcount_set(&tz->thermal_check_count, 3); 915 mutex_init(&tz->thermal_check_lock); 916 INIT_WORK(&tz->thermal_check_work, acpi_thermal_check_fn); 917 918 pr_info("%s [%s] (%ld C)\n", acpi_device_name(device), 919 acpi_device_bid(device), deci_kelvin_to_celsius(tz->temp_dk)); 920 921 result = acpi_dev_install_notify_handler(device, ACPI_DEVICE_NOTIFY, 922 acpi_thermal_notify, device); 923 if (result) 924 goto flush_wq; 925 926 return 0; 927 928 flush_wq: 929 flush_workqueue(acpi_thermal_pm_queue); 930 acpi_thermal_unregister_thermal_zone(tz); 931 free_memory: 932 acpi_thermal_free_thermal_zone(tz); 933 934 return result; 935 } 936 937 static void acpi_thermal_remove(struct acpi_device *device) 938 { 939 struct acpi_thermal *tz; 940 941 if (!device || !acpi_driver_data(device)) 942 return; 943 944 tz = acpi_driver_data(device); 945 946 acpi_dev_remove_notify_handler(device, ACPI_DEVICE_NOTIFY, 947 acpi_thermal_notify); 948 949 flush_workqueue(acpi_thermal_pm_queue); 950 acpi_thermal_unregister_thermal_zone(tz); 951 acpi_thermal_free_thermal_zone(tz); 952 } 953 954 #ifdef CONFIG_PM_SLEEP 955 static int acpi_thermal_suspend(struct device *dev) 956 { 957 /* Make sure the previously queued thermal check work has been done */ 958 flush_workqueue(acpi_thermal_pm_queue); 959 return 0; 960 } 961 962 static int acpi_thermal_resume(struct device *dev) 963 { 964 struct acpi_thermal *tz; 965 int i, j, power_state; 966 967 if (!dev) 968 return -EINVAL; 969 970 tz = acpi_driver_data(to_acpi_device(dev)); 971 if (!tz) 972 return -EINVAL; 973 974 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { 975 struct acpi_thermal_trip *acpi_trip = &tz->trips.active[i].trip; 976 977 if (!acpi_thermal_trip_valid(acpi_trip)) 978 break; 979 980 for (j = 0; j < acpi_trip->devices.count; j++) { 981 acpi_bus_update_power(acpi_trip->devices.handles[j], 982 &power_state); 983 } 984 } 985 986 acpi_queue_thermal_check(tz); 987 988 return AE_OK; 989 } 990 #else 991 #define acpi_thermal_suspend NULL 992 #define acpi_thermal_resume NULL 993 #endif 994 static SIMPLE_DEV_PM_OPS(acpi_thermal_pm, acpi_thermal_suspend, acpi_thermal_resume); 995 996 static const struct acpi_device_id thermal_device_ids[] = { 997 {ACPI_THERMAL_HID, 0}, 998 {"", 0}, 999 }; 1000 MODULE_DEVICE_TABLE(acpi, thermal_device_ids); 1001 1002 static struct acpi_driver acpi_thermal_driver = { 1003 .name = "thermal", 1004 .class = ACPI_THERMAL_CLASS, 1005 .ids = thermal_device_ids, 1006 .ops = { 1007 .add = acpi_thermal_add, 1008 .remove = acpi_thermal_remove, 1009 }, 1010 .drv.pm = &acpi_thermal_pm, 1011 }; 1012 1013 static int thermal_act(const struct dmi_system_id *d) 1014 { 1015 if (act == 0) { 1016 pr_notice("%s detected: disabling all active thermal trip points\n", 1017 d->ident); 1018 act = -1; 1019 } 1020 return 0; 1021 } 1022 1023 static int thermal_nocrt(const struct dmi_system_id *d) 1024 { 1025 pr_notice("%s detected: disabling all critical thermal trip point actions.\n", 1026 d->ident); 1027 crt = -1; 1028 return 0; 1029 } 1030 1031 static int thermal_tzp(const struct dmi_system_id *d) 1032 { 1033 if (tzp == 0) { 1034 pr_notice("%s detected: enabling thermal zone polling\n", 1035 d->ident); 1036 tzp = 300; /* 300 dS = 30 Seconds */ 1037 } 1038 return 0; 1039 } 1040 1041 static int thermal_psv(const struct dmi_system_id *d) 1042 { 1043 if (psv == 0) { 1044 pr_notice("%s detected: disabling all passive thermal trip points\n", 1045 d->ident); 1046 psv = -1; 1047 } 1048 return 0; 1049 } 1050 1051 static const struct dmi_system_id thermal_dmi_table[] __initconst = { 1052 /* 1053 * Award BIOS on this AOpen makes thermal control almost worthless. 1054 * http://bugzilla.kernel.org/show_bug.cgi?id=8842 1055 */ 1056 { 1057 .callback = thermal_act, 1058 .ident = "AOpen i915GMm-HFS", 1059 .matches = { 1060 DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"), 1061 DMI_MATCH(DMI_BOARD_NAME, "i915GMm-HFS"), 1062 }, 1063 }, 1064 { 1065 .callback = thermal_psv, 1066 .ident = "AOpen i915GMm-HFS", 1067 .matches = { 1068 DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"), 1069 DMI_MATCH(DMI_BOARD_NAME, "i915GMm-HFS"), 1070 }, 1071 }, 1072 { 1073 .callback = thermal_tzp, 1074 .ident = "AOpen i915GMm-HFS", 1075 .matches = { 1076 DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"), 1077 DMI_MATCH(DMI_BOARD_NAME, "i915GMm-HFS"), 1078 }, 1079 }, 1080 { 1081 .callback = thermal_nocrt, 1082 .ident = "Gigabyte GA-7ZX", 1083 .matches = { 1084 DMI_MATCH(DMI_BOARD_VENDOR, "Gigabyte Technology Co., Ltd."), 1085 DMI_MATCH(DMI_BOARD_NAME, "7ZX"), 1086 }, 1087 }, 1088 {} 1089 }; 1090 1091 static int __init acpi_thermal_init(void) 1092 { 1093 int result; 1094 1095 dmi_check_system(thermal_dmi_table); 1096 1097 if (off) { 1098 pr_notice("thermal control disabled\n"); 1099 return -ENODEV; 1100 } 1101 1102 acpi_thermal_pm_queue = alloc_workqueue("acpi_thermal_pm", 1103 WQ_HIGHPRI | WQ_MEM_RECLAIM, 0); 1104 if (!acpi_thermal_pm_queue) 1105 return -ENODEV; 1106 1107 result = acpi_bus_register_driver(&acpi_thermal_driver); 1108 if (result < 0) { 1109 destroy_workqueue(acpi_thermal_pm_queue); 1110 return -ENODEV; 1111 } 1112 1113 return 0; 1114 } 1115 1116 static void __exit acpi_thermal_exit(void) 1117 { 1118 acpi_bus_unregister_driver(&acpi_thermal_driver); 1119 destroy_workqueue(acpi_thermal_pm_queue); 1120 } 1121 1122 module_init(acpi_thermal_init); 1123 module_exit(acpi_thermal_exit); 1124 1125 MODULE_IMPORT_NS(ACPI_THERMAL); 1126 MODULE_AUTHOR("Paul Diefenbaugh"); 1127 MODULE_DESCRIPTION("ACPI Thermal Zone Driver"); 1128 MODULE_LICENSE("GPL"); 1129