root/drivers/acpi/thermal.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. acpi_thermal_get_temperature
  2. acpi_thermal_get_polling_frequency
  3. acpi_thermal_set_cooling_mode
  4. acpi_thermal_trips_update
  5. acpi_thermal_get_trip_points
  6. acpi_thermal_check
  7. thermal_get_temp
  8. thermal_get_mode
  9. thermal_set_mode
  10. thermal_get_trip_type
  11. thermal_get_trip_temp
  12. thermal_get_crit_temp
  13. thermal_get_trend
  14. thermal_notify
  15. acpi_thermal_cooling_device_cb
  16. acpi_thermal_bind_cooling_device
  17. acpi_thermal_unbind_cooling_device
  18. acpi_thermal_register_thermal_zone
  19. acpi_thermal_unregister_thermal_zone
  20. acpi_thermal_notify
  21. acpi_thermal_aml_dependency_fix
  22. acpi_thermal_get_info
  23. acpi_thermal_guess_offset
  24. acpi_thermal_check_fn
  25. acpi_thermal_add
  26. acpi_thermal_remove
  27. acpi_thermal_suspend
  28. acpi_thermal_resume
  29. thermal_act
  30. thermal_nocrt
  31. thermal_tzp
  32. thermal_psv
  33. acpi_thermal_init
  34. acpi_thermal_exit

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

/* [<][>][^][v][top][bottom][index][help] */