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