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