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