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