1 /*- 2 * Copyright (c) 2000, 2001 Michael Smith 3 * Copyright (c) 2000 BSDi 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 * 27 * $FreeBSD: head/sys/dev/acpica/acpi_thermal.c 255077 2013-08-30 19:21:12Z dumbbell $ 28 */ 29 30 #include "opt_acpi.h" 31 #include <sys/param.h> 32 #include <sys/kernel.h> 33 #include <sys/bus.h> 34 #include <sys/kthread.h> 35 #include <sys/malloc.h> 36 #include <sys/module.h> 37 #include <sys/proc.h> 38 #include <sys/reboot.h> 39 #include <sys/sysctl.h> 40 #include <sys/unistd.h> 41 #include <sys/power.h> 42 #include <sys/sensors.h> 43 44 #include <sys/mplock2.h> 45 46 #include "acpi.h" 47 #include "accommon.h" 48 49 #include <dev/acpica/acpivar.h> 50 51 /* Hooks for the ACPI CA debugging infrastructure */ 52 #define _COMPONENT ACPI_THERMAL 53 ACPI_MODULE_NAME("THERMAL") 54 55 #define TZ_ZEROC 2732 56 #define TZ_KELVTOC(x) (((x) - TZ_ZEROC) / 10), abs(((x) - TZ_ZEROC) % 10) 57 58 #define TZ_NOTIFY_TEMPERATURE 0x80 /* Temperature changed. */ 59 #define TZ_NOTIFY_LEVELS 0x81 /* Cooling levels changed. */ 60 #define TZ_NOTIFY_DEVICES 0x82 /* Device lists changed. */ 61 #define TZ_NOTIFY_CRITICAL 0xcc /* Fake notify that _CRT/_HOT reached. */ 62 63 /* Check for temperature changes every 10 seconds by default */ 64 #define TZ_POLLRATE 10 65 66 /* Make sure the reported temperature is valid for this number of polls. */ 67 #define TZ_VALIDCHECKS 3 68 69 /* Notify the user we will be shutting down in one more poll cycle. */ 70 #define TZ_NOTIFYCOUNT (TZ_VALIDCHECKS - 1) 71 72 /* ACPI spec defines this */ 73 #define TZ_NUMLEVELS 10 74 struct acpi_tz_zone { 75 int ac[TZ_NUMLEVELS]; 76 ACPI_BUFFER al[TZ_NUMLEVELS]; 77 int crt; 78 int hot; 79 ACPI_BUFFER psl; 80 int psv; 81 int tc1; 82 int tc2; 83 int tsp; 84 int tzp; 85 }; 86 87 struct acpi_tz_softc { 88 device_t tz_dev; 89 ACPI_HANDLE tz_handle; /*Thermal zone handle*/ 90 int tz_temperature; /*Current temperature*/ 91 int tz_active; /*Current active cooling*/ 92 #define TZ_ACTIVE_NONE -1 93 #define TZ_ACTIVE_UNKNOWN -2 94 int tz_requested; /*Minimum active cooling*/ 95 int tz_thflags; /*Current temp-related flags*/ 96 #define TZ_THFLAG_NONE 0 97 #define TZ_THFLAG_PSV (1<<0) 98 #define TZ_THFLAG_HOT (1<<2) 99 #define TZ_THFLAG_CRT (1<<3) 100 int tz_flags; 101 #define TZ_FLAG_NO_SCP (1<<0) /*No _SCP method*/ 102 #define TZ_FLAG_GETPROFILE (1<<1) /*Get power_profile in timeout*/ 103 #define TZ_FLAG_GETSETTINGS (1<<2) /*Get devs/setpoints*/ 104 struct timespec tz_cooling_started; 105 /*Current cooling starting time*/ 106 107 struct sysctl_ctx_list tz_sysctl_ctx; 108 struct sysctl_oid *tz_sysctl_tree; 109 eventhandler_tag tz_event; 110 111 struct acpi_tz_zone tz_zone; /*Thermal zone parameters*/ 112 int tz_validchecks; 113 int tz_insane_tmp_notified; 114 115 /* passive cooling */ 116 struct thread *tz_cooling_proc; 117 int tz_cooling_proc_running; 118 int tz_cooling_enabled; 119 int tz_cooling_active; 120 int tz_cooling_updated; 121 int tz_cooling_saved_freq; 122 /* sensors(9) related */ 123 struct ksensordev sensordev; 124 struct ksensor sensor; 125 }; 126 127 #define TZ_ACTIVE_LEVEL(act) ((act) >= 0 ? (act) : TZ_NUMLEVELS) 128 129 #define CPUFREQ_MAX_LEVELS 64 /* XXX cpufreq should export this */ 130 131 static int acpi_tz_probe(device_t dev); 132 static int acpi_tz_attach(device_t dev); 133 static int acpi_tz_establish(struct acpi_tz_softc *sc); 134 static void acpi_tz_monitor(void *Context); 135 static void acpi_tz_switch_cooler_off(ACPI_OBJECT *obj, void *arg); 136 static void acpi_tz_switch_cooler_on(ACPI_OBJECT *obj, void *arg); 137 static void acpi_tz_getparam(struct acpi_tz_softc *sc, char *node, 138 int *data); 139 static void acpi_tz_sanity(struct acpi_tz_softc *sc, int *val, char *what); 140 static int acpi_tz_active_sysctl(SYSCTL_HANDLER_ARGS); 141 static int acpi_tz_cooling_sysctl(SYSCTL_HANDLER_ARGS); 142 static int acpi_tz_temp_sysctl(SYSCTL_HANDLER_ARGS); 143 static int acpi_tz_passive_sysctl(SYSCTL_HANDLER_ARGS); 144 static void acpi_tz_notify_handler(ACPI_HANDLE h, UINT32 notify, 145 void *context); 146 static void acpi_tz_signal(struct acpi_tz_softc *sc, int flags); 147 static void acpi_tz_timeout(struct acpi_tz_softc *sc, int flags); 148 static void acpi_tz_power_profile(void *arg); 149 static void acpi_tz_thread(void *arg); 150 static int acpi_tz_cooling_is_available(struct acpi_tz_softc *sc); 151 static int acpi_tz_cooling_thread_start(struct acpi_tz_softc *sc); 152 153 static device_method_t acpi_tz_methods[] = { 154 /* Device interface */ 155 DEVMETHOD(device_probe, acpi_tz_probe), 156 DEVMETHOD(device_attach, acpi_tz_attach), 157 158 DEVMETHOD_END 159 }; 160 161 static driver_t acpi_tz_driver = { 162 "acpi_tz", 163 acpi_tz_methods, 164 sizeof(struct acpi_tz_softc), 165 }; 166 167 static char *acpi_tz_tmp_name = "_TMP"; 168 169 static devclass_t acpi_tz_devclass; 170 DRIVER_MODULE(acpi_tz, acpi, acpi_tz_driver, acpi_tz_devclass, NULL, NULL); 171 MODULE_DEPEND(acpi_tz, acpi, 1, 1, 1); 172 173 static struct sysctl_ctx_list acpi_tz_sysctl_ctx; 174 static struct sysctl_oid *acpi_tz_sysctl_tree; 175 176 /* Minimum cooling run time */ 177 static int acpi_tz_min_runtime; 178 static int acpi_tz_polling_rate = TZ_POLLRATE; 179 static int acpi_tz_override; 180 181 /* Timezone polling thread */ 182 static struct thread *acpi_tz_td; 183 ACPI_LOCK_DECL(thermal, "ACPI thermal zone"); 184 185 static int acpi_tz_cooling_unit = -1; 186 187 static int 188 acpi_tz_probe(device_t dev) 189 { 190 int result; 191 192 if (acpi_get_type(dev) == ACPI_TYPE_THERMAL && !acpi_disabled("thermal")) { 193 device_set_desc(dev, "Thermal Zone"); 194 result = -10; 195 } else 196 result = ENXIO; 197 return (result); 198 } 199 200 static int 201 acpi_tz_attach(device_t dev) 202 { 203 struct acpi_tz_softc *sc; 204 struct acpi_softc *acpi_sc; 205 int error; 206 char oidname[8]; 207 208 ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); 209 210 sc = device_get_softc(dev); 211 sc->tz_dev = dev; 212 sc->tz_handle = acpi_get_handle(dev); 213 sc->tz_requested = TZ_ACTIVE_NONE; 214 sc->tz_active = TZ_ACTIVE_UNKNOWN; 215 sc->tz_thflags = TZ_THFLAG_NONE; 216 sc->tz_cooling_proc = NULL; 217 sc->tz_cooling_proc_running = FALSE; 218 sc->tz_cooling_active = FALSE; 219 sc->tz_cooling_updated = FALSE; 220 sc->tz_cooling_enabled = FALSE; 221 222 /* 223 * Parse the current state of the thermal zone and build control 224 * structures. We don't need to worry about interference with the 225 * control thread since we haven't fully attached this device yet. 226 */ 227 if ((error = acpi_tz_establish(sc)) != 0) 228 return (error); 229 230 /* 231 * Register for any Notify events sent to this zone. 232 */ 233 AcpiInstallNotifyHandler(sc->tz_handle, ACPI_DEVICE_NOTIFY, 234 acpi_tz_notify_handler, sc); 235 236 /* 237 * Create our sysctl nodes. 238 * 239 * XXX we need a mechanism for adding nodes under ACPI. 240 */ 241 if (device_get_unit(dev) == 0) { 242 acpi_sc = acpi_device_get_parent_softc(dev); 243 sysctl_ctx_init(&acpi_tz_sysctl_ctx); 244 acpi_tz_sysctl_tree = SYSCTL_ADD_NODE(&acpi_tz_sysctl_ctx, 245 SYSCTL_CHILDREN(acpi_sc->acpi_sysctl_tree), 246 OID_AUTO, "thermal", CTLFLAG_RD, 0, ""); 247 SYSCTL_ADD_INT(&acpi_tz_sysctl_ctx, 248 SYSCTL_CHILDREN(acpi_tz_sysctl_tree), 249 OID_AUTO, "min_runtime", CTLFLAG_RW, 250 &acpi_tz_min_runtime, 0, 251 "minimum cooling run time in sec"); 252 SYSCTL_ADD_INT(&acpi_tz_sysctl_ctx, 253 SYSCTL_CHILDREN(acpi_tz_sysctl_tree), 254 OID_AUTO, "polling_rate", CTLFLAG_RW, 255 &acpi_tz_polling_rate, 0, "monitor polling interval in seconds"); 256 SYSCTL_ADD_INT(&acpi_tz_sysctl_ctx, 257 SYSCTL_CHILDREN(acpi_tz_sysctl_tree), OID_AUTO, 258 "user_override", CTLFLAG_RW, &acpi_tz_override, 0, 259 "allow override of thermal settings"); 260 } 261 sysctl_ctx_init(&sc->tz_sysctl_ctx); 262 ksprintf(oidname, "tz%d", device_get_unit(dev)); 263 sc->tz_sysctl_tree = SYSCTL_ADD_NODE(&sc->tz_sysctl_ctx, 264 SYSCTL_CHILDREN(acpi_tz_sysctl_tree), 265 OID_AUTO, oidname, CTLFLAG_RD, 0, ""); 266 SYSCTL_ADD_PROC(&sc->tz_sysctl_ctx, SYSCTL_CHILDREN(sc->tz_sysctl_tree), 267 OID_AUTO, "temperature", CTLTYPE_INT | CTLFLAG_RD, 268 &sc->tz_temperature, 0, sysctl_handle_int, 269 "IK", "current thermal zone temperature"); 270 SYSCTL_ADD_PROC(&sc->tz_sysctl_ctx, SYSCTL_CHILDREN(sc->tz_sysctl_tree), 271 OID_AUTO, "active", CTLTYPE_INT | CTLFLAG_RW, 272 sc, 0, acpi_tz_active_sysctl, "I", "cooling is active"); 273 SYSCTL_ADD_PROC(&sc->tz_sysctl_ctx, SYSCTL_CHILDREN(sc->tz_sysctl_tree), 274 OID_AUTO, "passive_cooling", CTLTYPE_INT | CTLFLAG_RW, 275 sc, 0, acpi_tz_cooling_sysctl, "I", 276 "enable passive (speed reduction) cooling"); 277 278 SYSCTL_ADD_INT(&sc->tz_sysctl_ctx, SYSCTL_CHILDREN(sc->tz_sysctl_tree), 279 OID_AUTO, "thermal_flags", CTLFLAG_RD, 280 &sc->tz_thflags, 0, "thermal zone flags"); 281 SYSCTL_ADD_PROC(&sc->tz_sysctl_ctx, SYSCTL_CHILDREN(sc->tz_sysctl_tree), 282 OID_AUTO, "_PSV", CTLTYPE_INT | CTLFLAG_RW, 283 sc, offsetof(struct acpi_tz_softc, tz_zone.psv), 284 acpi_tz_temp_sysctl, "IK", "passive cooling temp setpoint"); 285 SYSCTL_ADD_PROC(&sc->tz_sysctl_ctx, SYSCTL_CHILDREN(sc->tz_sysctl_tree), 286 OID_AUTO, "_HOT", CTLTYPE_INT | CTLFLAG_RW, 287 sc, offsetof(struct acpi_tz_softc, tz_zone.hot), 288 acpi_tz_temp_sysctl, "IK", 289 "too hot temp setpoint (suspend now)"); 290 SYSCTL_ADD_PROC(&sc->tz_sysctl_ctx, SYSCTL_CHILDREN(sc->tz_sysctl_tree), 291 OID_AUTO, "_CRT", CTLTYPE_INT | CTLFLAG_RW, 292 sc, offsetof(struct acpi_tz_softc, tz_zone.crt), 293 acpi_tz_temp_sysctl, "IK", 294 "critical temp setpoint (shutdown now)"); 295 SYSCTL_ADD_PROC(&sc->tz_sysctl_ctx, SYSCTL_CHILDREN(sc->tz_sysctl_tree), 296 OID_AUTO, "_ACx", CTLTYPE_INT | CTLFLAG_RD, 297 &sc->tz_zone.ac, sizeof(sc->tz_zone.ac), 298 sysctl_handle_opaque, "IK", ""); 299 SYSCTL_ADD_PROC(&sc->tz_sysctl_ctx, SYSCTL_CHILDREN(sc->tz_sysctl_tree), 300 OID_AUTO, "_TC1", CTLTYPE_INT | CTLFLAG_RW, 301 sc, offsetof(struct acpi_tz_softc, tz_zone.tc1), 302 acpi_tz_passive_sysctl, "I", 303 "thermal constant 1 for passive cooling"); 304 SYSCTL_ADD_PROC(&sc->tz_sysctl_ctx, SYSCTL_CHILDREN(sc->tz_sysctl_tree), 305 OID_AUTO, "_TC2", CTLTYPE_INT | CTLFLAG_RW, 306 sc, offsetof(struct acpi_tz_softc, tz_zone.tc2), 307 acpi_tz_passive_sysctl, "I", 308 "thermal constant 2 for passive cooling"); 309 SYSCTL_ADD_PROC(&sc->tz_sysctl_ctx, SYSCTL_CHILDREN(sc->tz_sysctl_tree), 310 OID_AUTO, "_TSP", CTLTYPE_INT | CTLFLAG_RW, 311 sc, offsetof(struct acpi_tz_softc, tz_zone.tsp), 312 acpi_tz_passive_sysctl, "I", 313 "thermal sampling period for passive cooling"); 314 315 /* 316 * Create thread to service all of the thermal zones. Register 317 * our power profile event handler. 318 */ 319 sc->tz_event = EVENTHANDLER_REGISTER(power_profile_change, 320 acpi_tz_power_profile, sc, 0); 321 if (acpi_tz_td == NULL) { 322 error = kthread_create(acpi_tz_thread, NULL, &acpi_tz_td, 323 "acpi_thermal"); 324 if (error != 0) { 325 device_printf(sc->tz_dev, "could not create thread - %d", error); 326 goto out; 327 } 328 } 329 330 /* 331 * Create a thread to handle passive cooling for 1st zone which 332 * has _PSV, _TSP, _TC1 and _TC2. Users can enable it for other 333 * zones manually for now. 334 * 335 * XXX We enable only one zone to avoid multiple zones conflict 336 * with each other since cpufreq currently sets all CPUs to the 337 * given frequency whereas it's possible for different thermal 338 * zones to specify independent settings for multiple CPUs. 339 */ 340 if (acpi_tz_cooling_unit < 0 && acpi_tz_cooling_is_available(sc)) 341 sc->tz_cooling_enabled = TRUE; 342 if (sc->tz_cooling_enabled) { 343 error = acpi_tz_cooling_thread_start(sc); 344 if (error != 0) { 345 sc->tz_cooling_enabled = FALSE; 346 goto out; 347 } 348 acpi_tz_cooling_unit = device_get_unit(dev); 349 } 350 351 /* 352 * Flag the event handler for a manual invocation by our timeout. 353 * We defer it like this so that the rest of the subsystem has time 354 * to come up. Don't bother evaluating/printing the temperature at 355 * this point; on many systems it'll be bogus until the EC is running. 356 */ 357 sc->tz_flags |= TZ_FLAG_GETPROFILE; 358 359 /* Attach sensors(9). */ 360 strlcpy(sc->sensordev.xname, device_get_nameunit(sc->tz_dev), 361 sizeof(sc->sensordev.xname)); 362 363 sc->sensor.type = SENSOR_TEMP; 364 sensor_attach(&sc->sensordev, &sc->sensor); 365 366 sensordev_install(&sc->sensordev); 367 368 out: 369 if (error != 0) { 370 EVENTHANDLER_DEREGISTER(power_profile_change, sc->tz_event); 371 AcpiRemoveNotifyHandler(sc->tz_handle, ACPI_DEVICE_NOTIFY, 372 acpi_tz_notify_handler); 373 sysctl_ctx_free(&sc->tz_sysctl_ctx); 374 } 375 return_VALUE (error); 376 } 377 378 /* 379 * Parse the current state of this thermal zone and set up to use it. 380 * 381 * Note that we may have previous state, which will have to be discarded. 382 */ 383 static int 384 acpi_tz_establish(struct acpi_tz_softc *sc) 385 { 386 ACPI_OBJECT *obj; 387 int i; 388 char nbuf[8]; 389 390 ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); 391 392 /* Erase any existing state. */ 393 for (i = 0; i < TZ_NUMLEVELS; i++) 394 if (sc->tz_zone.al[i].Pointer != NULL) 395 AcpiOsFree(sc->tz_zone.al[i].Pointer); 396 if (sc->tz_zone.psl.Pointer != NULL) 397 AcpiOsFree(sc->tz_zone.psl.Pointer); 398 399 /* 400 * XXX: We initialize only ACPI_BUFFER to avoid race condition 401 * with passive cooling thread which refers psv, tc1, tc2 and tsp. 402 */ 403 bzero(sc->tz_zone.ac, sizeof(sc->tz_zone.ac)); 404 bzero(sc->tz_zone.al, sizeof(sc->tz_zone.al)); 405 bzero(&sc->tz_zone.psl, sizeof(sc->tz_zone.psl)); 406 407 /* Evaluate thermal zone parameters. */ 408 for (i = 0; i < TZ_NUMLEVELS; i++) { 409 ksprintf(nbuf, "_AC%d", i); 410 acpi_tz_getparam(sc, nbuf, &sc->tz_zone.ac[i]); 411 ksprintf(nbuf, "_AL%d", i); 412 sc->tz_zone.al[i].Length = ACPI_ALLOCATE_BUFFER; 413 sc->tz_zone.al[i].Pointer = NULL; 414 AcpiEvaluateObject(sc->tz_handle, nbuf, NULL, &sc->tz_zone.al[i]); 415 obj = (ACPI_OBJECT *)sc->tz_zone.al[i].Pointer; 416 if (obj != NULL) { 417 /* Should be a package containing a list of power objects */ 418 if (obj->Type != ACPI_TYPE_PACKAGE) { 419 device_printf(sc->tz_dev, "%s has unknown type %d, rejecting\n", 420 nbuf, obj->Type); 421 return_VALUE (ENXIO); 422 } 423 } 424 } 425 acpi_tz_getparam(sc, "_CRT", &sc->tz_zone.crt); 426 acpi_tz_getparam(sc, "_HOT", &sc->tz_zone.hot); 427 sc->tz_zone.psl.Length = ACPI_ALLOCATE_BUFFER; 428 sc->tz_zone.psl.Pointer = NULL; 429 AcpiEvaluateObject(sc->tz_handle, "_PSL", NULL, &sc->tz_zone.psl); 430 acpi_tz_getparam(sc, "_PSV", &sc->tz_zone.psv); 431 acpi_tz_getparam(sc, "_TC1", &sc->tz_zone.tc1); 432 acpi_tz_getparam(sc, "_TC2", &sc->tz_zone.tc2); 433 acpi_tz_getparam(sc, "_TSP", &sc->tz_zone.tsp); 434 acpi_tz_getparam(sc, "_TZP", &sc->tz_zone.tzp); 435 436 /* 437 * Sanity-check the values we've been given. 438 * 439 * XXX what do we do about systems that give us the same value for 440 * more than one of these setpoints? 441 */ 442 acpi_tz_sanity(sc, &sc->tz_zone.crt, "_CRT"); 443 acpi_tz_sanity(sc, &sc->tz_zone.hot, "_HOT"); 444 acpi_tz_sanity(sc, &sc->tz_zone.psv, "_PSV"); 445 for (i = 0; i < TZ_NUMLEVELS; i++) 446 acpi_tz_sanity(sc, &sc->tz_zone.ac[i], "_ACx"); 447 448 return_VALUE (0); 449 } 450 451 static char *aclevel_string[] = { 452 "NONE", "_AC0", "_AC1", "_AC2", "_AC3", "_AC4", 453 "_AC5", "_AC6", "_AC7", "_AC8", "_AC9" 454 }; 455 456 static __inline const char * 457 acpi_tz_aclevel_string(int active) 458 { 459 if (active < -1 || active >= TZ_NUMLEVELS) 460 return (aclevel_string[0]); 461 462 return (aclevel_string[active + 1]); 463 } 464 465 /* 466 * Get the current temperature. 467 */ 468 static int 469 acpi_tz_get_temperature(struct acpi_tz_softc *sc) 470 { 471 int temp; 472 ACPI_STATUS status; 473 474 ACPI_FUNCTION_NAME ("acpi_tz_get_temperature"); 475 476 /* Evaluate the thermal zone's _TMP method. */ 477 status = acpi_GetInteger(sc->tz_handle, acpi_tz_tmp_name, &temp); 478 if (ACPI_FAILURE(status)) { 479 ACPI_VPRINT(sc->tz_dev, acpi_device_get_parent_softc(sc->tz_dev), 480 "error fetching current temperature -- %s\n", 481 AcpiFormatException(status)); 482 return (FALSE); 483 } 484 485 /* Check it for validity. */ 486 acpi_tz_sanity(sc, &temp, acpi_tz_tmp_name); 487 if (temp == -1) 488 return (FALSE); 489 490 ACPI_DEBUG_PRINT((ACPI_DB_VALUES, "got %d.%dC\n", TZ_KELVTOC(temp))); 491 sc->tz_temperature = temp; 492 /* Update sensor */ 493 if(sc->tz_temperature == -1) 494 sc->sensor.flags &= ~SENSOR_FINVALID; 495 sc->sensor.value = sc->tz_temperature * 100000 - 50000; 496 return (TRUE); 497 } 498 499 /* 500 * Evaluate the condition of a thermal zone, take appropriate actions. 501 */ 502 static void 503 acpi_tz_monitor(void *Context) 504 { 505 struct acpi_tz_softc *sc; 506 struct timespec curtime; 507 int temp; 508 int i; 509 int newactive, newflags; 510 511 ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); 512 513 sc = (struct acpi_tz_softc *)Context; 514 515 /* Get the current temperature. */ 516 if (!acpi_tz_get_temperature(sc)) { 517 /* XXX disable zone? go to max cooling? */ 518 return_VOID; 519 } 520 temp = sc->tz_temperature; 521 522 /* 523 * Work out what we ought to be doing right now. 524 * 525 * Note that the _ACx levels sort from hot to cold. 526 */ 527 newactive = TZ_ACTIVE_NONE; 528 for (i = TZ_NUMLEVELS - 1; i >= 0; i--) { 529 if (sc->tz_zone.ac[i] != -1 && temp >= sc->tz_zone.ac[i]) 530 newactive = i; 531 } 532 533 /* 534 * We are going to get _ACx level down (colder side), but give a guaranteed 535 * minimum cooling run time if requested. 536 */ 537 if (acpi_tz_min_runtime > 0 && sc->tz_active != TZ_ACTIVE_NONE && 538 sc->tz_active != TZ_ACTIVE_UNKNOWN && 539 (newactive == TZ_ACTIVE_NONE || newactive > sc->tz_active)) { 540 541 getnanotime(&curtime); 542 timespecsub(&curtime, &sc->tz_cooling_started); 543 if (curtime.tv_sec < acpi_tz_min_runtime) 544 newactive = sc->tz_active; 545 } 546 547 /* Handle user override of active mode */ 548 if (sc->tz_requested != TZ_ACTIVE_NONE && (newactive == TZ_ACTIVE_NONE 549 || sc->tz_requested < newactive)) 550 newactive = sc->tz_requested; 551 552 /* update temperature-related flags */ 553 newflags = TZ_THFLAG_NONE; 554 if (sc->tz_zone.psv != -1 && temp >= sc->tz_zone.psv) 555 newflags |= TZ_THFLAG_PSV; 556 if (sc->tz_zone.hot != -1 && temp >= sc->tz_zone.hot) 557 newflags |= TZ_THFLAG_HOT; 558 if (sc->tz_zone.crt != -1 && temp >= sc->tz_zone.crt) 559 newflags |= TZ_THFLAG_CRT; 560 561 /* If the active cooling state has changed, we have to switch things. */ 562 if (sc->tz_active == TZ_ACTIVE_UNKNOWN) { 563 /* 564 * We don't know which cooling device is on or off, 565 * so stop them all, because we now know which 566 * should be on (if any). 567 */ 568 for (i = 0; i < TZ_NUMLEVELS; i++) { 569 if (sc->tz_zone.al[i].Pointer != NULL) { 570 acpi_ForeachPackageObject( 571 (ACPI_OBJECT *)sc->tz_zone.al[i].Pointer, 572 acpi_tz_switch_cooler_off, sc); 573 } 574 } 575 /* now we know that all devices are off */ 576 sc->tz_active = TZ_ACTIVE_NONE; 577 } 578 579 if (newactive != sc->tz_active) { 580 /* Turn off unneeded cooling devices that are on, if any are */ 581 for (i = TZ_ACTIVE_LEVEL(sc->tz_active); 582 i < TZ_ACTIVE_LEVEL(newactive); i++) { 583 acpi_ForeachPackageObject( 584 (ACPI_OBJECT *)sc->tz_zone.al[i].Pointer, 585 acpi_tz_switch_cooler_off, sc); 586 } 587 /* Turn on cooling devices that are required, if any are */ 588 for (i = TZ_ACTIVE_LEVEL(sc->tz_active) - 1; 589 i >= TZ_ACTIVE_LEVEL(newactive); i--) { 590 acpi_ForeachPackageObject( 591 (ACPI_OBJECT *)sc->tz_zone.al[i].Pointer, 592 acpi_tz_switch_cooler_on, sc); 593 } 594 595 ACPI_VPRINT(sc->tz_dev, acpi_device_get_parent_softc(sc->tz_dev), 596 "switched from %s to %s: %d.%dC\n", 597 acpi_tz_aclevel_string(sc->tz_active), 598 acpi_tz_aclevel_string(newactive), TZ_KELVTOC(temp)); 599 sc->tz_active = newactive; 600 getnanotime(&sc->tz_cooling_started); 601 } 602 603 /* XXX (de)activate any passive cooling that may be required. */ 604 605 /* 606 * If the temperature is at _HOT or _CRT, increment our event count. 607 * If it has occurred enough times, shutdown the system. This is 608 * needed because some systems will report an invalid high temperature 609 * for one poll cycle. It is suspected this is due to the embedded 610 * controller timing out. A typical value is 138C for one cycle on 611 * a system that is otherwise 65C. 612 * 613 * If we're almost at that threshold, notify the user through devd(8). 614 */ 615 if ((newflags & (TZ_THFLAG_HOT | TZ_THFLAG_CRT)) != 0) { 616 sc->tz_validchecks++; 617 if (sc->tz_validchecks == TZ_VALIDCHECKS) { 618 device_printf(sc->tz_dev, 619 "WARNING - current temperature (%d.%dC) exceeds safe limits\n", 620 TZ_KELVTOC(sc->tz_temperature)); 621 shutdown_nice(RB_POWEROFF); 622 } else if (sc->tz_validchecks == TZ_NOTIFYCOUNT) 623 acpi_UserNotify("Thermal", sc->tz_handle, TZ_NOTIFY_CRITICAL); 624 } else { 625 sc->tz_validchecks = 0; 626 } 627 sc->tz_thflags = newflags; 628 629 return_VOID; 630 } 631 632 /* 633 * Given an object, verify that it's a reference to a device of some sort, 634 * and try to switch it off. 635 */ 636 static void 637 acpi_tz_switch_cooler_off(ACPI_OBJECT *obj, void *arg) 638 { 639 ACPI_HANDLE cooler; 640 641 ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); 642 643 cooler = acpi_GetReference(NULL, obj); 644 if (cooler == NULL) { 645 ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "can't get handle\n")); 646 return_VOID; 647 } 648 649 ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "called to turn %s off\n", 650 acpi_name(cooler))); 651 acpi_pwr_switch_consumer(cooler, ACPI_STATE_D3); 652 653 return_VOID; 654 } 655 656 /* 657 * Given an object, verify that it's a reference to a device of some sort, 658 * and try to switch it on. 659 * 660 * XXX replication of off/on function code is bad. 661 */ 662 static void 663 acpi_tz_switch_cooler_on(ACPI_OBJECT *obj, void *arg) 664 { 665 struct acpi_tz_softc *sc = (struct acpi_tz_softc *)arg; 666 ACPI_HANDLE cooler; 667 ACPI_STATUS status; 668 669 ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); 670 671 cooler = acpi_GetReference(NULL, obj); 672 if (cooler == NULL) { 673 ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "can't get handle\n")); 674 return_VOID; 675 } 676 677 ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "called to turn %s on\n", 678 acpi_name(cooler))); 679 status = acpi_pwr_switch_consumer(cooler, ACPI_STATE_D0); 680 if (ACPI_FAILURE(status)) { 681 ACPI_VPRINT(sc->tz_dev, acpi_device_get_parent_softc(sc->tz_dev), 682 "failed to activate %s - %s\n", acpi_name(cooler), 683 AcpiFormatException(status)); 684 } 685 686 return_VOID; 687 } 688 689 /* 690 * Read/debug-print a parameter, default it to -1. 691 */ 692 static void 693 acpi_tz_getparam(struct acpi_tz_softc *sc, char *node, int *data) 694 { 695 696 ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); 697 698 if (ACPI_FAILURE(acpi_GetInteger(sc->tz_handle, node, data))) { 699 *data = -1; 700 } else { 701 ACPI_DEBUG_PRINT((ACPI_DB_VALUES, "%s.%s = %d\n", 702 acpi_name(sc->tz_handle), node, *data)); 703 } 704 705 return_VOID; 706 } 707 708 /* 709 * Sanity-check a temperature value. Assume that setpoints 710 * should be between 0C and 200C. 711 */ 712 static void 713 acpi_tz_sanity(struct acpi_tz_softc *sc, int *val, char *what) 714 { 715 if (*val != -1 && (*val < TZ_ZEROC || *val > TZ_ZEROC + 2000)) { 716 /* 717 * If the value we are checking is _TMP, warn the user only 718 * once. This avoids spamming messages if, for instance, the 719 * sensor is broken and always returns an invalid temperature. 720 * 721 * This is only done for _TMP; other values always emit a 722 * warning. 723 */ 724 if (what != acpi_tz_tmp_name || !sc->tz_insane_tmp_notified) { 725 device_printf(sc->tz_dev, "%s value is absurd, ignored (%d.%dC)\n", 726 what, TZ_KELVTOC(*val)); 727 728 /* Don't warn the user again if the read value doesn't improve. */ 729 if (what == acpi_tz_tmp_name) 730 sc->tz_insane_tmp_notified = 1; 731 } 732 *val = -1; 733 return; 734 } 735 736 /* This value is correct. Warn if it's incorrect again. */ 737 if (what == acpi_tz_tmp_name) 738 sc->tz_insane_tmp_notified = 0; 739 } 740 741 /* 742 * Respond to a sysctl on the active state node. 743 */ 744 static int 745 acpi_tz_active_sysctl(SYSCTL_HANDLER_ARGS) 746 { 747 struct acpi_tz_softc *sc; 748 int active; 749 int error; 750 751 sc = (struct acpi_tz_softc *)oidp->oid_arg1; 752 active = sc->tz_active; 753 error = sysctl_handle_int(oidp, &active, 0, req); 754 755 /* Error or no new value */ 756 if (error != 0 || req->newptr == NULL) 757 return (error); 758 if (active < -1 || active >= TZ_NUMLEVELS) 759 return (EINVAL); 760 761 /* Set new preferred level and re-switch */ 762 sc->tz_requested = active; 763 acpi_tz_signal(sc, 0); 764 return (0); 765 } 766 767 static int 768 acpi_tz_cooling_sysctl(SYSCTL_HANDLER_ARGS) 769 { 770 struct acpi_tz_softc *sc; 771 int enabled, error; 772 773 sc = (struct acpi_tz_softc *)oidp->oid_arg1; 774 enabled = sc->tz_cooling_enabled; 775 error = sysctl_handle_int(oidp, &enabled, 0, req); 776 777 /* Error or no new value */ 778 if (error != 0 || req->newptr == NULL) 779 return (error); 780 if (enabled != TRUE && enabled != FALSE) 781 return (EINVAL); 782 783 if (enabled) { 784 if (acpi_tz_cooling_is_available(sc)) 785 error = acpi_tz_cooling_thread_start(sc); 786 else 787 error = ENODEV; 788 if (error) 789 enabled = FALSE; 790 } 791 sc->tz_cooling_enabled = enabled; 792 return (error); 793 } 794 795 static int 796 acpi_tz_temp_sysctl(SYSCTL_HANDLER_ARGS) 797 { 798 struct acpi_tz_softc *sc; 799 int temp, *temp_ptr; 800 int error; 801 802 sc = oidp->oid_arg1; 803 temp_ptr = (int *)((uintptr_t)sc + oidp->oid_arg2); 804 temp = *temp_ptr; 805 error = sysctl_handle_int(oidp, &temp, 0, req); 806 807 /* Error or no new value */ 808 if (error != 0 || req->newptr == NULL) 809 return (error); 810 811 /* Only allow changing settings if override is set. */ 812 if (!acpi_tz_override) 813 return (EPERM); 814 815 /* Check user-supplied value for sanity. */ 816 acpi_tz_sanity(sc, &temp, "user-supplied temp"); 817 if (temp == -1) 818 return (EINVAL); 819 820 *temp_ptr = temp; 821 return (0); 822 } 823 824 static int 825 acpi_tz_passive_sysctl(SYSCTL_HANDLER_ARGS) 826 { 827 struct acpi_tz_softc *sc; 828 int val, *val_ptr; 829 int error; 830 831 sc = oidp->oid_arg1; 832 val_ptr = (int *)((uintptr_t)sc + oidp->oid_arg2); 833 val = *val_ptr; 834 error = sysctl_handle_int(oidp, &val, 0, req); 835 836 /* Error or no new value */ 837 if (error != 0 || req->newptr == NULL) 838 return (error); 839 840 /* Only allow changing settings if override is set. */ 841 if (!acpi_tz_override) 842 return (EPERM); 843 844 *val_ptr = val; 845 return (0); 846 } 847 848 static void 849 acpi_tz_notify_handler(ACPI_HANDLE h, UINT32 notify, void *context) 850 { 851 struct acpi_tz_softc *sc = (struct acpi_tz_softc *)context; 852 853 ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); 854 855 switch (notify) { 856 case TZ_NOTIFY_TEMPERATURE: 857 /* Temperature change occurred */ 858 acpi_tz_signal(sc, 0); 859 break; 860 case TZ_NOTIFY_DEVICES: 861 case TZ_NOTIFY_LEVELS: 862 /* Zone devices/setpoints changed */ 863 acpi_tz_signal(sc, TZ_FLAG_GETSETTINGS); 864 break; 865 default: 866 ACPI_VPRINT(sc->tz_dev, acpi_device_get_parent_softc(sc->tz_dev), 867 "unknown Notify event 0x%x\n", notify); 868 break; 869 } 870 871 acpi_UserNotify("Thermal", h, notify); 872 873 return_VOID; 874 } 875 876 static void 877 acpi_tz_signal(struct acpi_tz_softc *sc, int flags) 878 { 879 ACPI_LOCK(thermal); 880 sc->tz_flags |= flags; 881 ACPI_UNLOCK(thermal); 882 wakeup(&acpi_tz_td); 883 } 884 885 /* 886 * Notifies can be generated asynchronously but have also been seen to be 887 * triggered by other thermal methods. One system generates a notify of 888 * 0x81 when the fan is turned on or off. Another generates it when _SCP 889 * is called. To handle these situations, we check the zone via 890 * acpi_tz_monitor() before evaluating changes to setpoints or the cooling 891 * policy. 892 */ 893 static void 894 acpi_tz_timeout(struct acpi_tz_softc *sc, int flags) 895 { 896 897 /* Check the current temperature and take action based on it */ 898 acpi_tz_monitor(sc); 899 900 /* If requested, get the power profile settings. */ 901 if (flags & TZ_FLAG_GETPROFILE) 902 acpi_tz_power_profile(sc); 903 904 /* 905 * If requested, check for new devices/setpoints. After finding them, 906 * check if we need to switch fans based on the new values. 907 */ 908 if (flags & TZ_FLAG_GETSETTINGS) { 909 acpi_tz_establish(sc); 910 acpi_tz_monitor(sc); 911 } 912 913 /* XXX passive cooling actions? */ 914 } 915 916 /* 917 * System power profile may have changed; fetch and notify the 918 * thermal zone accordingly. 919 * 920 * Since this can be called from an arbitrary eventhandler, it needs 921 * to get the ACPI lock itself. 922 */ 923 static void 924 acpi_tz_power_profile(void *arg) 925 { 926 ACPI_STATUS status; 927 struct acpi_tz_softc *sc = (struct acpi_tz_softc *)arg; 928 int state; 929 930 state = power_profile_get_state(); 931 if (state != POWER_PROFILE_PERFORMANCE && state != POWER_PROFILE_ECONOMY) 932 return; 933 934 /* check that we haven't decided there's no _SCP method */ 935 if ((sc->tz_flags & TZ_FLAG_NO_SCP) == 0) { 936 937 /* Call _SCP to set the new profile */ 938 status = acpi_SetInteger(sc->tz_handle, "_SCP", 939 (state == POWER_PROFILE_PERFORMANCE) ? 0 : 1); 940 if (ACPI_FAILURE(status)) { 941 if (status != AE_NOT_FOUND) 942 ACPI_VPRINT(sc->tz_dev, 943 acpi_device_get_parent_softc(sc->tz_dev), 944 "can't evaluate %s._SCP - %s\n", 945 acpi_name(sc->tz_handle), 946 AcpiFormatException(status)); 947 sc->tz_flags |= TZ_FLAG_NO_SCP; 948 } else { 949 /* We have to re-evaluate the entire zone now */ 950 acpi_tz_signal(sc, TZ_FLAG_GETSETTINGS); 951 } 952 } 953 } 954 955 /* 956 * Thermal zone monitor thread. 957 */ 958 static void 959 acpi_tz_thread(void *arg) 960 { 961 device_t *devs; 962 int devcount, i; 963 int flags; 964 struct acpi_tz_softc **sc; 965 966 ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); 967 968 devs = NULL; 969 devcount = 0; 970 sc = NULL; 971 get_mplock(); 972 973 for (;;) { 974 /* If the number of devices has changed, re-evaluate. */ 975 if (devclass_get_count(acpi_tz_devclass) != devcount) { 976 if (devs != NULL) { 977 kfree(devs, M_TEMP); 978 kfree(sc, M_TEMP); 979 } 980 devclass_get_devices(acpi_tz_devclass, &devs, &devcount); 981 sc = kmalloc(sizeof(struct acpi_tz_softc *) * devcount, M_TEMP, 982 M_WAITOK | M_ZERO); 983 for (i = 0; i < devcount; i++) 984 sc[i] = device_get_softc(devs[i]); 985 } 986 987 /* Check for temperature events and act on them. */ 988 for (i = 0; i < devcount; i++) { 989 ACPI_LOCK(thermal); 990 flags = sc[i]->tz_flags; 991 sc[i]->tz_flags &= TZ_FLAG_NO_SCP; 992 ACPI_UNLOCK(thermal); 993 acpi_tz_timeout(sc[i], flags); 994 } 995 996 /* If more work to do, don't go to sleep yet. */ 997 ACPI_LOCK(thermal); 998 for (i = 0; i < devcount; i++) { 999 if (sc[i]->tz_flags & ~TZ_FLAG_NO_SCP) 1000 break; 1001 } 1002 1003 /* 1004 * Interlocked sleep until signaled or we timeout. 1005 */ 1006 if (i == devcount) { 1007 tsleep_interlock(&acpi_tz_td, 0); 1008 ACPI_UNLOCK(thermal); 1009 tsleep(&acpi_tz_td, 0, "tzpoll", hz * acpi_tz_polling_rate); 1010 } else { 1011 ACPI_UNLOCK(thermal); 1012 } 1013 } 1014 rel_mplock(); 1015 } 1016 1017 #ifdef __FreeBSD__ 1018 static int 1019 acpi_tz_cpufreq_restore(struct acpi_tz_softc *sc) 1020 { 1021 device_t dev; 1022 int error; 1023 1024 if (!sc->tz_cooling_updated) 1025 return (0); 1026 if ((dev = devclass_get_device(devclass_find("cpufreq"), 0)) == NULL) 1027 return (ENXIO); 1028 ACPI_VPRINT(sc->tz_dev, acpi_device_get_parent_softc(sc->tz_dev), 1029 "temperature %d.%dC: resuming previous clock speed (%d MHz)\n", 1030 TZ_KELVTOC(sc->tz_temperature), sc->tz_cooling_saved_freq); 1031 error = CPUFREQ_SET(dev, NULL, CPUFREQ_PRIO_KERN); 1032 if (error == 0) 1033 sc->tz_cooling_updated = FALSE; 1034 return (error); 1035 } 1036 1037 static int 1038 acpi_tz_cpufreq_update(struct acpi_tz_softc *sc, int req) 1039 { 1040 device_t dev; 1041 struct cf_level *levels; 1042 int num_levels, error, freq, desired_freq, perf, i; 1043 1044 levels = kmalloc(CPUFREQ_MAX_LEVELS * sizeof(*levels), M_TEMP, M_NOWAIT); 1045 if (levels == NULL) 1046 return (ENOMEM); 1047 1048 /* 1049 * Find the main device, cpufreq0. We don't yet support independent 1050 * CPU frequency control on SMP. 1051 */ 1052 if ((dev = devclass_get_device(devclass_find("cpufreq"), 0)) == NULL) { 1053 error = ENXIO; 1054 goto out; 1055 } 1056 1057 /* Get the current frequency. */ 1058 error = CPUFREQ_GET(dev, &levels[0]); 1059 if (error) 1060 goto out; 1061 freq = levels[0].total_set.freq; 1062 1063 /* Get the current available frequency levels. */ 1064 num_levels = CPUFREQ_MAX_LEVELS; 1065 error = CPUFREQ_LEVELS(dev, levels, &num_levels); 1066 if (error) { 1067 if (error == E2BIG) 1068 printf("cpufreq: need to increase CPUFREQ_MAX_LEVELS\n"); 1069 goto out; 1070 } 1071 1072 /* Calculate the desired frequency as a percent of the max frequency. */ 1073 perf = 100 * freq / levels[0].total_set.freq - req; 1074 if (perf < 0) 1075 perf = 0; 1076 else if (perf > 100) 1077 perf = 100; 1078 desired_freq = levels[0].total_set.freq * perf / 100; 1079 1080 if (desired_freq < freq) { 1081 /* Find the closest available frequency, rounding down. */ 1082 for (i = 0; i < num_levels; i++) 1083 if (levels[i].total_set.freq <= desired_freq) 1084 break; 1085 1086 /* If we didn't find a relevant setting, use the lowest. */ 1087 if (i == num_levels) 1088 i--; 1089 } else { 1090 /* If we didn't decrease frequency yet, don't increase it. */ 1091 if (!sc->tz_cooling_updated) { 1092 sc->tz_cooling_active = FALSE; 1093 goto out; 1094 } 1095 1096 /* Use saved cpu frequency as maximum value. */ 1097 if (desired_freq > sc->tz_cooling_saved_freq) 1098 desired_freq = sc->tz_cooling_saved_freq; 1099 1100 /* Find the closest available frequency, rounding up. */ 1101 for (i = num_levels - 1; i >= 0; i--) 1102 if (levels[i].total_set.freq >= desired_freq) 1103 break; 1104 1105 /* If we didn't find a relevant setting, use the highest. */ 1106 if (i == -1) 1107 i++; 1108 1109 /* If we're going to the highest frequency, restore the old setting. */ 1110 if (i == 0 || desired_freq == sc->tz_cooling_saved_freq) { 1111 error = acpi_tz_cpufreq_restore(sc); 1112 if (error == 0) 1113 sc->tz_cooling_active = FALSE; 1114 goto out; 1115 } 1116 } 1117 1118 /* If we are going to a new frequency, activate it. */ 1119 if (levels[i].total_set.freq != freq) { 1120 ACPI_VPRINT(sc->tz_dev, acpi_device_get_parent_softc(sc->tz_dev), 1121 "temperature %d.%dC: %screasing clock speed " 1122 "from %d MHz to %d MHz\n", 1123 TZ_KELVTOC(sc->tz_temperature), 1124 (freq > levels[i].total_set.freq) ? "de" : "in", 1125 freq, levels[i].total_set.freq); 1126 error = CPUFREQ_SET(dev, &levels[i], CPUFREQ_PRIO_KERN); 1127 if (error == 0 && !sc->tz_cooling_updated) { 1128 sc->tz_cooling_saved_freq = freq; 1129 sc->tz_cooling_updated = TRUE; 1130 } 1131 } 1132 1133 out: 1134 if (levels) 1135 free(levels, M_TEMP); 1136 return (error); 1137 } 1138 #endif 1139 1140 /* 1141 * Passive cooling thread; monitors current temperature according to the 1142 * cooling interval and calculates whether to scale back CPU frequency. 1143 */ 1144 static void 1145 acpi_tz_cooling_thread(void *arg) 1146 { 1147 struct acpi_tz_softc *sc; 1148 int perf, curr_temp, prev_temp; 1149 #ifdef __FreeBSD__ 1150 int error; 1151 #endif 1152 1153 ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); 1154 1155 sc = (struct acpi_tz_softc *)arg; 1156 get_mplock(); 1157 1158 prev_temp = sc->tz_temperature; 1159 while (sc->tz_cooling_enabled) { 1160 if (sc->tz_cooling_active) 1161 (void)acpi_tz_get_temperature(sc); 1162 curr_temp = sc->tz_temperature; 1163 if (curr_temp >= sc->tz_zone.psv) 1164 sc->tz_cooling_active = TRUE; 1165 if (sc->tz_cooling_active) { 1166 perf = sc->tz_zone.tc1 * (curr_temp - prev_temp) + 1167 sc->tz_zone.tc2 * (curr_temp - sc->tz_zone.psv); 1168 perf /= 10; 1169 1170 if (perf != 0) { 1171 #ifdef __FreeBSD__ 1172 error = acpi_tz_cpufreq_update(sc, perf); 1173 1174 /* 1175 * If error and not simply a higher priority setting was 1176 * active, disable cooling. 1177 */ 1178 if (error != 0 && error != EPERM) { 1179 device_printf(sc->tz_dev, 1180 "failed to set new freq, disabling passive cooling\n"); 1181 sc->tz_cooling_enabled = FALSE; 1182 } 1183 #endif 1184 } 1185 } 1186 prev_temp = curr_temp; 1187 tsleep(&sc->tz_cooling_proc, 0, "cooling", 1188 hz * sc->tz_zone.tsp / 10); 1189 } 1190 if (sc->tz_cooling_active) { 1191 #ifdef __FreeBSD__ 1192 acpi_tz_cpufreq_restore(sc); 1193 #endif 1194 sc->tz_cooling_active = FALSE; 1195 } 1196 sc->tz_cooling_proc = NULL; 1197 ACPI_LOCK(thermal); 1198 sc->tz_cooling_proc_running = FALSE; 1199 ACPI_UNLOCK(thermal); 1200 rel_mplock(); 1201 } 1202 1203 /* 1204 * TODO: We ignore _PSL (list of cooling devices) since cpufreq enumerates 1205 * all CPUs for us. However, it's possible in the future _PSL will 1206 * reference non-CPU devices so we may want to support it then. 1207 */ 1208 static int 1209 acpi_tz_cooling_is_available(struct acpi_tz_softc *sc) 1210 { 1211 return (sc->tz_zone.tc1 != -1 && sc->tz_zone.tc2 != -1 && 1212 sc->tz_zone.tsp != -1 && sc->tz_zone.tsp != 0 && 1213 sc->tz_zone.psv != -1); 1214 } 1215 1216 static int 1217 acpi_tz_cooling_thread_start(struct acpi_tz_softc *sc) 1218 { 1219 int error; 1220 1221 ACPI_LOCK(thermal); 1222 if (sc->tz_cooling_proc_running) { 1223 ACPI_UNLOCK(thermal); 1224 return (0); 1225 } 1226 sc->tz_cooling_proc_running = TRUE; 1227 ACPI_UNLOCK(thermal); 1228 error = 0; 1229 if (sc->tz_cooling_proc == NULL) { 1230 error = kthread_create(acpi_tz_cooling_thread, sc, 1231 &sc->tz_cooling_proc, 1232 "acpi_cooling%d", device_get_unit(sc->tz_dev)); 1233 if (error != 0) { 1234 device_printf(sc->tz_dev, "could not create thread - %d", error); 1235 ACPI_LOCK(thermal); 1236 sc->tz_cooling_proc_running = FALSE; 1237 ACPI_UNLOCK(thermal); 1238 } 1239 } 1240 return (error); 1241 } 1242