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 int trip_index, enum thermal_trend *trend) 496 { 497 struct acpi_thermal *tz = thermal_zone_device_priv(thermal); 498 struct acpi_thermal_trip *acpi_trip; 499 int t, i; 500 501 if (!tz || trip_index < 0) 502 return -EINVAL; 503 504 if (tz->trips.critical.valid) 505 trip_index--; 506 507 if (tz->trips.hot.valid) 508 trip_index--; 509 510 if (trip_index < 0) 511 return -EINVAL; 512 513 acpi_trip = &tz->trips.passive.trip; 514 if (acpi_trip->valid && !trip_index--) { 515 t = tz->trips.passive.tc1 * (tz->temperature - 516 tz->last_temperature) + 517 tz->trips.passive.tc2 * (tz->temperature - 518 acpi_trip->temperature); 519 if (t > 0) 520 *trend = THERMAL_TREND_RAISING; 521 else if (t < 0) 522 *trend = THERMAL_TREND_DROPPING; 523 else 524 *trend = THERMAL_TREND_STABLE; 525 526 return 0; 527 } 528 529 t = acpi_thermal_temp(tz, tz->temperature); 530 531 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { 532 acpi_trip = &tz->trips.active[i].trip; 533 if (acpi_trip->valid && !trip_index--) { 534 if (t > acpi_thermal_temp(tz, acpi_trip->temperature)) { 535 *trend = THERMAL_TREND_RAISING; 536 return 0; 537 } 538 break; 539 } 540 } 541 542 return -EINVAL; 543 } 544 545 static void acpi_thermal_zone_device_hot(struct thermal_zone_device *thermal) 546 { 547 struct acpi_thermal *tz = thermal_zone_device_priv(thermal); 548 549 acpi_bus_generate_netlink_event(tz->device->pnp.device_class, 550 dev_name(&tz->device->dev), 551 ACPI_THERMAL_NOTIFY_HOT, 1); 552 } 553 554 static void acpi_thermal_zone_device_critical(struct thermal_zone_device *thermal) 555 { 556 struct acpi_thermal *tz = thermal_zone_device_priv(thermal); 557 558 acpi_bus_generate_netlink_event(tz->device->pnp.device_class, 559 dev_name(&tz->device->dev), 560 ACPI_THERMAL_NOTIFY_CRITICAL, 1); 561 562 thermal_zone_device_critical(thermal); 563 } 564 565 static int acpi_thermal_cooling_device_cb(struct thermal_zone_device *thermal, 566 struct thermal_cooling_device *cdev, 567 bool bind) 568 { 569 struct acpi_device *device = cdev->devdata; 570 struct acpi_thermal *tz = thermal_zone_device_priv(thermal); 571 struct acpi_device *dev; 572 acpi_handle handle; 573 int i; 574 int j; 575 int trip = -1; 576 int result = 0; 577 578 if (tz->trips.critical.valid) 579 trip++; 580 581 if (tz->trips.hot.valid) 582 trip++; 583 584 if (tz->trips.passive.trip.valid) { 585 trip++; 586 for (i = 0; i < tz->trips.passive.devices.count; i++) { 587 handle = tz->trips.passive.devices.handles[i]; 588 dev = acpi_fetch_acpi_dev(handle); 589 if (dev != device) 590 continue; 591 592 if (bind) 593 result = thermal_zone_bind_cooling_device( 594 thermal, trip, cdev, 595 THERMAL_NO_LIMIT, 596 THERMAL_NO_LIMIT, 597 THERMAL_WEIGHT_DEFAULT); 598 else 599 result = 600 thermal_zone_unbind_cooling_device( 601 thermal, trip, cdev); 602 603 if (result) 604 goto failed; 605 } 606 } 607 608 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { 609 if (!tz->trips.active[i].trip.valid) 610 break; 611 612 trip++; 613 for (j = 0; j < tz->trips.active[i].devices.count; j++) { 614 handle = tz->trips.active[i].devices.handles[j]; 615 dev = acpi_fetch_acpi_dev(handle); 616 if (dev != device) 617 continue; 618 619 if (bind) 620 result = thermal_zone_bind_cooling_device( 621 thermal, trip, cdev, 622 THERMAL_NO_LIMIT, 623 THERMAL_NO_LIMIT, 624 THERMAL_WEIGHT_DEFAULT); 625 else 626 result = thermal_zone_unbind_cooling_device( 627 thermal, trip, cdev); 628 629 if (result) 630 goto failed; 631 } 632 } 633 634 failed: 635 return result; 636 } 637 638 static int 639 acpi_thermal_bind_cooling_device(struct thermal_zone_device *thermal, 640 struct thermal_cooling_device *cdev) 641 { 642 return acpi_thermal_cooling_device_cb(thermal, cdev, true); 643 } 644 645 static int 646 acpi_thermal_unbind_cooling_device(struct thermal_zone_device *thermal, 647 struct thermal_cooling_device *cdev) 648 { 649 return acpi_thermal_cooling_device_cb(thermal, cdev, false); 650 } 651 652 static struct thermal_zone_device_ops acpi_thermal_zone_ops = { 653 .bind = acpi_thermal_bind_cooling_device, 654 .unbind = acpi_thermal_unbind_cooling_device, 655 .get_temp = thermal_get_temp, 656 .get_trend = thermal_get_trend, 657 .hot = acpi_thermal_zone_device_hot, 658 .critical = acpi_thermal_zone_device_critical, 659 }; 660 661 static int acpi_thermal_zone_sysfs_add(struct acpi_thermal *tz) 662 { 663 struct device *tzdev = thermal_zone_device(tz->thermal_zone); 664 int ret; 665 666 ret = sysfs_create_link(&tz->device->dev.kobj, 667 &tzdev->kobj, "thermal_zone"); 668 if (ret) 669 return ret; 670 671 ret = sysfs_create_link(&tzdev->kobj, 672 &tz->device->dev.kobj, "device"); 673 if (ret) 674 sysfs_remove_link(&tz->device->dev.kobj, "thermal_zone"); 675 676 return ret; 677 } 678 679 static void acpi_thermal_zone_sysfs_remove(struct acpi_thermal *tz) 680 { 681 struct device *tzdev = thermal_zone_device(tz->thermal_zone); 682 683 sysfs_remove_link(&tz->device->dev.kobj, "thermal_zone"); 684 sysfs_remove_link(&tzdev->kobj, "device"); 685 } 686 687 static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz) 688 { 689 struct acpi_thermal_trip *acpi_trip; 690 struct thermal_trip *trip; 691 int passive_delay = 0; 692 int trip_count = 0; 693 int result; 694 int i; 695 696 if (tz->trips.critical.valid) 697 trip_count++; 698 699 if (tz->trips.hot.valid) 700 trip_count++; 701 702 if (tz->trips.passive.trip.valid) { 703 trip_count++; 704 passive_delay = tz->trips.passive.tsp * 100; 705 } 706 707 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE && tz->trips.active[i].trip.valid; i++) 708 trip_count++; 709 710 trip = kcalloc(trip_count, sizeof(*trip), GFP_KERNEL); 711 if (!trip) 712 return -ENOMEM; 713 714 tz->trip_table = trip; 715 716 if (tz->trips.critical.valid) { 717 trip->type = THERMAL_TRIP_CRITICAL; 718 trip->temperature = acpi_thermal_temp(tz, tz->trips.critical.temperature); 719 trip++; 720 } 721 722 if (tz->trips.hot.valid) { 723 trip->type = THERMAL_TRIP_HOT; 724 trip->temperature = acpi_thermal_temp(tz, tz->trips.hot.temperature); 725 trip++; 726 } 727 728 acpi_trip = &tz->trips.passive.trip; 729 if (acpi_trip->valid) { 730 trip->type = THERMAL_TRIP_PASSIVE; 731 trip->temperature = acpi_thermal_temp(tz, acpi_trip->temperature); 732 trip->priv = acpi_trip; 733 trip++; 734 } 735 736 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { 737 acpi_trip = &tz->trips.active[i].trip; 738 739 if (!acpi_trip->valid) 740 break; 741 742 trip->type = THERMAL_TRIP_ACTIVE; 743 trip->temperature = acpi_thermal_temp(tz, acpi_trip->temperature); 744 trip->priv = acpi_trip; 745 trip++; 746 } 747 748 tz->thermal_zone = thermal_zone_device_register_with_trips("acpitz", 749 tz->trip_table, 750 trip_count, 751 0, tz, 752 &acpi_thermal_zone_ops, 753 NULL, 754 passive_delay, 755 tz->polling_frequency * 100); 756 if (IS_ERR(tz->thermal_zone)) { 757 result = PTR_ERR(tz->thermal_zone); 758 goto free_trip_table; 759 } 760 761 result = acpi_thermal_zone_sysfs_add(tz); 762 if (result) 763 goto unregister_tzd; 764 765 result = thermal_zone_device_enable(tz->thermal_zone); 766 if (result) 767 goto remove_links; 768 769 dev_info(&tz->device->dev, "registered as thermal_zone%d\n", 770 thermal_zone_device_id(tz->thermal_zone)); 771 772 return 0; 773 774 remove_links: 775 acpi_thermal_zone_sysfs_remove(tz); 776 unregister_tzd: 777 thermal_zone_device_unregister(tz->thermal_zone); 778 free_trip_table: 779 kfree(tz->trip_table); 780 781 return result; 782 } 783 784 static void acpi_thermal_unregister_thermal_zone(struct acpi_thermal *tz) 785 { 786 acpi_thermal_zone_sysfs_remove(tz); 787 thermal_zone_device_unregister(tz->thermal_zone); 788 kfree(tz->trip_table); 789 tz->thermal_zone = NULL; 790 } 791 792 793 /* -------------------------------------------------------------------------- 794 Driver Interface 795 -------------------------------------------------------------------------- */ 796 797 static void acpi_thermal_notify(acpi_handle handle, u32 event, void *data) 798 { 799 struct acpi_device *device = data; 800 struct acpi_thermal *tz = acpi_driver_data(device); 801 802 if (!tz) 803 return; 804 805 switch (event) { 806 case ACPI_THERMAL_NOTIFY_TEMPERATURE: 807 acpi_queue_thermal_check(tz); 808 break; 809 case ACPI_THERMAL_NOTIFY_THRESHOLDS: 810 case ACPI_THERMAL_NOTIFY_DEVICES: 811 acpi_thermal_trips_update(tz, event); 812 break; 813 default: 814 acpi_handle_debug(device->handle, "Unsupported event [0x%x]\n", 815 event); 816 break; 817 } 818 } 819 820 /* 821 * On some platforms, the AML code has dependency about 822 * the evaluating order of _TMP and _CRT/_HOT/_PSV/_ACx. 823 * 1. On HP Pavilion G4-1016tx, _TMP must be invoked after 824 * /_CRT/_HOT/_PSV/_ACx, or else system will be power off. 825 * 2. On HP Compaq 6715b/6715s, the return value of _PSV is 0 826 * if _TMP has never been evaluated. 827 * 828 * As this dependency is totally transparent to OS, evaluate 829 * all of them once, in the order of _CRT/_HOT/_PSV/_ACx, 830 * _TMP, before they are actually used. 831 */ 832 static void acpi_thermal_aml_dependency_fix(struct acpi_thermal *tz) 833 { 834 acpi_handle handle = tz->device->handle; 835 unsigned long long value; 836 int i; 837 838 acpi_evaluate_integer(handle, "_CRT", NULL, &value); 839 acpi_evaluate_integer(handle, "_HOT", NULL, &value); 840 acpi_evaluate_integer(handle, "_PSV", NULL, &value); 841 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { 842 char name[5] = { '_', 'A', 'C', ('0' + i), '\0' }; 843 acpi_status status; 844 845 status = acpi_evaluate_integer(handle, name, NULL, &value); 846 if (status == AE_NOT_FOUND) 847 break; 848 } 849 acpi_evaluate_integer(handle, "_TMP", NULL, &value); 850 } 851 852 static int acpi_thermal_get_info(struct acpi_thermal *tz) 853 { 854 int result; 855 856 if (!tz) 857 return -EINVAL; 858 859 acpi_thermal_aml_dependency_fix(tz); 860 861 /* Get trip points [_CRT, _PSV, etc.] (required) */ 862 result = acpi_thermal_get_trip_points(tz); 863 if (result) 864 return result; 865 866 /* Get temperature [_TMP] (required) */ 867 result = acpi_thermal_get_temperature(tz); 868 if (result) 869 return result; 870 871 /* Set the cooling mode [_SCP] to active cooling (default) */ 872 acpi_execute_simple_method(tz->device->handle, "_SCP", 873 ACPI_THERMAL_MODE_ACTIVE); 874 875 /* Get default polling frequency [_TZP] (optional) */ 876 if (tzp) 877 tz->polling_frequency = tzp; 878 else 879 acpi_thermal_get_polling_frequency(tz); 880 881 return 0; 882 } 883 884 /* 885 * The exact offset between Kelvin and degree Celsius is 273.15. However ACPI 886 * handles temperature values with a single decimal place. As a consequence, 887 * some implementations use an offset of 273.1 and others use an offset of 888 * 273.2. Try to find out which one is being used, to present the most 889 * accurate and visually appealing number. 890 * 891 * The heuristic below should work for all ACPI thermal zones which have a 892 * critical trip point with a value being a multiple of 0.5 degree Celsius. 893 */ 894 static void acpi_thermal_guess_offset(struct acpi_thermal *tz) 895 { 896 if (tz->trips.critical.valid && 897 (tz->trips.critical.temperature % 5) == 1) 898 tz->kelvin_offset = 273100; 899 else 900 tz->kelvin_offset = 273200; 901 } 902 903 static void acpi_thermal_check_fn(struct work_struct *work) 904 { 905 struct acpi_thermal *tz = container_of(work, struct acpi_thermal, 906 thermal_check_work); 907 908 /* 909 * In general, it is not sufficient to check the pending bit, because 910 * subsequent instances of this function may be queued after one of them 911 * has started running (e.g. if _TMP sleeps). Avoid bailing out if just 912 * one of them is running, though, because it may have done the actual 913 * check some time ago, so allow at least one of them to block on the 914 * mutex while another one is running the update. 915 */ 916 if (!refcount_dec_not_one(&tz->thermal_check_count)) 917 return; 918 919 mutex_lock(&tz->thermal_check_lock); 920 921 thermal_zone_device_update(tz->thermal_zone, THERMAL_EVENT_UNSPECIFIED); 922 923 refcount_inc(&tz->thermal_check_count); 924 925 mutex_unlock(&tz->thermal_check_lock); 926 } 927 928 static int acpi_thermal_add(struct acpi_device *device) 929 { 930 struct acpi_thermal *tz; 931 int result; 932 933 if (!device) 934 return -EINVAL; 935 936 tz = kzalloc(sizeof(struct acpi_thermal), GFP_KERNEL); 937 if (!tz) 938 return -ENOMEM; 939 940 tz->device = device; 941 strcpy(tz->name, device->pnp.bus_id); 942 strcpy(acpi_device_name(device), ACPI_THERMAL_DEVICE_NAME); 943 strcpy(acpi_device_class(device), ACPI_THERMAL_CLASS); 944 device->driver_data = tz; 945 946 result = acpi_thermal_get_info(tz); 947 if (result) 948 goto free_memory; 949 950 acpi_thermal_guess_offset(tz); 951 952 result = acpi_thermal_register_thermal_zone(tz); 953 if (result) 954 goto free_memory; 955 956 refcount_set(&tz->thermal_check_count, 3); 957 mutex_init(&tz->thermal_check_lock); 958 INIT_WORK(&tz->thermal_check_work, acpi_thermal_check_fn); 959 960 pr_info("%s [%s] (%ld C)\n", acpi_device_name(device), 961 acpi_device_bid(device), deci_kelvin_to_celsius(tz->temperature)); 962 963 result = acpi_dev_install_notify_handler(device, ACPI_DEVICE_NOTIFY, 964 acpi_thermal_notify); 965 if (result) 966 goto flush_wq; 967 968 return 0; 969 970 flush_wq: 971 flush_workqueue(acpi_thermal_pm_queue); 972 acpi_thermal_unregister_thermal_zone(tz); 973 free_memory: 974 kfree(tz); 975 976 return result; 977 } 978 979 static void acpi_thermal_remove(struct acpi_device *device) 980 { 981 struct acpi_thermal *tz; 982 983 if (!device || !acpi_driver_data(device)) 984 return; 985 986 tz = acpi_driver_data(device); 987 988 acpi_dev_remove_notify_handler(device, ACPI_DEVICE_NOTIFY, 989 acpi_thermal_notify); 990 991 flush_workqueue(acpi_thermal_pm_queue); 992 acpi_thermal_unregister_thermal_zone(tz); 993 994 kfree(tz); 995 } 996 997 #ifdef CONFIG_PM_SLEEP 998 static int acpi_thermal_suspend(struct device *dev) 999 { 1000 /* Make sure the previously queued thermal check work has been done */ 1001 flush_workqueue(acpi_thermal_pm_queue); 1002 return 0; 1003 } 1004 1005 static int acpi_thermal_resume(struct device *dev) 1006 { 1007 struct acpi_thermal *tz; 1008 int i, j, power_state; 1009 1010 if (!dev) 1011 return -EINVAL; 1012 1013 tz = acpi_driver_data(to_acpi_device(dev)); 1014 if (!tz) 1015 return -EINVAL; 1016 1017 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { 1018 if (!tz->trips.active[i].trip.valid) 1019 break; 1020 1021 for (j = 0; j < tz->trips.active[i].devices.count; j++) { 1022 acpi_bus_update_power(tz->trips.active[i].devices.handles[j], 1023 &power_state); 1024 } 1025 } 1026 1027 acpi_queue_thermal_check(tz); 1028 1029 return AE_OK; 1030 } 1031 #else 1032 #define acpi_thermal_suspend NULL 1033 #define acpi_thermal_resume NULL 1034 #endif 1035 static SIMPLE_DEV_PM_OPS(acpi_thermal_pm, acpi_thermal_suspend, acpi_thermal_resume); 1036 1037 static const struct acpi_device_id thermal_device_ids[] = { 1038 {ACPI_THERMAL_HID, 0}, 1039 {"", 0}, 1040 }; 1041 MODULE_DEVICE_TABLE(acpi, thermal_device_ids); 1042 1043 static struct acpi_driver acpi_thermal_driver = { 1044 .name = "thermal", 1045 .class = ACPI_THERMAL_CLASS, 1046 .ids = thermal_device_ids, 1047 .ops = { 1048 .add = acpi_thermal_add, 1049 .remove = acpi_thermal_remove, 1050 }, 1051 .drv.pm = &acpi_thermal_pm, 1052 }; 1053 1054 static int thermal_act(const struct dmi_system_id *d) { 1055 if (act == 0) { 1056 pr_notice("%s detected: disabling all active thermal trip points\n", 1057 d->ident); 1058 act = -1; 1059 } 1060 return 0; 1061 } 1062 static int thermal_nocrt(const struct dmi_system_id *d) { 1063 pr_notice("%s detected: disabling all critical thermal trip point actions.\n", 1064 d->ident); 1065 crt = -1; 1066 return 0; 1067 } 1068 static int thermal_tzp(const struct dmi_system_id *d) { 1069 if (tzp == 0) { 1070 pr_notice("%s detected: enabling thermal zone polling\n", 1071 d->ident); 1072 tzp = 300; /* 300 dS = 30 Seconds */ 1073 } 1074 return 0; 1075 } 1076 static int thermal_psv(const struct dmi_system_id *d) { 1077 if (psv == 0) { 1078 pr_notice("%s detected: disabling all passive thermal trip points\n", 1079 d->ident); 1080 psv = -1; 1081 } 1082 return 0; 1083 } 1084 1085 static const struct dmi_system_id thermal_dmi_table[] __initconst = { 1086 /* 1087 * Award BIOS on this AOpen makes thermal control almost worthless. 1088 * http://bugzilla.kernel.org/show_bug.cgi?id=8842 1089 */ 1090 { 1091 .callback = thermal_act, 1092 .ident = "AOpen i915GMm-HFS", 1093 .matches = { 1094 DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"), 1095 DMI_MATCH(DMI_BOARD_NAME, "i915GMm-HFS"), 1096 }, 1097 }, 1098 { 1099 .callback = thermal_psv, 1100 .ident = "AOpen i915GMm-HFS", 1101 .matches = { 1102 DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"), 1103 DMI_MATCH(DMI_BOARD_NAME, "i915GMm-HFS"), 1104 }, 1105 }, 1106 { 1107 .callback = thermal_tzp, 1108 .ident = "AOpen i915GMm-HFS", 1109 .matches = { 1110 DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"), 1111 DMI_MATCH(DMI_BOARD_NAME, "i915GMm-HFS"), 1112 }, 1113 }, 1114 { 1115 .callback = thermal_nocrt, 1116 .ident = "Gigabyte GA-7ZX", 1117 .matches = { 1118 DMI_MATCH(DMI_BOARD_VENDOR, "Gigabyte Technology Co., Ltd."), 1119 DMI_MATCH(DMI_BOARD_NAME, "7ZX"), 1120 }, 1121 }, 1122 {} 1123 }; 1124 1125 static int __init acpi_thermal_init(void) 1126 { 1127 int result; 1128 1129 dmi_check_system(thermal_dmi_table); 1130 1131 if (off) { 1132 pr_notice("thermal control disabled\n"); 1133 return -ENODEV; 1134 } 1135 1136 acpi_thermal_pm_queue = alloc_workqueue("acpi_thermal_pm", 1137 WQ_HIGHPRI | WQ_MEM_RECLAIM, 0); 1138 if (!acpi_thermal_pm_queue) 1139 return -ENODEV; 1140 1141 result = acpi_bus_register_driver(&acpi_thermal_driver); 1142 if (result < 0) { 1143 destroy_workqueue(acpi_thermal_pm_queue); 1144 return -ENODEV; 1145 } 1146 1147 return 0; 1148 } 1149 1150 static void __exit acpi_thermal_exit(void) 1151 { 1152 acpi_bus_unregister_driver(&acpi_thermal_driver); 1153 destroy_workqueue(acpi_thermal_pm_queue); 1154 } 1155 1156 module_init(acpi_thermal_init); 1157 module_exit(acpi_thermal_exit); 1158 1159 MODULE_AUTHOR("Paul Diefenbaugh"); 1160 MODULE_DESCRIPTION("ACPI Thermal Zone Driver"); 1161 MODULE_LICENSE("GPL"); 1162