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 #define ACPI_THERMAL_CLASS "thermal_zone" 35 #define ACPI_THERMAL_DEVICE_NAME "Thermal Zone" 36 #define ACPI_THERMAL_NOTIFY_TEMPERATURE 0x80 37 #define ACPI_THERMAL_NOTIFY_THRESHOLDS 0x81 38 #define ACPI_THERMAL_NOTIFY_DEVICES 0x82 39 #define ACPI_THERMAL_NOTIFY_CRITICAL 0xF0 40 #define ACPI_THERMAL_NOTIFY_HOT 0xF1 41 #define ACPI_THERMAL_MODE_ACTIVE 0x00 42 43 #define ACPI_THERMAL_MAX_ACTIVE 10 44 #define ACPI_THERMAL_MAX_LIMIT_STR_LEN 65 45 46 #define ACPI_THERMAL_TRIP_PASSIVE (-1) 47 48 /* 49 * This exception is thrown out in two cases: 50 * 1.An invalid trip point becomes invalid or a valid trip point becomes invalid 51 * when re-evaluating the AML code. 52 * 2.TODO: Devices listed in _PSL, _ALx, _TZD may change. 53 * We need to re-bind the cooling devices of a thermal zone when this occurs. 54 */ 55 #define ACPI_THERMAL_TRIPS_EXCEPTION(tz, str) \ 56 do { \ 57 acpi_handle_info(tz->device->handle, \ 58 "ACPI thermal trip point %s changed\n" \ 59 "Please report to linux-acpi@vger.kernel.org\n", str); \ 60 } while (0) 61 62 static int act; 63 module_param(act, int, 0644); 64 MODULE_PARM_DESC(act, "Disable or override all lowest active trip points."); 65 66 static int crt; 67 module_param(crt, int, 0644); 68 MODULE_PARM_DESC(crt, "Disable or lower all critical trip points."); 69 70 static int tzp; 71 module_param(tzp, int, 0444); 72 MODULE_PARM_DESC(tzp, "Thermal zone polling frequency, in 1/10 seconds."); 73 74 static int off; 75 module_param(off, int, 0); 76 MODULE_PARM_DESC(off, "Set to disable ACPI thermal support."); 77 78 static int psv; 79 module_param(psv, int, 0644); 80 MODULE_PARM_DESC(psv, "Disable or override all passive trip points."); 81 82 static struct workqueue_struct *acpi_thermal_pm_queue; 83 84 struct acpi_thermal_trip { 85 unsigned long temp_dk; 86 struct acpi_handle_list devices; 87 }; 88 89 struct acpi_thermal_passive { 90 struct acpi_thermal_trip trip; 91 unsigned long tc1; 92 unsigned long tc2; 93 unsigned long tsp; 94 }; 95 96 struct acpi_thermal_active { 97 struct acpi_thermal_trip trip; 98 }; 99 100 struct acpi_thermal_trips { 101 struct acpi_thermal_passive passive; 102 struct acpi_thermal_active active[ACPI_THERMAL_MAX_ACTIVE]; 103 }; 104 105 struct acpi_thermal { 106 struct acpi_device *device; 107 acpi_bus_id name; 108 unsigned long temp_dk; 109 unsigned long last_temp_dk; 110 unsigned long polling_frequency; 111 volatile u8 zombie; 112 struct acpi_thermal_trips trips; 113 struct thermal_trip *trip_table; 114 struct thermal_zone_device *thermal_zone; 115 int kelvin_offset; /* in millidegrees */ 116 struct work_struct thermal_check_work; 117 struct mutex thermal_check_lock; 118 refcount_t thermal_check_count; 119 }; 120 121 /* -------------------------------------------------------------------------- 122 Thermal Zone Management 123 -------------------------------------------------------------------------- */ 124 125 static int acpi_thermal_get_temperature(struct acpi_thermal *tz) 126 { 127 acpi_status status = AE_OK; 128 unsigned long long tmp; 129 130 if (!tz) 131 return -EINVAL; 132 133 tz->last_temp_dk = tz->temp_dk; 134 135 status = acpi_evaluate_integer(tz->device->handle, "_TMP", NULL, &tmp); 136 if (ACPI_FAILURE(status)) 137 return -ENODEV; 138 139 tz->temp_dk = tmp; 140 141 acpi_handle_debug(tz->device->handle, "Temperature is %lu dK\n", 142 tz->temp_dk); 143 144 return 0; 145 } 146 147 static int acpi_thermal_get_polling_frequency(struct acpi_thermal *tz) 148 { 149 acpi_status status = AE_OK; 150 unsigned long long tmp; 151 152 if (!tz) 153 return -EINVAL; 154 155 status = acpi_evaluate_integer(tz->device->handle, "_TZP", NULL, &tmp); 156 if (ACPI_FAILURE(status)) 157 return -ENODEV; 158 159 tz->polling_frequency = tmp; 160 acpi_handle_debug(tz->device->handle, "Polling frequency is %lu dS\n", 161 tz->polling_frequency); 162 163 return 0; 164 } 165 166 static int acpi_thermal_temp(struct acpi_thermal *tz, int temp_deci_k) 167 { 168 if (temp_deci_k == THERMAL_TEMP_INVALID) 169 return THERMAL_TEMP_INVALID; 170 171 return deci_kelvin_to_millicelsius_with_offset(temp_deci_k, 172 tz->kelvin_offset); 173 } 174 175 static bool acpi_thermal_trip_valid(struct acpi_thermal_trip *acpi_trip) 176 { 177 return acpi_trip->temp_dk != THERMAL_TEMP_INVALID; 178 } 179 180 static int active_trip_index(struct acpi_thermal *tz, 181 struct acpi_thermal_trip *acpi_trip) 182 { 183 struct acpi_thermal_active *active; 184 185 active = container_of(acpi_trip, struct acpi_thermal_active, trip); 186 return active - tz->trips.active; 187 } 188 189 static long get_passive_temp(struct acpi_thermal *tz) 190 { 191 unsigned long long tmp; 192 acpi_status status; 193 194 status = acpi_evaluate_integer(tz->device->handle, "_PSV", NULL, &tmp); 195 if (ACPI_FAILURE(status)) 196 return THERMAL_TEMP_INVALID; 197 198 return tmp; 199 } 200 201 static long get_active_temp(struct acpi_thermal *tz, int index) 202 { 203 char method[] = { '_', 'A', 'C', '0' + index, '\0' }; 204 unsigned long long tmp; 205 acpi_status status; 206 207 status = acpi_evaluate_integer(tz->device->handle, method, NULL, &tmp); 208 if (ACPI_FAILURE(status)) 209 return THERMAL_TEMP_INVALID; 210 211 /* 212 * If an override has been provided, apply it so there are no active 213 * trips with thresholds greater than the override. 214 */ 215 if (act > 0) { 216 unsigned long long override = celsius_to_deci_kelvin(act); 217 218 if (tmp > override) 219 tmp = override; 220 } 221 return tmp; 222 } 223 224 static void acpi_thermal_update_trip(struct acpi_thermal *tz, 225 const struct thermal_trip *trip) 226 { 227 struct acpi_thermal_trip *acpi_trip = trip->priv; 228 229 if (trip->type == THERMAL_TRIP_PASSIVE) { 230 if (psv > 0) 231 return; 232 233 acpi_trip->temp_dk = get_passive_temp(tz); 234 } else { 235 int index = active_trip_index(tz, acpi_trip); 236 237 acpi_trip->temp_dk = get_active_temp(tz, index); 238 } 239 240 if (!acpi_thermal_trip_valid(acpi_trip)) 241 ACPI_THERMAL_TRIPS_EXCEPTION(tz, "state"); 242 } 243 244 static bool update_trip_devices(struct acpi_thermal *tz, 245 struct acpi_thermal_trip *acpi_trip, 246 int index, bool compare) 247 { 248 struct acpi_handle_list devices = { 0 }; 249 char method[] = "_PSL"; 250 acpi_status status; 251 252 if (index != ACPI_THERMAL_TRIP_PASSIVE) { 253 method[1] = 'A'; 254 method[2] = 'L'; 255 method[3] = '0' + index; 256 } 257 258 status = acpi_evaluate_reference(tz->device->handle, method, NULL, &devices); 259 if (ACPI_FAILURE(status)) { 260 acpi_handle_info(tz->device->handle, "%s evaluation failure\n", method); 261 return false; 262 } 263 264 if (acpi_handle_list_equal(&acpi_trip->devices, &devices)) { 265 acpi_handle_list_free(&devices); 266 return true; 267 } 268 269 if (compare) 270 ACPI_THERMAL_TRIPS_EXCEPTION(tz, "device"); 271 272 acpi_handle_list_replace(&acpi_trip->devices, &devices); 273 return true; 274 } 275 276 static void acpi_thermal_update_trip_devices(struct acpi_thermal *tz, 277 const struct thermal_trip *trip) 278 { 279 struct acpi_thermal_trip *acpi_trip = trip->priv; 280 int index = trip->type == THERMAL_TRIP_PASSIVE ? 281 ACPI_THERMAL_TRIP_PASSIVE : active_trip_index(tz, acpi_trip); 282 283 if (update_trip_devices(tz, acpi_trip, index, true)) 284 return; 285 286 acpi_trip->temp_dk = THERMAL_TEMP_INVALID; 287 ACPI_THERMAL_TRIPS_EXCEPTION(tz, "state"); 288 } 289 290 struct adjust_trip_data { 291 struct acpi_thermal *tz; 292 u32 event; 293 }; 294 295 static int acpi_thermal_adjust_trip(struct thermal_trip *trip, void *data) 296 { 297 struct acpi_thermal_trip *acpi_trip = trip->priv; 298 struct adjust_trip_data *atd = data; 299 struct acpi_thermal *tz = atd->tz; 300 301 if (!acpi_trip || !acpi_thermal_trip_valid(acpi_trip)) 302 return 0; 303 304 if (atd->event == ACPI_THERMAL_NOTIFY_THRESHOLDS) 305 acpi_thermal_update_trip(tz, trip); 306 else 307 acpi_thermal_update_trip_devices(tz, trip); 308 309 if (acpi_thermal_trip_valid(acpi_trip)) 310 trip->temperature = acpi_thermal_temp(tz, acpi_trip->temp_dk); 311 else 312 trip->temperature = THERMAL_TEMP_INVALID; 313 314 return 0; 315 } 316 317 static void acpi_queue_thermal_check(struct acpi_thermal *tz) 318 { 319 if (!work_pending(&tz->thermal_check_work)) 320 queue_work(acpi_thermal_pm_queue, &tz->thermal_check_work); 321 } 322 323 static void acpi_thermal_trips_update(struct acpi_thermal *tz, u32 event) 324 { 325 struct adjust_trip_data atd = { .tz = tz, .event = event }; 326 struct acpi_device *adev = tz->device; 327 328 /* 329 * Use thermal_zone_for_each_trip() to carry out the trip points 330 * update, so as to protect thermal_get_trend() from getting stale 331 * trip point temperatures and to prevent thermal_zone_device_update() 332 * invoked from acpi_thermal_check_fn() from producing inconsistent 333 * results. 334 */ 335 thermal_zone_for_each_trip(tz->thermal_zone, 336 acpi_thermal_adjust_trip, &atd); 337 acpi_queue_thermal_check(tz); 338 acpi_bus_generate_netlink_event(adev->pnp.device_class, 339 dev_name(&adev->dev), event, 0); 340 } 341 342 static long acpi_thermal_get_critical_trip(struct acpi_thermal *tz) 343 { 344 unsigned long long tmp; 345 acpi_status status; 346 347 if (crt > 0) { 348 tmp = celsius_to_deci_kelvin(crt); 349 goto set; 350 } 351 if (crt == -1) { 352 acpi_handle_debug(tz->device->handle, "Critical threshold disabled\n"); 353 return THERMAL_TEMP_INVALID; 354 } 355 356 status = acpi_evaluate_integer(tz->device->handle, "_CRT", NULL, &tmp); 357 if (ACPI_FAILURE(status)) { 358 acpi_handle_debug(tz->device->handle, "No critical threshold\n"); 359 return THERMAL_TEMP_INVALID; 360 } 361 if (tmp <= 2732) { 362 /* 363 * Below zero (Celsius) values clearly aren't right for sure, 364 * so discard them as invalid. 365 */ 366 pr_info(FW_BUG "Invalid critical threshold (%llu)\n", tmp); 367 return THERMAL_TEMP_INVALID; 368 } 369 370 set: 371 acpi_handle_debug(tz->device->handle, "Critical threshold [%llu]\n", tmp); 372 return tmp; 373 } 374 375 static long acpi_thermal_get_hot_trip(struct acpi_thermal *tz) 376 { 377 unsigned long long tmp; 378 acpi_status status; 379 380 status = acpi_evaluate_integer(tz->device->handle, "_HOT", NULL, &tmp); 381 if (ACPI_FAILURE(status)) { 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 [%llu]\n", tmp); 387 return tmp; 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, "_TSP", NULL, &tmp); 408 if (ACPI_FAILURE(status)) 409 return false; 410 411 tz->trips.passive.tsp = tmp; 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 int acpi_thermal_get_trip_points(struct acpi_thermal *tz) 456 { 457 unsigned int count = 0; 458 int i; 459 460 if (acpi_thermal_init_trip(tz, ACPI_THERMAL_TRIP_PASSIVE)) 461 count++; 462 463 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { 464 if (acpi_thermal_init_trip(tz, i)) 465 count++; 466 else 467 break; 468 469 } 470 471 while (++i < ACPI_THERMAL_MAX_ACTIVE) 472 tz->trips.active[i].trip.temp_dk = THERMAL_TEMP_INVALID; 473 474 return count; 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 struct acpi_thermal_bind_data { 563 struct thermal_zone_device *thermal; 564 struct thermal_cooling_device *cdev; 565 bool bind; 566 }; 567 568 static int bind_unbind_cdev_cb(struct thermal_trip *trip, void *arg) 569 { 570 struct acpi_thermal_trip *acpi_trip = trip->priv; 571 struct acpi_thermal_bind_data *bd = arg; 572 struct thermal_zone_device *thermal = bd->thermal; 573 struct thermal_cooling_device *cdev = bd->cdev; 574 struct acpi_device *cdev_adev = cdev->devdata; 575 int i; 576 577 /* Skip critical and hot trips. */ 578 if (!acpi_trip) 579 return 0; 580 581 for (i = 0; i < acpi_trip->devices.count; i++) { 582 acpi_handle handle = acpi_trip->devices.handles[i]; 583 struct acpi_device *adev = acpi_fetch_acpi_dev(handle); 584 585 if (adev != cdev_adev) 586 continue; 587 588 if (bd->bind) { 589 int ret; 590 591 ret = thermal_bind_cdev_to_trip(thermal, trip, cdev, 592 THERMAL_NO_LIMIT, 593 THERMAL_NO_LIMIT, 594 THERMAL_WEIGHT_DEFAULT); 595 if (ret) 596 return ret; 597 } else { 598 thermal_unbind_cdev_from_trip(thermal, trip, cdev); 599 } 600 } 601 602 return 0; 603 } 604 605 static int acpi_thermal_bind_unbind_cdev(struct thermal_zone_device *thermal, 606 struct thermal_cooling_device *cdev, 607 bool bind) 608 { 609 struct acpi_thermal_bind_data bd = { 610 .thermal = thermal, .cdev = cdev, .bind = bind 611 }; 612 613 return for_each_thermal_trip(thermal, bind_unbind_cdev_cb, &bd); 614 } 615 616 static int 617 acpi_thermal_bind_cooling_device(struct thermal_zone_device *thermal, 618 struct thermal_cooling_device *cdev) 619 { 620 return acpi_thermal_bind_unbind_cdev(thermal, cdev, true); 621 } 622 623 static int 624 acpi_thermal_unbind_cooling_device(struct thermal_zone_device *thermal, 625 struct thermal_cooling_device *cdev) 626 { 627 return acpi_thermal_bind_unbind_cdev(thermal, cdev, false); 628 } 629 630 static struct thermal_zone_device_ops acpi_thermal_zone_ops = { 631 .bind = acpi_thermal_bind_cooling_device, 632 .unbind = acpi_thermal_unbind_cooling_device, 633 .get_temp = thermal_get_temp, 634 .get_trend = thermal_get_trend, 635 .hot = acpi_thermal_zone_device_hot, 636 .critical = acpi_thermal_zone_device_critical, 637 }; 638 639 static int acpi_thermal_zone_sysfs_add(struct acpi_thermal *tz) 640 { 641 struct device *tzdev = thermal_zone_device(tz->thermal_zone); 642 int ret; 643 644 ret = sysfs_create_link(&tz->device->dev.kobj, 645 &tzdev->kobj, "thermal_zone"); 646 if (ret) 647 return ret; 648 649 ret = sysfs_create_link(&tzdev->kobj, 650 &tz->device->dev.kobj, "device"); 651 if (ret) 652 sysfs_remove_link(&tz->device->dev.kobj, "thermal_zone"); 653 654 return ret; 655 } 656 657 static void acpi_thermal_zone_sysfs_remove(struct acpi_thermal *tz) 658 { 659 struct device *tzdev = thermal_zone_device(tz->thermal_zone); 660 661 sysfs_remove_link(&tz->device->dev.kobj, "thermal_zone"); 662 sysfs_remove_link(&tzdev->kobj, "device"); 663 } 664 665 static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz, 666 unsigned int trip_count, 667 int passive_delay) 668 { 669 int result; 670 671 tz->thermal_zone = thermal_zone_device_register_with_trips("acpitz", 672 tz->trip_table, 673 trip_count, 674 0, tz, 675 &acpi_thermal_zone_ops, 676 NULL, 677 passive_delay, 678 tz->polling_frequency * 100); 679 if (IS_ERR(tz->thermal_zone)) 680 return PTR_ERR(tz->thermal_zone); 681 682 result = acpi_thermal_zone_sysfs_add(tz); 683 if (result) 684 goto unregister_tzd; 685 686 result = thermal_zone_device_enable(tz->thermal_zone); 687 if (result) 688 goto remove_links; 689 690 dev_info(&tz->device->dev, "registered as thermal_zone%d\n", 691 thermal_zone_device_id(tz->thermal_zone)); 692 693 return 0; 694 695 remove_links: 696 acpi_thermal_zone_sysfs_remove(tz); 697 unregister_tzd: 698 thermal_zone_device_unregister(tz->thermal_zone); 699 700 return result; 701 } 702 703 static void acpi_thermal_unregister_thermal_zone(struct acpi_thermal *tz) 704 { 705 thermal_zone_device_disable(tz->thermal_zone); 706 acpi_thermal_zone_sysfs_remove(tz); 707 thermal_zone_device_unregister(tz->thermal_zone); 708 tz->thermal_zone = NULL; 709 } 710 711 712 /* -------------------------------------------------------------------------- 713 Driver Interface 714 -------------------------------------------------------------------------- */ 715 716 static void acpi_thermal_notify(acpi_handle handle, u32 event, void *data) 717 { 718 struct acpi_device *device = data; 719 struct acpi_thermal *tz = acpi_driver_data(device); 720 721 if (!tz) 722 return; 723 724 switch (event) { 725 case ACPI_THERMAL_NOTIFY_TEMPERATURE: 726 acpi_queue_thermal_check(tz); 727 break; 728 case ACPI_THERMAL_NOTIFY_THRESHOLDS: 729 case ACPI_THERMAL_NOTIFY_DEVICES: 730 acpi_thermal_trips_update(tz, event); 731 break; 732 default: 733 acpi_handle_debug(device->handle, "Unsupported event [0x%x]\n", 734 event); 735 break; 736 } 737 } 738 739 /* 740 * On some platforms, the AML code has dependency about 741 * the evaluating order of _TMP and _CRT/_HOT/_PSV/_ACx. 742 * 1. On HP Pavilion G4-1016tx, _TMP must be invoked after 743 * /_CRT/_HOT/_PSV/_ACx, or else system will be power off. 744 * 2. On HP Compaq 6715b/6715s, the return value of _PSV is 0 745 * if _TMP has never been evaluated. 746 * 747 * As this dependency is totally transparent to OS, evaluate 748 * all of them once, in the order of _CRT/_HOT/_PSV/_ACx, 749 * _TMP, before they are actually used. 750 */ 751 static void acpi_thermal_aml_dependency_fix(struct acpi_thermal *tz) 752 { 753 acpi_handle handle = tz->device->handle; 754 unsigned long long value; 755 int i; 756 757 acpi_evaluate_integer(handle, "_CRT", NULL, &value); 758 acpi_evaluate_integer(handle, "_HOT", NULL, &value); 759 acpi_evaluate_integer(handle, "_PSV", NULL, &value); 760 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { 761 char name[5] = { '_', 'A', 'C', ('0' + i), '\0' }; 762 acpi_status status; 763 764 status = acpi_evaluate_integer(handle, name, NULL, &value); 765 if (status == AE_NOT_FOUND) 766 break; 767 } 768 acpi_evaluate_integer(handle, "_TMP", NULL, &value); 769 } 770 771 /* 772 * The exact offset between Kelvin and degree Celsius is 273.15. However ACPI 773 * handles temperature values with a single decimal place. As a consequence, 774 * some implementations use an offset of 273.1 and others use an offset of 775 * 273.2. Try to find out which one is being used, to present the most 776 * accurate and visually appealing number. 777 * 778 * The heuristic below should work for all ACPI thermal zones which have a 779 * critical trip point with a value being a multiple of 0.5 degree Celsius. 780 */ 781 static void acpi_thermal_guess_offset(struct acpi_thermal *tz, long crit_temp) 782 { 783 if (crit_temp != THERMAL_TEMP_INVALID && crit_temp % 5 == 1) 784 tz->kelvin_offset = 273100; 785 else 786 tz->kelvin_offset = 273200; 787 } 788 789 static void acpi_thermal_check_fn(struct work_struct *work) 790 { 791 struct acpi_thermal *tz = container_of(work, struct acpi_thermal, 792 thermal_check_work); 793 794 /* 795 * In general, it is not sufficient to check the pending bit, because 796 * subsequent instances of this function may be queued after one of them 797 * has started running (e.g. if _TMP sleeps). Avoid bailing out if just 798 * one of them is running, though, because it may have done the actual 799 * check some time ago, so allow at least one of them to block on the 800 * mutex while another one is running the update. 801 */ 802 if (!refcount_dec_not_one(&tz->thermal_check_count)) 803 return; 804 805 mutex_lock(&tz->thermal_check_lock); 806 807 thermal_zone_device_update(tz->thermal_zone, THERMAL_EVENT_UNSPECIFIED); 808 809 refcount_inc(&tz->thermal_check_count); 810 811 mutex_unlock(&tz->thermal_check_lock); 812 } 813 814 static void acpi_thermal_free_thermal_zone(struct acpi_thermal *tz) 815 { 816 int i; 817 818 acpi_handle_list_free(&tz->trips.passive.trip.devices); 819 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) 820 acpi_handle_list_free(&tz->trips.active[i].trip.devices); 821 822 kfree(tz); 823 } 824 825 static int acpi_thermal_add(struct acpi_device *device) 826 { 827 struct acpi_thermal_trip *acpi_trip; 828 struct thermal_trip *trip; 829 struct acpi_thermal *tz; 830 unsigned int trip_count; 831 int crit_temp, hot_temp; 832 int passive_delay = 0; 833 int result; 834 int i; 835 836 if (!device) 837 return -EINVAL; 838 839 tz = kzalloc(sizeof(struct acpi_thermal), GFP_KERNEL); 840 if (!tz) 841 return -ENOMEM; 842 843 tz->device = device; 844 strcpy(tz->name, device->pnp.bus_id); 845 strcpy(acpi_device_name(device), ACPI_THERMAL_DEVICE_NAME); 846 strcpy(acpi_device_class(device), ACPI_THERMAL_CLASS); 847 device->driver_data = tz; 848 849 acpi_thermal_aml_dependency_fix(tz); 850 851 /* Get trip points [_CRT, _PSV, etc.] (required). */ 852 trip_count = acpi_thermal_get_trip_points(tz); 853 854 crit_temp = acpi_thermal_get_critical_trip(tz); 855 if (crit_temp != THERMAL_TEMP_INVALID) 856 trip_count++; 857 858 hot_temp = acpi_thermal_get_hot_trip(tz); 859 if (hot_temp != THERMAL_TEMP_INVALID) 860 trip_count++; 861 862 if (!trip_count) { 863 pr_warn(FW_BUG "No valid trip points!\n"); 864 result = -ENODEV; 865 goto free_memory; 866 } 867 868 /* Get temperature [_TMP] (required). */ 869 result = acpi_thermal_get_temperature(tz); 870 if (result) 871 goto free_memory; 872 873 /* Set the cooling mode [_SCP] to active cooling. */ 874 acpi_execute_simple_method(tz->device->handle, "_SCP", 875 ACPI_THERMAL_MODE_ACTIVE); 876 877 /* Determine the default polling frequency [_TZP]. */ 878 if (tzp) 879 tz->polling_frequency = tzp; 880 else 881 acpi_thermal_get_polling_frequency(tz); 882 883 acpi_thermal_guess_offset(tz, crit_temp); 884 885 trip = kcalloc(trip_count, sizeof(*trip), GFP_KERNEL); 886 if (!trip) { 887 result = -ENOMEM; 888 goto free_memory; 889 } 890 891 tz->trip_table = trip; 892 893 if (crit_temp != THERMAL_TEMP_INVALID) { 894 trip->type = THERMAL_TRIP_CRITICAL; 895 trip->temperature = acpi_thermal_temp(tz, crit_temp); 896 trip++; 897 } 898 899 if (hot_temp != THERMAL_TEMP_INVALID) { 900 trip->type = THERMAL_TRIP_HOT; 901 trip->temperature = acpi_thermal_temp(tz, hot_temp); 902 trip++; 903 } 904 905 acpi_trip = &tz->trips.passive.trip; 906 if (acpi_thermal_trip_valid(acpi_trip)) { 907 passive_delay = tz->trips.passive.tsp * 100; 908 909 trip->type = THERMAL_TRIP_PASSIVE; 910 trip->temperature = acpi_thermal_temp(tz, acpi_trip->temp_dk); 911 trip->priv = acpi_trip; 912 trip++; 913 } 914 915 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { 916 acpi_trip = &tz->trips.active[i].trip; 917 918 if (!acpi_thermal_trip_valid(acpi_trip)) 919 break; 920 921 trip->type = THERMAL_TRIP_ACTIVE; 922 trip->temperature = acpi_thermal_temp(tz, acpi_trip->temp_dk); 923 trip->priv = acpi_trip; 924 trip++; 925 } 926 927 result = acpi_thermal_register_thermal_zone(tz, trip_count, passive_delay); 928 if (result) 929 goto free_trips; 930 931 refcount_set(&tz->thermal_check_count, 3); 932 mutex_init(&tz->thermal_check_lock); 933 INIT_WORK(&tz->thermal_check_work, acpi_thermal_check_fn); 934 935 pr_info("%s [%s] (%ld C)\n", acpi_device_name(device), 936 acpi_device_bid(device), deci_kelvin_to_celsius(tz->temp_dk)); 937 938 result = acpi_dev_install_notify_handler(device, ACPI_DEVICE_NOTIFY, 939 acpi_thermal_notify, device); 940 if (result) 941 goto flush_wq; 942 943 return 0; 944 945 flush_wq: 946 flush_workqueue(acpi_thermal_pm_queue); 947 acpi_thermal_unregister_thermal_zone(tz); 948 free_trips: 949 kfree(tz->trip_table); 950 free_memory: 951 acpi_thermal_free_thermal_zone(tz); 952 953 return result; 954 } 955 956 static void acpi_thermal_remove(struct acpi_device *device) 957 { 958 struct acpi_thermal *tz; 959 960 if (!device || !acpi_driver_data(device)) 961 return; 962 963 tz = acpi_driver_data(device); 964 965 acpi_dev_remove_notify_handler(device, ACPI_DEVICE_NOTIFY, 966 acpi_thermal_notify); 967 968 flush_workqueue(acpi_thermal_pm_queue); 969 acpi_thermal_unregister_thermal_zone(tz); 970 kfree(tz->trip_table); 971 acpi_thermal_free_thermal_zone(tz); 972 } 973 974 #ifdef CONFIG_PM_SLEEP 975 static int acpi_thermal_suspend(struct device *dev) 976 { 977 /* Make sure the previously queued thermal check work has been done */ 978 flush_workqueue(acpi_thermal_pm_queue); 979 return 0; 980 } 981 982 static int acpi_thermal_resume(struct device *dev) 983 { 984 struct acpi_thermal *tz; 985 int i, j, power_state; 986 987 if (!dev) 988 return -EINVAL; 989 990 tz = acpi_driver_data(to_acpi_device(dev)); 991 if (!tz) 992 return -EINVAL; 993 994 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { 995 struct acpi_thermal_trip *acpi_trip = &tz->trips.active[i].trip; 996 997 if (!acpi_thermal_trip_valid(acpi_trip)) 998 break; 999 1000 for (j = 0; j < acpi_trip->devices.count; j++) { 1001 acpi_bus_update_power(acpi_trip->devices.handles[j], 1002 &power_state); 1003 } 1004 } 1005 1006 acpi_queue_thermal_check(tz); 1007 1008 return AE_OK; 1009 } 1010 #else 1011 #define acpi_thermal_suspend NULL 1012 #define acpi_thermal_resume NULL 1013 #endif 1014 static SIMPLE_DEV_PM_OPS(acpi_thermal_pm, acpi_thermal_suspend, acpi_thermal_resume); 1015 1016 static const struct acpi_device_id thermal_device_ids[] = { 1017 {ACPI_THERMAL_HID, 0}, 1018 {"", 0}, 1019 }; 1020 MODULE_DEVICE_TABLE(acpi, thermal_device_ids); 1021 1022 static struct acpi_driver acpi_thermal_driver = { 1023 .name = "thermal", 1024 .class = ACPI_THERMAL_CLASS, 1025 .ids = thermal_device_ids, 1026 .ops = { 1027 .add = acpi_thermal_add, 1028 .remove = acpi_thermal_remove, 1029 }, 1030 .drv.pm = &acpi_thermal_pm, 1031 }; 1032 1033 static int thermal_act(const struct dmi_system_id *d) 1034 { 1035 if (act == 0) { 1036 pr_notice("%s detected: disabling all active thermal trip points\n", 1037 d->ident); 1038 act = -1; 1039 } 1040 return 0; 1041 } 1042 1043 static int thermal_nocrt(const struct dmi_system_id *d) 1044 { 1045 pr_notice("%s detected: disabling all critical thermal trip point actions.\n", 1046 d->ident); 1047 crt = -1; 1048 return 0; 1049 } 1050 1051 static int thermal_tzp(const struct dmi_system_id *d) 1052 { 1053 if (tzp == 0) { 1054 pr_notice("%s detected: enabling thermal zone polling\n", 1055 d->ident); 1056 tzp = 300; /* 300 dS = 30 Seconds */ 1057 } 1058 return 0; 1059 } 1060 1061 static int thermal_psv(const struct dmi_system_id *d) 1062 { 1063 if (psv == 0) { 1064 pr_notice("%s detected: disabling all passive thermal trip points\n", 1065 d->ident); 1066 psv = -1; 1067 } 1068 return 0; 1069 } 1070 1071 static const struct dmi_system_id thermal_dmi_table[] __initconst = { 1072 /* 1073 * Award BIOS on this AOpen makes thermal control almost worthless. 1074 * http://bugzilla.kernel.org/show_bug.cgi?id=8842 1075 */ 1076 { 1077 .callback = thermal_act, 1078 .ident = "AOpen i915GMm-HFS", 1079 .matches = { 1080 DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"), 1081 DMI_MATCH(DMI_BOARD_NAME, "i915GMm-HFS"), 1082 }, 1083 }, 1084 { 1085 .callback = thermal_psv, 1086 .ident = "AOpen i915GMm-HFS", 1087 .matches = { 1088 DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"), 1089 DMI_MATCH(DMI_BOARD_NAME, "i915GMm-HFS"), 1090 }, 1091 }, 1092 { 1093 .callback = thermal_tzp, 1094 .ident = "AOpen i915GMm-HFS", 1095 .matches = { 1096 DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"), 1097 DMI_MATCH(DMI_BOARD_NAME, "i915GMm-HFS"), 1098 }, 1099 }, 1100 { 1101 .callback = thermal_nocrt, 1102 .ident = "Gigabyte GA-7ZX", 1103 .matches = { 1104 DMI_MATCH(DMI_BOARD_VENDOR, "Gigabyte Technology Co., Ltd."), 1105 DMI_MATCH(DMI_BOARD_NAME, "7ZX"), 1106 }, 1107 }, 1108 {} 1109 }; 1110 1111 static int __init acpi_thermal_init(void) 1112 { 1113 int result; 1114 1115 dmi_check_system(thermal_dmi_table); 1116 1117 if (off) { 1118 pr_notice("thermal control disabled\n"); 1119 return -ENODEV; 1120 } 1121 1122 acpi_thermal_pm_queue = alloc_workqueue("acpi_thermal_pm", 1123 WQ_HIGHPRI | WQ_MEM_RECLAIM, 0); 1124 if (!acpi_thermal_pm_queue) 1125 return -ENODEV; 1126 1127 result = acpi_bus_register_driver(&acpi_thermal_driver); 1128 if (result < 0) { 1129 destroy_workqueue(acpi_thermal_pm_queue); 1130 return -ENODEV; 1131 } 1132 1133 return 0; 1134 } 1135 1136 static void __exit acpi_thermal_exit(void) 1137 { 1138 acpi_bus_unregister_driver(&acpi_thermal_driver); 1139 destroy_workqueue(acpi_thermal_pm_queue); 1140 } 1141 1142 module_init(acpi_thermal_init); 1143 module_exit(acpi_thermal_exit); 1144 1145 MODULE_AUTHOR("Paul Diefenbaugh"); 1146 MODULE_DESCRIPTION("ACPI Thermal Zone Driver"); 1147 MODULE_LICENSE("GPL"); 1148