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 #include "opt_acpi.h" 30 #include <sys/param.h> 31 #include <sys/eventhandler.h> 32 #include <sys/kernel.h> 33 #include <sys/bus.h> 34 #include <sys/cpu.h> 35 #include <sys/kthread.h> 36 #include <sys/malloc.h> 37 #include <sys/module.h> 38 #include <sys/proc.h> 39 #include <sys/reboot.h> 40 #include <sys/sysctl.h> 41 #include <sys/unistd.h> 42 #include <sys/power.h> 43 44 #include "cpufreq_if.h" 45 46 #include <contrib/dev/acpica/include/acpi.h> 47 #include <contrib/dev/acpica/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 2731 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/_CR3 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 int cr3; 80 ACPI_BUFFER psl; 81 int psv; 82 int tc1; 83 int tc2; 84 int tsp; 85 int tzp; 86 }; 87 88 struct 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_CR3 (1<<2) 100 #define TZ_THFLAG_HOT (1<<3) 101 #define TZ_THFLAG_CRT (1<<4) 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 /* Thermal zone 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[16]; 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 snprintf(oidname, sizeof(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, "_CR3", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE, sc, 286 offsetof(struct acpi_tz_softc, tz_zone.cr3), acpi_tz_temp_sysctl, "IK", 287 "too warm temp setpoint (standby now)"); 288 SYSCTL_ADD_PROC(&sc->tz_sysctl_ctx, SYSCTL_CHILDREN(sc->tz_sysctl_tree), 289 OID_AUTO, "_HOT", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE, sc, 290 offsetof(struct acpi_tz_softc, tz_zone.hot), acpi_tz_temp_sysctl, "IK", 291 "too hot temp setpoint (suspend now)"); 292 SYSCTL_ADD_PROC(&sc->tz_sysctl_ctx, SYSCTL_CHILDREN(sc->tz_sysctl_tree), 293 OID_AUTO, "_CRT", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE, sc, 294 offsetof(struct acpi_tz_softc, tz_zone.crt), acpi_tz_temp_sysctl, "IK", 295 "critical temp setpoint (shutdown now)"); 296 SYSCTL_ADD_PROC(&sc->tz_sysctl_ctx, SYSCTL_CHILDREN(sc->tz_sysctl_tree), 297 OID_AUTO, "_ACx", CTLTYPE_INT | CTLFLAG_RD | CTLFLAG_MPSAFE, 298 &sc->tz_zone.ac, sizeof(sc->tz_zone.ac), sysctl_handle_opaque, "IK", 299 ""); 300 SYSCTL_ADD_PROC(&sc->tz_sysctl_ctx, SYSCTL_CHILDREN(sc->tz_sysctl_tree), 301 OID_AUTO, "_TC1", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE, sc, 302 offsetof(struct acpi_tz_softc, tz_zone.tc1), acpi_tz_passive_sysctl, 303 "I", "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 | CTLFLAG_MPSAFE, sc, 306 offsetof(struct acpi_tz_softc, tz_zone.tc2), acpi_tz_passive_sysctl, 307 "I", "thermal constant 2 for passive cooling"); 308 SYSCTL_ADD_PROC(&sc->tz_sysctl_ctx, SYSCTL_CHILDREN(sc->tz_sysctl_tree), 309 OID_AUTO, "_TSP", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE, sc, 310 offsetof(struct acpi_tz_softc, tz_zone.tsp), acpi_tz_passive_sysctl, 311 "I", "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 330 static void 331 acpi_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(devclass_find("acpi_tz"), &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 } 376 SYSINIT(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 */ 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 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 acpi_tz_getparam(sc, "_CR3", &sc->tz_zone.cr3); 428 sc->tz_zone.psl.Length = ACPI_ALLOCATE_BUFFER; 429 sc->tz_zone.psl.Pointer = NULL; 430 AcpiEvaluateObject(sc->tz_handle, "_PSL", NULL, &sc->tz_zone.psl); 431 acpi_tz_getparam(sc, "_PSV", &sc->tz_zone.psv); 432 acpi_tz_getparam(sc, "_TC1", &sc->tz_zone.tc1); 433 acpi_tz_getparam(sc, "_TC2", &sc->tz_zone.tc2); 434 acpi_tz_getparam(sc, "_TSP", &sc->tz_zone.tsp); 435 acpi_tz_getparam(sc, "_TZP", &sc->tz_zone.tzp); 436 437 /* 438 * Sanity-check the values we've been given. 439 * 440 * XXX what do we do about systems that give us the same value for 441 * more than one of these setpoints? 442 */ 443 acpi_tz_sanity(sc, &sc->tz_zone.crt, "_CRT"); 444 acpi_tz_sanity(sc, &sc->tz_zone.hot, "_HOT"); 445 acpi_tz_sanity(sc, &sc->tz_zone.cr3, "_CR3"); 446 acpi_tz_sanity(sc, &sc->tz_zone.psv, "_PSV"); 447 for (i = 0; i < TZ_NUMLEVELS; i++) 448 acpi_tz_sanity(sc, &sc->tz_zone.ac[i], "_ACx"); 449 450 return_VALUE (0); 451 } 452 453 static char *aclevel_string[] = { 454 "NONE", "_AC0", "_AC1", "_AC2", "_AC3", "_AC4", 455 "_AC5", "_AC6", "_AC7", "_AC8", "_AC9" 456 }; 457 458 static __inline const char * 459 acpi_tz_aclevel_string(int active) 460 { 461 if (active < -1 || active >= TZ_NUMLEVELS) 462 return (aclevel_string[0]); 463 464 return (aclevel_string[active + 1]); 465 } 466 467 /* 468 * Get the current temperature. 469 */ 470 static int 471 acpi_tz_get_temperature(struct acpi_tz_softc *sc) 472 { 473 int temp; 474 ACPI_STATUS status; 475 476 ACPI_FUNCTION_NAME ("acpi_tz_get_temperature"); 477 478 /* Evaluate the thermal zone's _TMP method. */ 479 status = acpi_GetInteger(sc->tz_handle, acpi_tz_tmp_name, &temp); 480 if (ACPI_FAILURE(status)) { 481 ACPI_VPRINT(sc->tz_dev, acpi_device_get_parent_softc(sc->tz_dev), 482 "error fetching current temperature -- %s\n", 483 AcpiFormatException(status)); 484 return (FALSE); 485 } 486 487 /* Check it for validity. */ 488 acpi_tz_sanity(sc, &temp, acpi_tz_tmp_name); 489 if (temp == -1) 490 return (FALSE); 491 492 ACPI_DEBUG_PRINT((ACPI_DB_VALUES, "got %d.%dC\n", TZ_KELVTOC(temp))); 493 sc->tz_temperature = temp; 494 return (TRUE); 495 } 496 497 /* 498 * Evaluate the condition of a thermal zone, take appropriate actions. 499 */ 500 static void 501 acpi_tz_monitor(void *Context) 502 { 503 struct acpi_softc *acpi_sc; 504 struct acpi_tz_softc *sc; 505 struct timespec curtime; 506 int temp; 507 int i; 508 int newactive, newflags; 509 510 ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); 511 512 sc = (struct acpi_tz_softc *)Context; 513 514 /* Get the current temperature. */ 515 if (!acpi_tz_get_temperature(sc)) { 516 /* XXX disable zone? go to max cooling? */ 517 return_VOID; 518 } 519 temp = sc->tz_temperature; 520 521 /* 522 * Work out what we ought to be doing right now. 523 * 524 * Note that the _ACx levels sort from hot to cold. 525 */ 526 newactive = TZ_ACTIVE_NONE; 527 for (i = TZ_NUMLEVELS - 1; i >= 0; i--) { 528 if (sc->tz_zone.ac[i] != -1 && temp >= sc->tz_zone.ac[i]) 529 newactive = i; 530 } 531 532 /* 533 * We are going to get _ACx level down (colder side), but give a guaranteed 534 * minimum cooling run time if requested. 535 */ 536 if (acpi_tz_min_runtime > 0 && sc->tz_active != TZ_ACTIVE_NONE && 537 sc->tz_active != TZ_ACTIVE_UNKNOWN && 538 (newactive == TZ_ACTIVE_NONE || newactive > sc->tz_active)) { 539 getnanotime(&curtime); 540 timespecsub(&curtime, &sc->tz_cooling_started, &curtime); 541 if (curtime.tv_sec < acpi_tz_min_runtime) 542 newactive = sc->tz_active; 543 } 544 545 /* Handle user override of active mode */ 546 if (sc->tz_requested != TZ_ACTIVE_NONE && (newactive == TZ_ACTIVE_NONE 547 || sc->tz_requested < newactive)) 548 newactive = sc->tz_requested; 549 550 /* update temperature-related flags */ 551 newflags = TZ_THFLAG_NONE; 552 if (sc->tz_zone.psv != -1 && temp >= sc->tz_zone.psv) 553 newflags |= TZ_THFLAG_PSV; 554 if (sc->tz_zone.cr3 != -1 && temp >= sc->tz_zone.cr3) 555 newflags |= TZ_THFLAG_CR3; 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_CR3 | 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 if ((newflags & (TZ_THFLAG_HOT | TZ_THFLAG_CRT)) != 0) 622 shutdown_nice(RB_POWEROFF); 623 else { 624 acpi_sc = acpi_device_get_parent_softc(sc->tz_dev); 625 acpi_ReqSleepState(acpi_sc, ACPI_STATE_S3); 626 } 627 } else if (sc->tz_validchecks == TZ_NOTIFYCOUNT) 628 acpi_UserNotify("Thermal", sc->tz_handle, TZ_NOTIFY_CRITICAL); 629 } else { 630 sc->tz_validchecks = 0; 631 } 632 sc->tz_thflags = newflags; 633 634 return_VOID; 635 } 636 637 /* 638 * Given an object, verify that it's a reference to a device of some sort, 639 * and try to switch it off. 640 */ 641 static void 642 acpi_tz_switch_cooler_off(ACPI_OBJECT *obj, void *arg) 643 { 644 ACPI_HANDLE cooler; 645 646 ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); 647 648 cooler = acpi_GetReference(NULL, obj); 649 if (cooler == NULL) { 650 ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "can't get handle\n")); 651 return_VOID; 652 } 653 654 ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "called to turn %s off\n", 655 acpi_name(cooler))); 656 acpi_pwr_switch_consumer(cooler, ACPI_STATE_D3); 657 658 return_VOID; 659 } 660 661 /* 662 * Given an object, verify that it's a reference to a device of some sort, 663 * and try to switch it on. 664 * 665 * XXX replication of off/on function code is bad. 666 */ 667 static void 668 acpi_tz_switch_cooler_on(ACPI_OBJECT *obj, void *arg) 669 { 670 struct acpi_tz_softc *sc = (struct acpi_tz_softc *)arg; 671 ACPI_HANDLE cooler; 672 ACPI_STATUS status; 673 674 ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); 675 676 cooler = acpi_GetReference(NULL, obj); 677 if (cooler == NULL) { 678 ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "can't get handle\n")); 679 return_VOID; 680 } 681 682 ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "called to turn %s on\n", 683 acpi_name(cooler))); 684 status = acpi_pwr_switch_consumer(cooler, ACPI_STATE_D0); 685 if (ACPI_FAILURE(status)) { 686 ACPI_VPRINT(sc->tz_dev, acpi_device_get_parent_softc(sc->tz_dev), 687 "failed to activate %s - %s\n", acpi_name(cooler), 688 AcpiFormatException(status)); 689 } 690 691 return_VOID; 692 } 693 694 /* 695 * Read/debug-print a parameter, default it to -1. 696 */ 697 static void 698 acpi_tz_getparam(struct acpi_tz_softc *sc, char *node, int *data) 699 { 700 701 ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); 702 703 if (ACPI_FAILURE(acpi_GetInteger(sc->tz_handle, node, data))) { 704 *data = -1; 705 } else { 706 ACPI_DEBUG_PRINT((ACPI_DB_VALUES, "%s.%s = %d\n", 707 acpi_name(sc->tz_handle), node, *data)); 708 } 709 710 return_VOID; 711 } 712 713 /* 714 * Sanity-check a temperature value. Assume that setpoints 715 * should be between 0C and 200C. 716 */ 717 static void 718 acpi_tz_sanity(struct acpi_tz_softc *sc, int *val, char *what) 719 { 720 if (*val != -1 && (*val < TZ_ZEROC || *val > TZ_ZEROC + 2000)) { 721 /* 722 * If the value we are checking is _TMP, warn the user only 723 * once. This avoids spamming messages if, for instance, the 724 * sensor is broken and always returns an invalid temperature. 725 * 726 * This is only done for _TMP; other values always emit a 727 * warning. 728 */ 729 if (what != acpi_tz_tmp_name || !sc->tz_insane_tmp_notified) { 730 device_printf(sc->tz_dev, "%s value is absurd, ignored (%d.%dC)\n", 731 what, TZ_KELVTOC(*val)); 732 733 /* Don't warn the user again if the read value doesn't improve. */ 734 if (what == acpi_tz_tmp_name) 735 sc->tz_insane_tmp_notified = 1; 736 } 737 *val = -1; 738 return; 739 } 740 741 /* This value is correct. Warn if it's incorrect again. */ 742 if (what == acpi_tz_tmp_name) 743 sc->tz_insane_tmp_notified = 0; 744 } 745 746 /* 747 * Respond to a sysctl on the active state node. 748 */ 749 static int 750 acpi_tz_active_sysctl(SYSCTL_HANDLER_ARGS) 751 { 752 struct acpi_tz_softc *sc; 753 int active; 754 int error; 755 756 sc = (struct acpi_tz_softc *)oidp->oid_arg1; 757 active = sc->tz_active; 758 error = sysctl_handle_int(oidp, &active, 0, req); 759 760 /* Error or no new value */ 761 if (error != 0 || req->newptr == NULL) 762 return (error); 763 if (active < -1 || active >= TZ_NUMLEVELS) 764 return (EINVAL); 765 766 /* Set new preferred level and re-switch */ 767 sc->tz_requested = active; 768 acpi_tz_signal(sc, 0); 769 return (0); 770 } 771 772 static int 773 acpi_tz_cooling_sysctl(SYSCTL_HANDLER_ARGS) 774 { 775 struct acpi_tz_softc *sc; 776 int enabled, error; 777 778 sc = (struct acpi_tz_softc *)oidp->oid_arg1; 779 enabled = sc->tz_cooling_enabled; 780 error = sysctl_handle_int(oidp, &enabled, 0, req); 781 782 /* Error or no new value */ 783 if (error != 0 || req->newptr == NULL) 784 return (error); 785 if (enabled != TRUE && enabled != FALSE) 786 return (EINVAL); 787 788 if (enabled) { 789 if (acpi_tz_cooling_is_available(sc)) 790 error = acpi_tz_cooling_thread_start(sc); 791 else 792 error = ENODEV; 793 if (error) 794 enabled = FALSE; 795 } 796 sc->tz_cooling_enabled = enabled; 797 return (error); 798 } 799 800 static int 801 acpi_tz_temp_sysctl(SYSCTL_HANDLER_ARGS) 802 { 803 struct acpi_tz_softc *sc; 804 int temp, *temp_ptr; 805 int error; 806 807 sc = oidp->oid_arg1; 808 temp_ptr = (int *)(void *)(uintptr_t)((uintptr_t)sc + oidp->oid_arg2); 809 temp = *temp_ptr; 810 error = sysctl_handle_int(oidp, &temp, 0, req); 811 812 /* Error or no new value */ 813 if (error != 0 || req->newptr == NULL) 814 return (error); 815 816 /* Only allow changing settings if override is set. */ 817 if (!acpi_tz_override) 818 return (EPERM); 819 820 /* Check user-supplied value for sanity. */ 821 acpi_tz_sanity(sc, &temp, "user-supplied temp"); 822 if (temp == -1) 823 return (EINVAL); 824 825 *temp_ptr = temp; 826 return (0); 827 } 828 829 static int 830 acpi_tz_passive_sysctl(SYSCTL_HANDLER_ARGS) 831 { 832 struct acpi_tz_softc *sc; 833 int val, *val_ptr; 834 int error; 835 836 sc = oidp->oid_arg1; 837 val_ptr = (int *)(void *)(uintptr_t)((uintptr_t)sc + oidp->oid_arg2); 838 val = *val_ptr; 839 error = sysctl_handle_int(oidp, &val, 0, req); 840 841 /* Error or no new value */ 842 if (error != 0 || req->newptr == NULL) 843 return (error); 844 845 /* Only allow changing settings if override is set. */ 846 if (!acpi_tz_override) 847 return (EPERM); 848 849 *val_ptr = val; 850 return (0); 851 } 852 853 static void 854 acpi_tz_notify_handler(ACPI_HANDLE h, UINT32 notify, void *context) 855 { 856 struct acpi_tz_softc *sc = (struct acpi_tz_softc *)context; 857 858 ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); 859 860 switch (notify) { 861 case TZ_NOTIFY_TEMPERATURE: 862 /* Temperature change occurred */ 863 acpi_tz_signal(sc, 0); 864 break; 865 case TZ_NOTIFY_DEVICES: 866 case TZ_NOTIFY_LEVELS: 867 /* Zone devices/setpoints changed */ 868 acpi_tz_signal(sc, TZ_FLAG_GETSETTINGS); 869 break; 870 default: 871 ACPI_VPRINT(sc->tz_dev, acpi_device_get_parent_softc(sc->tz_dev), 872 "unknown Notify event 0x%x\n", notify); 873 break; 874 } 875 876 acpi_UserNotify("Thermal", h, notify); 877 878 return_VOID; 879 } 880 881 static void 882 acpi_tz_signal(struct acpi_tz_softc *sc, int flags) 883 { 884 ACPI_LOCK(thermal); 885 sc->tz_flags |= flags; 886 ACPI_UNLOCK(thermal); 887 wakeup(&acpi_tz_proc); 888 } 889 890 /* 891 * Notifies can be generated asynchronously but have also been seen to be 892 * triggered by other thermal methods. One system generates a notify of 893 * 0x81 when the fan is turned on or off. Another generates it when _SCP 894 * is called. To handle these situations, we check the zone via 895 * acpi_tz_monitor() before evaluating changes to setpoints or the cooling 896 * policy. 897 */ 898 static void 899 acpi_tz_timeout(struct acpi_tz_softc *sc, int flags) 900 { 901 902 /* Check the current temperature and take action based on it */ 903 acpi_tz_monitor(sc); 904 905 /* If requested, get the power profile settings. */ 906 if (flags & TZ_FLAG_GETPROFILE) 907 acpi_tz_power_profile(sc); 908 909 /* 910 * If requested, check for new devices/setpoints. After finding them, 911 * check if we need to switch fans based on the new values. 912 */ 913 if (flags & TZ_FLAG_GETSETTINGS) { 914 acpi_tz_establish(sc); 915 acpi_tz_monitor(sc); 916 } 917 918 /* XXX passive cooling actions? */ 919 } 920 921 /* 922 * System power profile may have changed; fetch and notify the 923 * thermal zone accordingly. 924 * 925 * Since this can be called from an arbitrary eventhandler, it needs 926 * to get the ACPI lock itself. 927 */ 928 static void 929 acpi_tz_power_profile(void *arg) 930 { 931 ACPI_STATUS status; 932 struct acpi_tz_softc *sc = (struct acpi_tz_softc *)arg; 933 int state; 934 935 state = power_profile_get_state(); 936 if (state != POWER_PROFILE_PERFORMANCE && state != POWER_PROFILE_ECONOMY) 937 return; 938 939 /* check that we haven't decided there's no _SCP method */ 940 if ((sc->tz_flags & TZ_FLAG_NO_SCP) == 0) { 941 /* Call _SCP to set the new profile */ 942 status = acpi_SetInteger(sc->tz_handle, "_SCP", 943 (state == POWER_PROFILE_PERFORMANCE) ? 0 : 1); 944 if (ACPI_FAILURE(status)) { 945 if (status != AE_NOT_FOUND) 946 ACPI_VPRINT(sc->tz_dev, 947 acpi_device_get_parent_softc(sc->tz_dev), 948 "can't evaluate %s._SCP - %s\n", 949 acpi_name(sc->tz_handle), 950 AcpiFormatException(status)); 951 sc->tz_flags |= TZ_FLAG_NO_SCP; 952 } else { 953 /* We have to re-evaluate the entire zone now */ 954 acpi_tz_signal(sc, TZ_FLAG_GETSETTINGS); 955 } 956 } 957 } 958 959 /* 960 * Thermal zone monitor thread. 961 */ 962 static void 963 acpi_tz_thread(void *arg) 964 { 965 devclass_t acpi_tz_devclass; 966 device_t *devs; 967 int devcount, i; 968 int flags; 969 struct acpi_tz_softc **sc; 970 971 ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); 972 973 acpi_tz_devclass = devclass_find("acpi_tz"); 974 devs = NULL; 975 devcount = 0; 976 sc = NULL; 977 978 for (;;) { 979 /* If the number of devices has changed, re-evaluate. */ 980 if (devclass_get_count(acpi_tz_devclass) != devcount) { 981 if (devs != NULL) { 982 free(devs, M_TEMP); 983 free(sc, M_TEMP); 984 } 985 devclass_get_devices(acpi_tz_devclass, &devs, &devcount); 986 sc = malloc(sizeof(struct acpi_tz_softc *) * devcount, M_TEMP, 987 M_WAITOK | M_ZERO); 988 for (i = 0; i < devcount; i++) 989 sc[i] = device_get_softc(devs[i]); 990 } 991 992 /* Check for temperature events and act on them. */ 993 for (i = 0; i < devcount; i++) { 994 ACPI_LOCK(thermal); 995 flags = sc[i]->tz_flags; 996 sc[i]->tz_flags &= TZ_FLAG_NO_SCP; 997 ACPI_UNLOCK(thermal); 998 acpi_tz_timeout(sc[i], flags); 999 } 1000 1001 /* If more work to do, don't go to sleep yet. */ 1002 ACPI_LOCK(thermal); 1003 for (i = 0; i < devcount; i++) { 1004 if (sc[i]->tz_flags & ~TZ_FLAG_NO_SCP) 1005 break; 1006 } 1007 1008 /* 1009 * If we have no more work, sleep for a while, setting PDROP so that 1010 * the mutex will not be reacquired. Otherwise, drop the mutex and 1011 * loop to handle more events. 1012 */ 1013 if (i == devcount) 1014 msleep(&acpi_tz_proc, &thermal_mutex, PZERO | PDROP, "tzpoll", 1015 hz * acpi_tz_polling_rate); 1016 else 1017 ACPI_UNLOCK(thermal); 1018 } 1019 } 1020 1021 static int 1022 acpi_tz_cpufreq_restore(struct acpi_tz_softc *sc) 1023 { 1024 device_t dev; 1025 int error; 1026 1027 if (!sc->tz_cooling_updated) 1028 return (0); 1029 if ((dev = devclass_get_device(devclass_find("cpufreq"), 0)) == NULL) 1030 return (ENXIO); 1031 ACPI_VPRINT(sc->tz_dev, acpi_device_get_parent_softc(sc->tz_dev), 1032 "temperature %d.%dC: resuming previous clock speed (%d MHz)\n", 1033 TZ_KELVTOC(sc->tz_temperature), sc->tz_cooling_saved_freq); 1034 error = CPUFREQ_SET(dev, NULL, CPUFREQ_PRIO_KERN); 1035 if (error == 0) 1036 sc->tz_cooling_updated = FALSE; 1037 return (error); 1038 } 1039 1040 static int 1041 acpi_tz_cpufreq_update(struct acpi_tz_softc *sc, int req) 1042 { 1043 device_t dev; 1044 struct cf_level *levels; 1045 int num_levels, error, freq, desired_freq, perf, i; 1046 1047 levels = malloc(CPUFREQ_MAX_LEVELS * sizeof(*levels), M_TEMP, M_NOWAIT); 1048 if (levels == NULL) 1049 return (ENOMEM); 1050 1051 /* 1052 * Find the main device, cpufreq0. We don't yet support independent 1053 * CPU frequency control on SMP. 1054 */ 1055 if ((dev = devclass_get_device(devclass_find("cpufreq"), 0)) == NULL) { 1056 error = ENXIO; 1057 goto out; 1058 } 1059 1060 /* Get the current frequency. */ 1061 error = CPUFREQ_GET(dev, &levels[0]); 1062 if (error) 1063 goto out; 1064 freq = levels[0].total_set.freq; 1065 1066 /* Get the current available frequency levels. */ 1067 num_levels = CPUFREQ_MAX_LEVELS; 1068 error = CPUFREQ_LEVELS(dev, levels, &num_levels); 1069 if (error) { 1070 if (error == E2BIG) 1071 printf("cpufreq: need to increase CPUFREQ_MAX_LEVELS\n"); 1072 goto out; 1073 } 1074 1075 /* Calculate the desired frequency as a percent of the max frequency. */ 1076 perf = 100 * freq / levels[0].total_set.freq - req; 1077 if (perf < 0) 1078 perf = 0; 1079 else if (perf > 100) 1080 perf = 100; 1081 desired_freq = levels[0].total_set.freq * perf / 100; 1082 1083 if (desired_freq < freq) { 1084 /* Find the closest available frequency, rounding down. */ 1085 for (i = 0; i < num_levels; i++) 1086 if (levels[i].total_set.freq <= desired_freq) 1087 break; 1088 1089 /* If we didn't find a relevant setting, use the lowest. */ 1090 if (i == num_levels) 1091 i--; 1092 } else { 1093 /* If we didn't decrease frequency yet, don't increase it. */ 1094 if (!sc->tz_cooling_updated) { 1095 sc->tz_cooling_active = FALSE; 1096 goto out; 1097 } 1098 1099 /* Use saved cpu frequency as maximum value. */ 1100 if (desired_freq > sc->tz_cooling_saved_freq) 1101 desired_freq = sc->tz_cooling_saved_freq; 1102 1103 /* Find the closest available frequency, rounding up. */ 1104 for (i = num_levels - 1; i >= 0; i--) 1105 if (levels[i].total_set.freq >= desired_freq) 1106 break; 1107 1108 /* If we didn't find a relevant setting, use the highest. */ 1109 if (i == -1) 1110 i++; 1111 1112 /* If we're going to the highest frequency, restore the old setting. */ 1113 if (i == 0 || desired_freq == sc->tz_cooling_saved_freq) { 1114 error = acpi_tz_cpufreq_restore(sc); 1115 if (error == 0) 1116 sc->tz_cooling_active = FALSE; 1117 goto out; 1118 } 1119 } 1120 1121 /* If we are going to a new frequency, activate it. */ 1122 if (levels[i].total_set.freq != freq) { 1123 ACPI_VPRINT(sc->tz_dev, acpi_device_get_parent_softc(sc->tz_dev), 1124 "temperature %d.%dC: %screasing clock speed " 1125 "from %d MHz to %d MHz\n", 1126 TZ_KELVTOC(sc->tz_temperature), 1127 (freq > levels[i].total_set.freq) ? "de" : "in", 1128 freq, levels[i].total_set.freq); 1129 error = CPUFREQ_SET(dev, &levels[i], CPUFREQ_PRIO_KERN); 1130 if (error == 0 && !sc->tz_cooling_updated) { 1131 sc->tz_cooling_saved_freq = freq; 1132 sc->tz_cooling_updated = TRUE; 1133 } 1134 } 1135 1136 out: 1137 if (levels) 1138 free(levels, M_TEMP); 1139 return (error); 1140 } 1141 1142 /* 1143 * Passive cooling thread; monitors current temperature according to the 1144 * cooling interval and calculates whether to scale back CPU frequency. 1145 */ 1146 static void 1147 acpi_tz_cooling_thread(void *arg) 1148 { 1149 struct acpi_tz_softc *sc; 1150 int error, perf, curr_temp, prev_temp; 1151 1152 ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); 1153 1154 sc = (struct acpi_tz_softc *)arg; 1155 1156 prev_temp = sc->tz_temperature; 1157 while (sc->tz_cooling_enabled) { 1158 if (sc->tz_cooling_active) 1159 (void)acpi_tz_get_temperature(sc); 1160 curr_temp = sc->tz_temperature; 1161 if (curr_temp >= sc->tz_zone.psv) 1162 sc->tz_cooling_active = TRUE; 1163 if (sc->tz_cooling_active) { 1164 perf = sc->tz_zone.tc1 * (curr_temp - prev_temp) + 1165 sc->tz_zone.tc2 * (curr_temp - sc->tz_zone.psv); 1166 perf /= 10; 1167 1168 if (perf != 0) { 1169 error = acpi_tz_cpufreq_update(sc, perf); 1170 1171 /* 1172 * If error and not simply a higher priority setting was 1173 * active, disable cooling. 1174 */ 1175 if (error != 0 && error != EPERM) { 1176 device_printf(sc->tz_dev, 1177 "failed to set new freq, disabling passive cooling\n"); 1178 sc->tz_cooling_enabled = FALSE; 1179 } 1180 } 1181 } 1182 prev_temp = curr_temp; 1183 tsleep(&sc->tz_cooling_proc, PZERO, "cooling", 1184 hz * sc->tz_zone.tsp / 10); 1185 } 1186 if (sc->tz_cooling_active) { 1187 acpi_tz_cpufreq_restore(sc); 1188 sc->tz_cooling_active = FALSE; 1189 } 1190 sc->tz_cooling_proc = NULL; 1191 ACPI_LOCK(thermal); 1192 sc->tz_cooling_proc_running = FALSE; 1193 ACPI_UNLOCK(thermal); 1194 kproc_exit(0); 1195 } 1196 1197 /* 1198 * TODO: We ignore _PSL (list of cooling devices) since cpufreq enumerates 1199 * all CPUs for us. However, it's possible in the future _PSL will 1200 * reference non-CPU devices so we may want to support it then. 1201 */ 1202 static int 1203 acpi_tz_cooling_is_available(struct acpi_tz_softc *sc) 1204 { 1205 return (sc->tz_zone.tc1 != -1 && sc->tz_zone.tc2 != -1 && 1206 sc->tz_zone.tsp != -1 && sc->tz_zone.tsp != 0 && 1207 sc->tz_zone.psv != -1); 1208 } 1209 1210 static int 1211 acpi_tz_cooling_thread_start(struct acpi_tz_softc *sc) 1212 { 1213 int error; 1214 1215 ACPI_LOCK(thermal); 1216 if (sc->tz_cooling_proc_running) { 1217 ACPI_UNLOCK(thermal); 1218 return (0); 1219 } 1220 sc->tz_cooling_proc_running = TRUE; 1221 ACPI_UNLOCK(thermal); 1222 error = 0; 1223 if (sc->tz_cooling_proc == NULL) { 1224 error = kproc_create(acpi_tz_cooling_thread, sc, 1225 &sc->tz_cooling_proc, RFHIGHPID, 0, "acpi_cooling%d", 1226 device_get_unit(sc->tz_dev)); 1227 if (error != 0) { 1228 device_printf(sc->tz_dev, "could not create thread - %d", error); 1229 ACPI_LOCK(thermal); 1230 sc->tz_cooling_proc_running = FALSE; 1231 ACPI_UNLOCK(thermal); 1232 } 1233 } 1234 return (error); 1235 } 1236