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