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