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