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