acpi_thermal.c (aad970f1fee9a2a3e5a0f880be9b87c6193b3bd1) | acpi_thermal.c (be2b179704218e240b66f023545f8e97d4c29a08) |
---|---|
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: --- 26 unchanged lines hidden (view full) --- 35#include <sys/bus.h> 36#include <sys/proc.h> 37#include <sys/reboot.h> 38#include <sys/sysctl.h> 39#include <sys/unistd.h> 40#include <sys/power.h> 41 42#include "acpi.h" | 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: --- 26 unchanged lines hidden (view full) --- 35#include <sys/bus.h> 36#include <sys/proc.h> 37#include <sys/reboot.h> 38#include <sys/sysctl.h> 39#include <sys/unistd.h> 40#include <sys/power.h> 41 42#include "acpi.h" |
43 | |
44#include <dev/acpica/acpivar.h> 45 | 43#include <dev/acpica/acpivar.h> 44 |
46/* 47 * Hooks for the ACPI CA debugging infrastructure 48 */ | 45/* Hooks for the ACPI CA debugging infrastructure */ |
49#define _COMPONENT ACPI_THERMAL 50ACPI_MODULE_NAME("THERMAL") 51 52#define TZ_ZEROC 2732 53#define TZ_KELVTOC(x) (((x) - TZ_ZEROC) / 10), (((x) - TZ_ZEROC) % 10) 54 55#define TZ_NOTIFY_TEMPERATURE 0x80 56#define TZ_NOTIFY_DEVICES 0x81 57#define TZ_NOTIFY_LEVELS 0x82 58 | 46#define _COMPONENT ACPI_THERMAL 47ACPI_MODULE_NAME("THERMAL") 48 49#define TZ_ZEROC 2732 50#define TZ_KELVTOC(x) (((x) - TZ_ZEROC) / 10), (((x) - TZ_ZEROC) % 10) 51 52#define TZ_NOTIFY_TEMPERATURE 0x80 53#define TZ_NOTIFY_DEVICES 0x81 54#define TZ_NOTIFY_LEVELS 0x82 55 |
59#define TZ_POLLRATE 30 /* every 30 seconds by default */ | 56/* Check for temperature changes every 30 seconds by default */ 57#define TZ_POLLRATE 30 |
60 | 58 |
61#define TZ_NUMLEVELS 10 /* defined by ACPI spec */ | 59/* ACPI spec defines this */ 60#define TZ_NUMLEVELS 10 |
62struct acpi_tz_zone { 63 int ac[TZ_NUMLEVELS]; 64 ACPI_BUFFER al[TZ_NUMLEVELS]; 65 int crt; 66 int hot; 67 ACPI_BUFFER psl; 68 int psv; 69 int tc1; 70 int tc2; 71 int tsp; 72 int tzp; 73}; 74 75 76struct acpi_tz_softc { | 61struct acpi_tz_zone { 62 int ac[TZ_NUMLEVELS]; 63 ACPI_BUFFER al[TZ_NUMLEVELS]; 64 int crt; 65 int hot; 66 ACPI_BUFFER psl; 67 int psv; 68 int tc1; 69 int tc2; 70 int tsp; 71 int tzp; 72}; 73 74 75struct acpi_tz_softc { |
77 device_t tz_dev; /* device handle */ 78 ACPI_HANDLE tz_handle; /* thermal zone handle */ 79 int tz_temperature; /* current temperature */ 80 int tz_active; /* current active cooling */ | 76 device_t tz_dev; 77 ACPI_HANDLE tz_handle; /*Thermal zone handle*/ 78 int tz_temperature; /*Current temperature*/ 79 int tz_active; /*Current active cooling*/ |
81#define TZ_ACTIVE_NONE -1 | 80#define TZ_ACTIVE_NONE -1 |
82 int tz_requested; /* user-requested minimum active cooling */ 83 int tz_thflags; /* current temperature-related flags */ | 81 int tz_requested; /*Minimum active cooling*/ 82 int tz_thflags; /*Current temp-related flags*/ |
84#define TZ_THFLAG_NONE 0 85#define TZ_THFLAG_PSV (1<<0) 86#define TZ_THFLAG_HOT (1<<2) 87#define TZ_THFLAG_CRT (1<<3) 88 int tz_flags; | 83#define TZ_THFLAG_NONE 0 84#define TZ_THFLAG_PSV (1<<0) 85#define TZ_THFLAG_HOT (1<<2) 86#define TZ_THFLAG_CRT (1<<3) 87 int tz_flags; |
89#define TZ_FLAG_NO_SCP (1<<0) /* no _SCP method */ 90#define TZ_FLAG_GETPROFILE (1<<1) /* fetch power_profile in timeout */ 91 struct timespec tz_cooling_started; /* current cooling starting time */ | 88#define TZ_FLAG_NO_SCP (1<<0) /*No _SCP method*/ 89#define TZ_FLAG_GETPROFILE (1<<1) /*Get power_profile in timeout*/ 90 struct timespec tz_cooling_started; 91 /*Current cooling starting time*/ |
92 | 92 |
93 struct sysctl_ctx_list tz_sysctl_ctx; /* sysctl tree */ | 93 struct sysctl_ctx_list tz_sysctl_ctx; |
94 struct sysctl_oid *tz_sysctl_tree; 95 | 94 struct sysctl_oid *tz_sysctl_tree; 95 |
96 struct acpi_tz_zone tz_zone; /* thermal zone parameters */ | 96 struct acpi_tz_zone tz_zone; /*Thermal zone parameters*/ |
97 int tz_tmp_updating; 98}; 99 100static int acpi_tz_probe(device_t dev); 101static int acpi_tz_attach(device_t dev); 102static int acpi_tz_establish(struct acpi_tz_softc *sc); | 97 int tz_tmp_updating; 98}; 99 100static int acpi_tz_probe(device_t dev); 101static int acpi_tz_attach(device_t dev); 102static int acpi_tz_establish(struct acpi_tz_softc *sc); |
103static void acpi_tz_monitor(struct acpi_tz_softc *sc); | 103static void acpi_tz_monitor(void *Context); |
104static void acpi_tz_all_off(struct acpi_tz_softc *sc); 105static void acpi_tz_switch_cooler_off(ACPI_OBJECT *obj, void *arg); 106static void acpi_tz_switch_cooler_on(ACPI_OBJECT *obj, void *arg); | 104static void acpi_tz_all_off(struct acpi_tz_softc *sc); 105static void acpi_tz_switch_cooler_off(ACPI_OBJECT *obj, void *arg); 106static void acpi_tz_switch_cooler_on(ACPI_OBJECT *obj, void *arg); |
107static void acpi_tz_getparam(struct acpi_tz_softc *sc, char *node, int *data); | 107static void acpi_tz_getparam(struct acpi_tz_softc *sc, char *node, 108 int *data); |
108static void acpi_tz_sanity(struct acpi_tz_softc *sc, int *val, char *what); 109static int acpi_tz_active_sysctl(SYSCTL_HANDLER_ARGS); | 109static void acpi_tz_sanity(struct acpi_tz_softc *sc, int *val, char *what); 110static int acpi_tz_active_sysctl(SYSCTL_HANDLER_ARGS); |
110static void acpi_tz_notify_handler(ACPI_HANDLE h, UINT32 notify, void *context); | 111static void acpi_tz_notify_handler(ACPI_HANDLE h, UINT32 notify, 112 void *context); |
111static void acpi_tz_timeout(struct acpi_tz_softc *sc); 112static void acpi_tz_power_profile(void *arg); | 113static void acpi_tz_timeout(struct acpi_tz_softc *sc); 114static void acpi_tz_power_profile(void *arg); |
113 | |
114static void acpi_tz_thread(void *arg); | 115static void acpi_tz_thread(void *arg); |
115static struct proc *acpi_tz_proc; | |
116 117static device_method_t acpi_tz_methods[] = { 118 /* Device interface */ 119 DEVMETHOD(device_probe, acpi_tz_probe), 120 DEVMETHOD(device_attach, acpi_tz_attach), 121 122 {0, 0} 123}; --- 5 unchanged lines hidden (view full) --- 129}; 130 131static devclass_t acpi_tz_devclass; 132DRIVER_MODULE(acpi_tz, acpi, acpi_tz_driver, acpi_tz_devclass, 0, 0); 133 134static struct sysctl_ctx_list acpi_tz_sysctl_ctx; 135static struct sysctl_oid *acpi_tz_sysctl_tree; 136 | 116 117static device_method_t acpi_tz_methods[] = { 118 /* Device interface */ 119 DEVMETHOD(device_probe, acpi_tz_probe), 120 DEVMETHOD(device_attach, acpi_tz_attach), 121 122 {0, 0} 123}; --- 5 unchanged lines hidden (view full) --- 129}; 130 131static devclass_t acpi_tz_devclass; 132DRIVER_MODULE(acpi_tz, acpi, acpi_tz_driver, acpi_tz_devclass, 0, 0); 133 134static struct sysctl_ctx_list acpi_tz_sysctl_ctx; 135static struct sysctl_oid *acpi_tz_sysctl_tree; 136 |
137static int acpi_tz_min_runtime = 0;/* minimum cooling run time */ | 137/* Minimum cooling run time */ 138static int acpi_tz_min_runtime = 0; |
138static int acpi_tz_polling_rate = TZ_POLLRATE; 139 | 139static int acpi_tz_polling_rate = TZ_POLLRATE; 140 |
141/* Timezone polling thread */ 142static struct proc *acpi_tz_proc; 143 |
|
140/* 141 * Match an ACPI thermal zone. 142 */ 143static int 144acpi_tz_probe(device_t dev) 145{ 146 int result; 147 ACPI_LOCK_DECL; 148 149 ACPI_LOCK; 150 | 144/* 145 * Match an ACPI thermal zone. 146 */ 147static int 148acpi_tz_probe(device_t dev) 149{ 150 int result; 151 ACPI_LOCK_DECL; 152 153 ACPI_LOCK; 154 |
151 /* no FUNCTION_TRACE - too noisy */ | 155 /* No FUNCTION_TRACE - too noisy */ |
152 | 156 |
153 if ((acpi_get_type(dev) == ACPI_TYPE_THERMAL) && 154 !acpi_disabled("thermal")) { | 157 if (acpi_get_type(dev) == ACPI_TYPE_THERMAL && !acpi_disabled("thermal")) { |
155 device_set_desc(dev, "thermal zone"); 156 result = -10; 157 } else { 158 result = ENXIO; 159 } 160 ACPI_UNLOCK; | 158 device_set_desc(dev, "thermal zone"); 159 result = -10; 160 } else { 161 result = ENXIO; 162 } 163 ACPI_UNLOCK; |
161 return(result); | 164 return (result); |
162} 163 164/* 165 * Attach to an ACPI thermal zone. 166 */ 167static int 168acpi_tz_attach(device_t dev) 169{ --- 30 unchanged lines hidden (view full) --- 200 * Create our sysctl nodes. 201 * 202 * XXX we need a mechanism for adding nodes under ACPI. 203 */ 204 if (device_get_unit(dev) == 0) { 205 acpi_sc = acpi_device_get_parent_softc(dev); 206 sysctl_ctx_init(&acpi_tz_sysctl_ctx); 207 acpi_tz_sysctl_tree = SYSCTL_ADD_NODE(&acpi_tz_sysctl_ctx, | 165} 166 167/* 168 * Attach to an ACPI thermal zone. 169 */ 170static int 171acpi_tz_attach(device_t dev) 172{ --- 30 unchanged lines hidden (view full) --- 203 * Create our sysctl nodes. 204 * 205 * XXX we need a mechanism for adding nodes under ACPI. 206 */ 207 if (device_get_unit(dev) == 0) { 208 acpi_sc = acpi_device_get_parent_softc(dev); 209 sysctl_ctx_init(&acpi_tz_sysctl_ctx); 210 acpi_tz_sysctl_tree = SYSCTL_ADD_NODE(&acpi_tz_sysctl_ctx, |
208 SYSCTL_CHILDREN(acpi_sc->acpi_sysctl_tree), 209 OID_AUTO, "thermal", CTLFLAG_RD, 0, ""); | 211 SYSCTL_CHILDREN(acpi_sc->acpi_sysctl_tree), 212 OID_AUTO, "thermal", CTLFLAG_RD, 0, ""); |
210 SYSCTL_ADD_INT(&acpi_tz_sysctl_ctx, 211 SYSCTL_CHILDREN(acpi_tz_sysctl_tree), 212 OID_AUTO, "min_runtime", CTLFLAG_RD | CTLFLAG_RW, | 213 SYSCTL_ADD_INT(&acpi_tz_sysctl_ctx, 214 SYSCTL_CHILDREN(acpi_tz_sysctl_tree), 215 OID_AUTO, "min_runtime", CTLFLAG_RD | CTLFLAG_RW, |
213 &acpi_tz_min_runtime, 0, "minimum cooling run time in sec"); | 216 &acpi_tz_min_runtime, 0, 217 "minimum cooling run time in sec"); |
214 SYSCTL_ADD_INT(&acpi_tz_sysctl_ctx, 215 SYSCTL_CHILDREN(acpi_tz_sysctl_tree), 216 OID_AUTO, "polling_rate", CTLFLAG_RD | CTLFLAG_RW, 217 &acpi_tz_polling_rate, 0, "monitor polling rate"); 218 } 219 sysctl_ctx_init(&sc->tz_sysctl_ctx); 220 sprintf(oidname, "tz%d", device_get_unit(dev)); 221 sc->tz_sysctl_tree = SYSCTL_ADD_NODE(&sc->tz_sysctl_ctx, | 218 SYSCTL_ADD_INT(&acpi_tz_sysctl_ctx, 219 SYSCTL_CHILDREN(acpi_tz_sysctl_tree), 220 OID_AUTO, "polling_rate", CTLFLAG_RD | CTLFLAG_RW, 221 &acpi_tz_polling_rate, 0, "monitor polling rate"); 222 } 223 sysctl_ctx_init(&sc->tz_sysctl_ctx); 224 sprintf(oidname, "tz%d", device_get_unit(dev)); 225 sc->tz_sysctl_tree = SYSCTL_ADD_NODE(&sc->tz_sysctl_ctx, |
222 SYSCTL_CHILDREN(acpi_tz_sysctl_tree), OID_AUTO, 223 oidname, CTLFLAG_RD, 0, ""); | 226 SYSCTL_CHILDREN(acpi_tz_sysctl_tree), 227 OID_AUTO, oidname, CTLFLAG_RD, 0, ""); |
224 SYSCTL_ADD_INT(&sc->tz_sysctl_ctx, SYSCTL_CHILDREN(sc->tz_sysctl_tree), 225 OID_AUTO, "temperature", CTLFLAG_RD, 226 &sc->tz_temperature, 0, "current thermal zone temperature"); 227 SYSCTL_ADD_PROC(&sc->tz_sysctl_ctx, SYSCTL_CHILDREN(sc->tz_sysctl_tree), 228 OID_AUTO, "active", CTLTYPE_INT | CTLFLAG_RW, 229 sc, 0, acpi_tz_active_sysctl, "I", ""); 230 231 SYSCTL_ADD_INT(&sc->tz_sysctl_ctx, SYSCTL_CHILDREN(sc->tz_sysctl_tree), --- 7 unchanged lines hidden (view full) --- 239 &sc->tz_zone.hot, 0, ""); 240 SYSCTL_ADD_INT(&sc->tz_sysctl_ctx, SYSCTL_CHILDREN(sc->tz_sysctl_tree), 241 OID_AUTO, "_CRT", CTLFLAG_RD, 242 &sc->tz_zone.crt, 0, ""); 243 SYSCTL_ADD_OPAQUE(&sc->tz_sysctl_ctx, SYSCTL_CHILDREN(sc->tz_sysctl_tree), 244 OID_AUTO, "_ACx", CTLFLAG_RD, &sc->tz_zone.ac, 245 sizeof(sc->tz_zone.ac), "I", ""); 246 | 228 SYSCTL_ADD_INT(&sc->tz_sysctl_ctx, SYSCTL_CHILDREN(sc->tz_sysctl_tree), 229 OID_AUTO, "temperature", CTLFLAG_RD, 230 &sc->tz_temperature, 0, "current thermal zone temperature"); 231 SYSCTL_ADD_PROC(&sc->tz_sysctl_ctx, SYSCTL_CHILDREN(sc->tz_sysctl_tree), 232 OID_AUTO, "active", CTLTYPE_INT | CTLFLAG_RW, 233 sc, 0, acpi_tz_active_sysctl, "I", ""); 234 235 SYSCTL_ADD_INT(&sc->tz_sysctl_ctx, SYSCTL_CHILDREN(sc->tz_sysctl_tree), --- 7 unchanged lines hidden (view full) --- 243 &sc->tz_zone.hot, 0, ""); 244 SYSCTL_ADD_INT(&sc->tz_sysctl_ctx, SYSCTL_CHILDREN(sc->tz_sysctl_tree), 245 OID_AUTO, "_CRT", CTLFLAG_RD, 246 &sc->tz_zone.crt, 0, ""); 247 SYSCTL_ADD_OPAQUE(&sc->tz_sysctl_ctx, SYSCTL_CHILDREN(sc->tz_sysctl_tree), 248 OID_AUTO, "_ACx", CTLFLAG_RD, &sc->tz_zone.ac, 249 sizeof(sc->tz_zone.ac), "I", ""); 250 |
247 | |
248 /* 249 * Register our power profile event handler, and flag it for a manual 250 * invocation by our timeout. We defer it like this so that the rest 251 * of the subsystem has time to come up. 252 */ 253 EVENTHANDLER_REGISTER(power_profile_change, acpi_tz_power_profile, sc, 0); 254 sc->tz_flags |= TZ_FLAG_GETPROFILE; 255 --- 5 unchanged lines hidden (view full) --- 261 /* 262 * Create our thread; we only need one, it will service all of the 263 * thermal zones. 264 */ 265 if (acpi_tz_proc == NULL) { 266 error = kthread_create(acpi_tz_thread, NULL, &acpi_tz_proc, 267 RFHIGHPID, 0, "acpi_thermal"); 268 if (error != 0) { | 251 /* 252 * Register our power profile event handler, and flag it for a manual 253 * invocation by our timeout. We defer it like this so that the rest 254 * of the subsystem has time to come up. 255 */ 256 EVENTHANDLER_REGISTER(power_profile_change, acpi_tz_power_profile, sc, 0); 257 sc->tz_flags |= TZ_FLAG_GETPROFILE; 258 --- 5 unchanged lines hidden (view full) --- 264 /* 265 * Create our thread; we only need one, it will service all of the 266 * thermal zones. 267 */ 268 if (acpi_tz_proc == NULL) { 269 error = kthread_create(acpi_tz_thread, NULL, &acpi_tz_proc, 270 RFHIGHPID, 0, "acpi_thermal"); 271 if (error != 0) { |
269 device_printf(sc->tz_dev, "could not create thread - %d", error); | 272 device_printf(sc->tz_dev, "could not create thread - %d", 273 error); |
270 goto out; 271 } 272 } 273 274 out: 275 ACPI_UNLOCK; 276 | 274 goto out; 275 } 276 } 277 278 out: 279 ACPI_UNLOCK; 280 |
277 return_VALUE(error); | 281 return_VALUE (error); |
278} 279 280/* 281 * Parse the current state of this thermal zone and set up to use it. 282 * 283 * Note that we may have previous state, which will have to be discarded. 284 */ 285static int 286acpi_tz_establish(struct acpi_tz_softc *sc) 287{ 288 ACPI_OBJECT *obj; 289 int i; 290 char nbuf[8]; 291 292 ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); 293 294 ACPI_ASSERTLOCK; 295 | 282} 283 284/* 285 * Parse the current state of this thermal zone and set up to use it. 286 * 287 * Note that we may have previous state, which will have to be discarded. 288 */ 289static int 290acpi_tz_establish(struct acpi_tz_softc *sc) 291{ 292 ACPI_OBJECT *obj; 293 int i; 294 char nbuf[8]; 295 296 ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); 297 298 ACPI_ASSERTLOCK; 299 |
296 /* 297 * Power everything off and erase any existing state. 298 */ | 300 /* Power everything off and erase any existing state. */ |
299 acpi_tz_all_off(sc); 300 for (i = 0; i < TZ_NUMLEVELS; i++) 301 if (sc->tz_zone.al[i].Pointer != NULL) 302 AcpiOsFree(sc->tz_zone.al[i].Pointer); 303 if (sc->tz_zone.psl.Pointer != NULL) 304 AcpiOsFree(sc->tz_zone.psl.Pointer); 305 bzero(&sc->tz_zone, sizeof(sc->tz_zone)); 306 | 301 acpi_tz_all_off(sc); 302 for (i = 0; i < TZ_NUMLEVELS; i++) 303 if (sc->tz_zone.al[i].Pointer != NULL) 304 AcpiOsFree(sc->tz_zone.al[i].Pointer); 305 if (sc->tz_zone.psl.Pointer != NULL) 306 AcpiOsFree(sc->tz_zone.psl.Pointer); 307 bzero(&sc->tz_zone, sizeof(sc->tz_zone)); 308 |
307 /* 308 * Evaluate thermal zone parameters. 309 */ | 309 /* Evaluate thermal zone parameters. */ |
310 for (i = 0; i < TZ_NUMLEVELS; i++) { 311 sprintf(nbuf, "_AC%d", i); 312 acpi_tz_getparam(sc, nbuf, &sc->tz_zone.ac[i]); 313 sprintf(nbuf, "_AL%d", i); 314 sc->tz_zone.al[i].Length = ACPI_ALLOCATE_BUFFER; 315 sc->tz_zone.al[i].Pointer = NULL; 316 AcpiEvaluateObject(sc->tz_handle, nbuf, NULL, &sc->tz_zone.al[i]); 317 obj = (ACPI_OBJECT *)sc->tz_zone.al[i].Pointer; 318 if (obj != NULL) { | 310 for (i = 0; i < TZ_NUMLEVELS; i++) { 311 sprintf(nbuf, "_AC%d", i); 312 acpi_tz_getparam(sc, nbuf, &sc->tz_zone.ac[i]); 313 sprintf(nbuf, "_AL%d", i); 314 sc->tz_zone.al[i].Length = ACPI_ALLOCATE_BUFFER; 315 sc->tz_zone.al[i].Pointer = NULL; 316 AcpiEvaluateObject(sc->tz_handle, nbuf, NULL, &sc->tz_zone.al[i]); 317 obj = (ACPI_OBJECT *)sc->tz_zone.al[i].Pointer; 318 if (obj != NULL) { |
319 /* should be a package containing a list of power objects */ | 319 /* Should be a package containing a list of power objects */ |
320 if (obj->Type != ACPI_TYPE_PACKAGE) { | 320 if (obj->Type != ACPI_TYPE_PACKAGE) { |
321 device_printf(sc->tz_dev, "%s has unknown object type %d, rejecting\n", | 321 device_printf(sc->tz_dev, "%s has unknown type %d, rejecting\n", |
322 nbuf, obj->Type); | 322 nbuf, obj->Type); |
323 return_VALUE(ENXIO); | 323 return_VALUE (ENXIO); |
324 } 325 } 326 } 327 acpi_tz_getparam(sc, "_CRT", &sc->tz_zone.crt); 328 acpi_tz_getparam(sc, "_HOT", &sc->tz_zone.hot); 329 sc->tz_zone.psl.Length = ACPI_ALLOCATE_BUFFER; 330 sc->tz_zone.psl.Pointer = NULL; 331 AcpiEvaluateObject(sc->tz_handle, "_PSL", NULL, &sc->tz_zone.psl); --- 15 unchanged lines hidden (view full) --- 347 for (i = 0; i < TZ_NUMLEVELS; i++) 348 acpi_tz_sanity(sc, &sc->tz_zone.ac[i], "_ACx"); 349 350 /* 351 * Power off everything that we've just been given. 352 */ 353 acpi_tz_all_off(sc); 354 | 324 } 325 } 326 } 327 acpi_tz_getparam(sc, "_CRT", &sc->tz_zone.crt); 328 acpi_tz_getparam(sc, "_HOT", &sc->tz_zone.hot); 329 sc->tz_zone.psl.Length = ACPI_ALLOCATE_BUFFER; 330 sc->tz_zone.psl.Pointer = NULL; 331 AcpiEvaluateObject(sc->tz_handle, "_PSL", NULL, &sc->tz_zone.psl); --- 15 unchanged lines hidden (view full) --- 347 for (i = 0; i < TZ_NUMLEVELS; i++) 348 acpi_tz_sanity(sc, &sc->tz_zone.ac[i], "_ACx"); 349 350 /* 351 * Power off everything that we've just been given. 352 */ 353 acpi_tz_all_off(sc); 354 |
355 return_VALUE(0); | 355 return_VALUE (0); |
356} 357 358static char *aclevel_string[] = { 359 "NONE", "_AC0", "_AC1", "_AC2", "_AC3", "_AC4", 360 "_AC5", "_AC6", "_AC7", "_AC8", "_AC9" }; 361 362static __inline const char * 363acpi_tz_aclevel_string(int active) 364{ | 356} 357 358static char *aclevel_string[] = { 359 "NONE", "_AC0", "_AC1", "_AC2", "_AC3", "_AC4", 360 "_AC5", "_AC6", "_AC7", "_AC8", "_AC9" }; 361 362static __inline const char * 363acpi_tz_aclevel_string(int active) 364{ |
365 if (active < -1 || active >= TZ_NUMLEVELS) { | 365 if (active < -1 || active >= TZ_NUMLEVELS) |
366 return (aclevel_string[0]); | 366 return (aclevel_string[0]); |
367 } | |
368 369 return (aclevel_string[active+1]); 370} 371 372/* 373 * Evaluate the condition of a thermal zone, take appropriate actions. 374 */ 375static void | 367 368 return (aclevel_string[active+1]); 369} 370 371/* 372 * Evaluate the condition of a thermal zone, take appropriate actions. 373 */ 374static void |
376acpi_tz_monitor(struct acpi_tz_softc *sc) | 375acpi_tz_monitor(void *Context) |
377{ | 376{ |
377 struct acpi_tz_softc *sc; 378 struct timespec curtime; |
|
378 int temp; 379 int i; 380 int newactive, newflags; | 379 int temp; 380 int i; 381 int newactive, newflags; |
381 struct timespec curtime; | |
382 ACPI_STATUS status; 383 384 ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); 385 386 ACPI_ASSERTLOCK; 387 | 382 ACPI_STATUS status; 383 384 ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); 385 386 ACPI_ASSERTLOCK; 387 |
388 if (sc->tz_tmp_updating) { | 388 sc = (struct acpi_tz_softc *)Context; 389 if (sc->tz_tmp_updating) |
389 goto out; | 390 goto out; |
390 } | |
391 sc->tz_tmp_updating = 1; 392 | 391 sc->tz_tmp_updating = 1; 392 |
393 /* 394 * Get the current temperature. 395 */ 396 if (ACPI_FAILURE(status = acpi_EvaluateInteger(sc->tz_handle, "_TMP", &temp))) { | 393 /* Get the current temperature. */ 394 status = acpi_EvaluateInteger(sc->tz_handle, "_TMP", &temp); 395 if (ACPI_FAILURE(status)) { |
397 ACPI_VPRINT(sc->tz_dev, acpi_device_get_parent_softc(sc->tz_dev), 398 "error fetching current temperature -- %s\n", 399 AcpiFormatException(status)); 400 /* XXX disable zone? go to max cooling? */ 401 goto out; 402 } 403 404 ACPI_DEBUG_PRINT((ACPI_DB_VALUES, "got %d.%dC\n", TZ_KELVTOC(temp))); --- 4 unchanged lines hidden (view full) --- 409 * 410 * Note that the _ACx levels sort from hot to cold. 411 */ 412 newactive = TZ_ACTIVE_NONE; 413 for (i = TZ_NUMLEVELS - 1; i >= 0; i--) { 414 if ((sc->tz_zone.ac[i] != -1) && (temp >= sc->tz_zone.ac[i])) { 415 newactive = i; 416 if (sc->tz_active != newactive) { | 396 ACPI_VPRINT(sc->tz_dev, acpi_device_get_parent_softc(sc->tz_dev), 397 "error fetching current temperature -- %s\n", 398 AcpiFormatException(status)); 399 /* XXX disable zone? go to max cooling? */ 400 goto out; 401 } 402 403 ACPI_DEBUG_PRINT((ACPI_DB_VALUES, "got %d.%dC\n", TZ_KELVTOC(temp))); --- 4 unchanged lines hidden (view full) --- 408 * 409 * Note that the _ACx levels sort from hot to cold. 410 */ 411 newactive = TZ_ACTIVE_NONE; 412 for (i = TZ_NUMLEVELS - 1; i >= 0; i--) { 413 if ((sc->tz_zone.ac[i] != -1) && (temp >= sc->tz_zone.ac[i])) { 414 newactive = i; 415 if (sc->tz_active != newactive) { |
417 ACPI_VPRINT(sc->tz_dev, acpi_device_get_parent_softc(sc->tz_dev), 418 "_AC%d: temperature %d.%d >= setpoint %d.%d\n", i, 419 TZ_KELVTOC(temp), TZ_KELVTOC(sc->tz_zone.ac[i])); | 416 ACPI_VPRINT(sc->tz_dev, 417 acpi_device_get_parent_softc(sc->tz_dev), 418 "_AC%d: temperature %d.%d >= setpoint %d.%d\n", i, 419 TZ_KELVTOC(temp), TZ_KELVTOC(sc->tz_zone.ac[i])); |
420 getnanotime(&sc->tz_cooling_started); 421 } 422 } 423 } 424 425 /* 426 * We are going to get _ACx level down (colder side), but give a guaranteed 427 * minimum cooling run time if requested. 428 */ 429 if (acpi_tz_min_runtime > 0 && sc->tz_active != TZ_ACTIVE_NONE && 430 (newactive == TZ_ACTIVE_NONE || newactive > sc->tz_active)) { | 420 getnanotime(&sc->tz_cooling_started); 421 } 422 } 423 } 424 425 /* 426 * We are going to get _ACx level down (colder side), but give a guaranteed 427 * minimum cooling run time if requested. 428 */ 429 if (acpi_tz_min_runtime > 0 && sc->tz_active != TZ_ACTIVE_NONE && 430 (newactive == TZ_ACTIVE_NONE || newactive > sc->tz_active)) { |
431 |
|
431 getnanotime(&curtime); 432 timespecsub(&curtime, &sc->tz_cooling_started); | 432 getnanotime(&curtime); 433 timespecsub(&curtime, &sc->tz_cooling_started); |
433 if (curtime.tv_sec < acpi_tz_min_runtime) { | 434 if (curtime.tv_sec < acpi_tz_min_runtime) |
434 newactive = sc->tz_active; | 435 newactive = sc->tz_active; |
435 } | |
436 } 437 | 436 } 437 |
438 /* handle user override of active mode */ | 438 /* Handle user override of active mode */ |
439 if (sc->tz_requested > newactive) 440 newactive = sc->tz_requested; 441 442 /* update temperature-related flags */ 443 newflags = TZ_THFLAG_NONE; 444 if ((sc->tz_zone.psv != -1) && (temp >= sc->tz_zone.psv)) 445 newflags |= TZ_THFLAG_PSV; 446 if ((sc->tz_zone.hot != -1) && (temp >= sc->tz_zone.hot)) 447 newflags |= TZ_THFLAG_HOT; 448 if ((sc->tz_zone.crt != -1) && (temp >= sc->tz_zone.crt)) 449 newflags |= TZ_THFLAG_CRT; 450 | 439 if (sc->tz_requested > newactive) 440 newactive = sc->tz_requested; 441 442 /* update temperature-related flags */ 443 newflags = TZ_THFLAG_NONE; 444 if ((sc->tz_zone.psv != -1) && (temp >= sc->tz_zone.psv)) 445 newflags |= TZ_THFLAG_PSV; 446 if ((sc->tz_zone.hot != -1) && (temp >= sc->tz_zone.hot)) 447 newflags |= TZ_THFLAG_HOT; 448 if ((sc->tz_zone.crt != -1) && (temp >= sc->tz_zone.crt)) 449 newflags |= TZ_THFLAG_CRT; 450 |
451 /* 452 * If the active cooling state has changed, we have to switch things. 453 */ | 451 /* If the active cooling state has changed, we have to switch things. */ |
454 if (newactive != sc->tz_active) { | 452 if (newactive != sc->tz_active) { |
455 456 /* turn off the cooling devices that are on, if any are */ | 453 /* Turn off the cooling devices that are on, if any are */ |
457 if (sc->tz_active != TZ_ACTIVE_NONE) | 454 if (sc->tz_active != TZ_ACTIVE_NONE) |
458 acpi_ForeachPackageObject((ACPI_OBJECT *)sc->tz_zone.al[sc->tz_active].Pointer, 459 acpi_tz_switch_cooler_off, sc); | 455 acpi_ForeachPackageObject( 456 (ACPI_OBJECT *)sc->tz_zone.al[sc->tz_active].Pointer, 457 acpi_tz_switch_cooler_off, sc); |
460 | 458 |
461 /* turn on cooling devices that are required, if any are */ 462 if (newactive != TZ_ACTIVE_NONE) 463 acpi_ForeachPackageObject((ACPI_OBJECT *)sc->tz_zone.al[newactive].Pointer, 464 acpi_tz_switch_cooler_on, sc); | 459 /* Turn on cooling devices that are required, if any are */ 460 if (newactive != TZ_ACTIVE_NONE) { 461 acpi_ForeachPackageObject( 462 (ACPI_OBJECT *)sc->tz_zone.al[newactive].Pointer, 463 acpi_tz_switch_cooler_on, sc); 464 } |
465 ACPI_VPRINT(sc->tz_dev, acpi_device_get_parent_softc(sc->tz_dev), | 465 ACPI_VPRINT(sc->tz_dev, acpi_device_get_parent_softc(sc->tz_dev), |
466 "switched from %s to %s: %d.%dC\n", 467 acpi_tz_aclevel_string(sc->tz_active), 468 acpi_tz_aclevel_string(newactive), TZ_KELVTOC(temp)); | 466 "switched from %s to %s: %d.%dC\n", 467 acpi_tz_aclevel_string(sc->tz_active), 468 acpi_tz_aclevel_string(newactive), TZ_KELVTOC(temp)); |
469 sc->tz_active = newactive; 470 } 471 | 469 sc->tz_active = newactive; 470 } 471 |
472 /* 473 * XXX (de)activate any passive cooling that may be required. 474 */ | 472 /* XXX (de)activate any passive cooling that may be required. */ |
475 476 /* 477 * If we have just become _HOT or _CRT, warn the user. 478 * 479 * We should actually shut down at this point, but it's not clear 480 * that some systems don't actually map _CRT to the same value as _AC0. 481 */ | 473 474 /* 475 * If we have just become _HOT or _CRT, warn the user. 476 * 477 * We should actually shut down at this point, but it's not clear 478 * that some systems don't actually map _CRT to the same value as _AC0. 479 */ |
482 if ((newflags & (TZ_THFLAG_HOT | TZ_THFLAG_CRT)) && 483 !(sc->tz_thflags & (TZ_THFLAG_HOT | TZ_THFLAG_CRT))) { 484 device_printf(sc->tz_dev, "WARNING - current temperature (%d.%dC) exceeds system limits\n", | 480 if ((newflags & (TZ_THFLAG_HOT | TZ_THFLAG_CRT)) != 0 && 481 (sc->tz_thflags & (TZ_THFLAG_HOT | TZ_THFLAG_CRT)) == 0) { 482 483 device_printf(sc->tz_dev, 484 "WARNING - current temperature (%d.%dC) exceeds system limits\n", |
485 TZ_KELVTOC(sc->tz_temperature)); 486 /* shutdown_nice(RB_POWEROFF);*/ 487 } 488 sc->tz_thflags = newflags; 489 490out: 491 sc->tz_tmp_updating = 0; 492 return_VOID; --- 6 unchanged lines hidden (view full) --- 499acpi_tz_all_off(struct acpi_tz_softc *sc) 500{ 501 int i; 502 503 ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); 504 505 ACPI_ASSERTLOCK; 506 | 485 TZ_KELVTOC(sc->tz_temperature)); 486 /* shutdown_nice(RB_POWEROFF);*/ 487 } 488 sc->tz_thflags = newflags; 489 490out: 491 sc->tz_tmp_updating = 0; 492 return_VOID; --- 6 unchanged lines hidden (view full) --- 499acpi_tz_all_off(struct acpi_tz_softc *sc) 500{ 501 int i; 502 503 ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); 504 505 ACPI_ASSERTLOCK; 506 |
507 /* 508 * Scan all the _ALx objects, and turn them all off. 509 */ | 507 /* Scan all the _ALx objects and turn them all off. */ |
510 for (i = 0; i < TZ_NUMLEVELS; i++) { 511 if (sc->tz_zone.al[i].Pointer == NULL) 512 continue; 513 acpi_ForeachPackageObject((ACPI_OBJECT *)sc->tz_zone.al[i].Pointer, 514 acpi_tz_switch_cooler_off, sc); 515 } 516 517 /* 518 * XXX revert any passive-cooling options. 519 */ 520 521 sc->tz_active = TZ_ACTIVE_NONE; 522 sc->tz_thflags = TZ_THFLAG_NONE; | 508 for (i = 0; i < TZ_NUMLEVELS; i++) { 509 if (sc->tz_zone.al[i].Pointer == NULL) 510 continue; 511 acpi_ForeachPackageObject((ACPI_OBJECT *)sc->tz_zone.al[i].Pointer, 512 acpi_tz_switch_cooler_off, sc); 513 } 514 515 /* 516 * XXX revert any passive-cooling options. 517 */ 518 519 sc->tz_active = TZ_ACTIVE_NONE; 520 sc->tz_thflags = TZ_THFLAG_NONE; |
521 |
|
523 return_VOID; 524} 525 526/* 527 * Given an object, verify that it's a reference to a device of some sort, 528 * and try to switch it off. 529 */ 530static void 531acpi_tz_switch_cooler_off(ACPI_OBJECT *obj, void *arg) 532{ 533 ACPI_HANDLE cooler; 534 535 ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); 536 537 ACPI_ASSERTLOCK; 538 539 switch(obj->Type) { 540 case ACPI_TYPE_ANY: | 522 return_VOID; 523} 524 525/* 526 * Given an object, verify that it's a reference to a device of some sort, 527 * and try to switch it off. 528 */ 529static void 530acpi_tz_switch_cooler_off(ACPI_OBJECT *obj, void *arg) 531{ 532 ACPI_HANDLE cooler; 533 534 ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); 535 536 ACPI_ASSERTLOCK; 537 538 switch(obj->Type) { 539 case ACPI_TYPE_ANY: |
541 ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "called to turn %s off\n", acpi_name(obj->Reference.Handle))); | 540 ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "called to turn %s off\n", 541 acpi_name(obj->Reference.Handle))); |
542 543 acpi_pwr_switch_consumer(obj->Reference.Handle, ACPI_STATE_D3); 544 break; | 542 543 acpi_pwr_switch_consumer(obj->Reference.Handle, ACPI_STATE_D3); 544 break; |
545 | |
546 case ACPI_TYPE_STRING: | 545 case ACPI_TYPE_STRING: |
547 ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "called to turn %s off\n", obj->String.Pointer)); | 546 ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "called to turn %s off\n", 547 obj->String.Pointer)); |
548 549 /* 550 * Find the handle for the device and turn it off. 551 * The String object here seems to contain a fully-qualified path, so we 552 * don't have to search for it in our parents. 553 * 554 * XXX This may not always be the case. 555 */ 556 if (ACPI_SUCCESS(AcpiGetHandle(NULL, obj->String.Pointer, &cooler))) 557 acpi_pwr_switch_consumer(cooler, ACPI_STATE_D3); 558 break; | 548 549 /* 550 * Find the handle for the device and turn it off. 551 * The String object here seems to contain a fully-qualified path, so we 552 * don't have to search for it in our parents. 553 * 554 * XXX This may not always be the case. 555 */ 556 if (ACPI_SUCCESS(AcpiGetHandle(NULL, obj->String.Pointer, &cooler))) 557 acpi_pwr_switch_consumer(cooler, ACPI_STATE_D3); 558 break; |
559 | |
560 default: | 559 default: |
561 ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "called to handle unsupported object type %d\n", 562 obj->Type)); | 560 ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, 561 "called to handle unsupported object type %d\n", 562 obj->Type)); |
563 break; 564 } | 563 break; 564 } |
565 |
|
565 return_VOID; 566} 567 568/* 569 * Given an object, verify that it's a reference to a device of some sort, 570 * and try to switch it on. 571 * 572 * XXX replication of off/on function code is bad, mmmkay? --- 6 unchanged lines hidden (view full) --- 579 ACPI_STATUS status; 580 581 ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); 582 583 ACPI_ASSERTLOCK; 584 585 switch(obj->Type) { 586 case ACPI_TYPE_ANY: | 566 return_VOID; 567} 568 569/* 570 * Given an object, verify that it's a reference to a device of some sort, 571 * and try to switch it on. 572 * 573 * XXX replication of off/on function code is bad, mmmkay? --- 6 unchanged lines hidden (view full) --- 580 ACPI_STATUS status; 581 582 ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); 583 584 ACPI_ASSERTLOCK; 585 586 switch(obj->Type) { 587 case ACPI_TYPE_ANY: |
587 ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "called to turn %s on\n", acpi_name(obj->Reference.Handle))); | 588 ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "called to turn %s on\n", 589 acpi_name(obj->Reference.Handle))); |
588 | 590 |
589 if (ACPI_FAILURE(status = acpi_pwr_switch_consumer(obj->Reference.Handle, ACPI_STATE_D0))) { | 591 status = acpi_pwr_switch_consumer(obj->Reference.Handle, ACPI_STATE_D0); 592 if (ACPI_FAILURE(status)) { |
590 ACPI_VPRINT(sc->tz_dev, acpi_device_get_parent_softc(sc->tz_dev), | 593 ACPI_VPRINT(sc->tz_dev, acpi_device_get_parent_softc(sc->tz_dev), |
591 "failed to activate %s - %s\n", acpi_name(obj->Reference.Handle), 592 AcpiFormatException(status)); | 594 "failed to activate %s - %s\n", 595 acpi_name(obj->Reference.Handle), 596 AcpiFormatException(status)); |
593 } 594 break; | 597 } 598 break; |
595 | |
596 case ACPI_TYPE_STRING: | 599 case ACPI_TYPE_STRING: |
597 ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "called to turn %s on\n", obj->String.Pointer)); | 600 ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "called to turn %s on\n", 601 obj->String.Pointer)); |
598 599 /* 600 * Find the handle for the device and turn it off. 601 * The String object here seems to contain a fully-qualified path, so we 602 * don't have to search for it in our parents. 603 * 604 * XXX This may not always be the case. 605 */ 606 if (ACPI_SUCCESS(AcpiGetHandle(NULL, obj->String.Pointer, &cooler))) { | 602 603 /* 604 * Find the handle for the device and turn it off. 605 * The String object here seems to contain a fully-qualified path, so we 606 * don't have to search for it in our parents. 607 * 608 * XXX This may not always be the case. 609 */ 610 if (ACPI_SUCCESS(AcpiGetHandle(NULL, obj->String.Pointer, &cooler))) { |
607 if (ACPI_FAILURE(status = acpi_pwr_switch_consumer(cooler, ACPI_STATE_D0))) { 608 ACPI_VPRINT(sc->tz_dev, acpi_device_get_parent_softc(sc->tz_dev), 609 "failed to activate %s - %s\n", 610 obj->String.Pointer, AcpiFormatException(status)); | 611 status = acpi_pwr_switch_consumer(cooler, ACPI_STATE_D0); 612 if (ACPI_FAILURE(status)) { 613 ACPI_VPRINT(sc->tz_dev, 614 acpi_device_get_parent_softc(sc->tz_dev), 615 "failed to activate %s - %s\n", 616 obj->String.Pointer, AcpiFormatException(status)); |
611 } 612 } else { 613 ACPI_VPRINT(sc->tz_dev, acpi_device_get_parent_softc(sc->tz_dev), | 617 } 618 } else { 619 ACPI_VPRINT(sc->tz_dev, acpi_device_get_parent_softc(sc->tz_dev), |
614 "couldn't find %s\n", obj->String.Pointer); | 620 "couldn't find %s\n", obj->String.Pointer); |
615 } 616 break; | 621 } 622 break; |
617 | |
618 default: | 623 default: |
619 ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "called to handle unsupported object type %d\n", | 624 ACPI_DEBUG_PRINT((ACPI_DB_OBJECTS, "unsupported object type %d\n", |
620 obj->Type)); 621 break; 622 } | 625 obj->Type)); 626 break; 627 } |
623 return_VOID; | 628 629 return_VOID; |
624} 625 626/* 627 * Read/debug-print a parameter, default it to -1. 628 */ 629static void 630acpi_tz_getparam(struct acpi_tz_softc *sc, char *node, int *data) 631{ 632 633 ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); 634 635 ACPI_ASSERTLOCK; 636 637 if (ACPI_FAILURE(acpi_EvaluateInteger(sc->tz_handle, node, data))) { 638 *data = -1; 639 } else { | 630} 631 632/* 633 * Read/debug-print a parameter, default it to -1. 634 */ 635static void 636acpi_tz_getparam(struct acpi_tz_softc *sc, char *node, int *data) 637{ 638 639 ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); 640 641 ACPI_ASSERTLOCK; 642 643 if (ACPI_FAILURE(acpi_EvaluateInteger(sc->tz_handle, node, data))) { 644 *data = -1; 645 } else { |
640 ACPI_DEBUG_PRINT((ACPI_DB_VALUES, "%s.%s = %d\n", acpi_name(sc->tz_handle), 641 node, *data)); | 646 ACPI_DEBUG_PRINT((ACPI_DB_VALUES, "%s.%s = %d\n", 647 acpi_name(sc->tz_handle), node, *data)); |
642 } | 648 } |
649 |
|
643 return_VOID; 644} 645 646/* 647 * Sanity-check a temperature value. Assume that setpoints 648 * should be between 0C and 150C. 649 */ 650static void 651acpi_tz_sanity(struct acpi_tz_softc *sc, int *val, char *what) 652{ | 650 return_VOID; 651} 652 653/* 654 * Sanity-check a temperature value. Assume that setpoints 655 * should be between 0C and 150C. 656 */ 657static void 658acpi_tz_sanity(struct acpi_tz_softc *sc, int *val, char *what) 659{ |
653 if ((*val != -1) && ((*val < TZ_ZEROC) || (*val > (TZ_ZEROC + 1500)))) { | 660 if (*val != -1 && (*val < TZ_ZEROC || *val > TZ_ZEROC + 1500)) { |
654 device_printf(sc->tz_dev, "%s value is absurd, ignored (%d.%dC)\n", 655 what, TZ_KELVTOC(*val)); 656 *val = -1; 657 } 658} 659 660/* 661 * Respond to a sysctl on the active state node. --- 7 unchanged lines hidden (view full) --- 669 ACPI_LOCK_DECL; 670 671 ACPI_LOCK; 672 673 sc = (struct acpi_tz_softc *)oidp->oid_arg1; 674 active = sc->tz_active; 675 error = sysctl_handle_int(oidp, &active, 0, req); 676 | 661 device_printf(sc->tz_dev, "%s value is absurd, ignored (%d.%dC)\n", 662 what, TZ_KELVTOC(*val)); 663 *val = -1; 664 } 665} 666 667/* 668 * Respond to a sysctl on the active state node. --- 7 unchanged lines hidden (view full) --- 676 ACPI_LOCK_DECL; 677 678 ACPI_LOCK; 679 680 sc = (struct acpi_tz_softc *)oidp->oid_arg1; 681 active = sc->tz_active; 682 error = sysctl_handle_int(oidp, &active, 0, req); 683 |
677 /* error or no new value */ 678 if ((error != 0) || (req->newptr == NULL)) | 684 /* Error or no new value */ 685 if (error != 0 || req->newptr == NULL) |
679 goto out; | 686 goto out; |
680 681 /* range check */ 682 if ((active < -1) || (active >= TZ_NUMLEVELS)) { | 687 if (active < -1 || active >= TZ_NUMLEVELS) { |
683 error = EINVAL; 684 goto out; 685 } 686 | 688 error = EINVAL; 689 goto out; 690 } 691 |
687 /* set new preferred level and re-switch */ | 692 /* Set new preferred level and re-switch */ |
688 sc->tz_requested = active; 689 acpi_tz_monitor(sc); 690 691 out: 692 ACPI_UNLOCK; | 693 sc->tz_requested = active; 694 acpi_tz_monitor(sc); 695 696 out: 697 ACPI_UNLOCK; |
693 return(error); | 698 return (error); |
694} 695 696/* 697 * Respond to a Notify event sent to the zone. 698 */ 699static void 700acpi_tz_notify_handler(ACPI_HANDLE h, UINT32 notify, void *context) 701{ 702 struct acpi_tz_softc *sc = (struct acpi_tz_softc *)context; 703 704 ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); 705 706 ACPI_ASSERTLOCK; 707 708 switch(notify) { 709 case TZ_NOTIFY_TEMPERATURE: | 699} 700 701/* 702 * Respond to a Notify event sent to the zone. 703 */ 704static void 705acpi_tz_notify_handler(ACPI_HANDLE h, UINT32 notify, void *context) 706{ 707 struct acpi_tz_softc *sc = (struct acpi_tz_softc *)context; 708 709 ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); 710 711 ACPI_ASSERTLOCK; 712 713 switch(notify) { 714 case TZ_NOTIFY_TEMPERATURE: |
710 /* temperature change occurred */ 711 AcpiOsQueueForExecution(OSD_PRIORITY_HIGH, (OSD_EXECUTION_CALLBACK)acpi_tz_monitor, sc); | 715 /* Temperature change occurred */ 716 AcpiOsQueueForExecution(OSD_PRIORITY_HIGH, acpi_tz_monitor, sc); |
712 break; 713 case TZ_NOTIFY_DEVICES: 714 case TZ_NOTIFY_LEVELS: | 717 break; 718 case TZ_NOTIFY_DEVICES: 719 case TZ_NOTIFY_LEVELS: |
715 /* zone devices/setpoints changed */ 716 AcpiOsQueueForExecution(OSD_PRIORITY_HIGH, (OSD_EXECUTION_CALLBACK)acpi_tz_establish, sc); | 720 /* Zone devices/setpoints changed */ 721 AcpiOsQueueForExecution(OSD_PRIORITY_HIGH, 722 (OSD_EXECUTION_CALLBACK)acpi_tz_establish, sc); |
717 break; 718 default: 719 ACPI_VPRINT(sc->tz_dev, acpi_device_get_parent_softc(sc->tz_dev), | 723 break; 724 default: 725 ACPI_VPRINT(sc->tz_dev, acpi_device_get_parent_softc(sc->tz_dev), |
720 "unknown Notify event 0x%x\n", notify); | 726 "unknown Notify event 0x%x\n", notify); |
721 break; 722 } | 727 break; 728 } |
729 |
|
723 return_VOID; 724} 725 726/* 727 * Poll the thermal zone. 728 */ 729static void 730acpi_tz_timeout(struct acpi_tz_softc *sc) 731{ | 730 return_VOID; 731} 732 733/* 734 * Poll the thermal zone. 735 */ 736static void 737acpi_tz_timeout(struct acpi_tz_softc *sc) 738{ |
732 733 /* do we need to get the power profile settings? */ | 739 /* Do we need to get the power profile settings? */ |
734 if (sc->tz_flags & TZ_FLAG_GETPROFILE) { 735 acpi_tz_power_profile((void *)sc); 736 sc->tz_flags &= ~TZ_FLAG_GETPROFILE; 737 } 738 739 ACPI_ASSERTLOCK; 740 | 740 if (sc->tz_flags & TZ_FLAG_GETPROFILE) { 741 acpi_tz_power_profile((void *)sc); 742 sc->tz_flags &= ~TZ_FLAG_GETPROFILE; 743 } 744 745 ACPI_ASSERTLOCK; 746 |
741 /* check the current temperature and take action based on it */ | 747 /* Check the current temperature and take action based on it */ |
742 acpi_tz_monitor(sc); 743 744 /* XXX passive cooling actions? */ 745} 746 747/* 748 * System power profile may have changed; fetch and notify the 749 * thermal zone accordingly. --- 7 unchanged lines hidden (view full) --- 757 ACPI_OBJECT_LIST args; 758 ACPI_OBJECT obj; 759 ACPI_STATUS status; 760 struct acpi_tz_softc *sc = (struct acpi_tz_softc *)arg; 761 int state; 762 ACPI_LOCK_DECL; 763 764 state = power_profile_get_state(); | 748 acpi_tz_monitor(sc); 749 750 /* XXX passive cooling actions? */ 751} 752 753/* 754 * System power profile may have changed; fetch and notify the 755 * thermal zone accordingly. --- 7 unchanged lines hidden (view full) --- 763 ACPI_OBJECT_LIST args; 764 ACPI_OBJECT obj; 765 ACPI_STATUS status; 766 struct acpi_tz_softc *sc = (struct acpi_tz_softc *)arg; 767 int state; 768 ACPI_LOCK_DECL; 769 770 state = power_profile_get_state(); |
765 if (state != POWER_PROFILE_PERFORMANCE && 766 state != POWER_PROFILE_ECONOMY) { 767 return; 768 } | 771 if (state != POWER_PROFILE_PERFORMANCE && state != POWER_PROFILE_ECONOMY) 772 return; |
769 770 ACPI_LOCK; 771 772 /* check that we haven't decided there's no _SCP method */ | 773 774 ACPI_LOCK; 775 776 /* check that we haven't decided there's no _SCP method */ |
773 if (!(sc->tz_flags & TZ_FLAG_NO_SCP)) { | 777 if ((sc->tz_flags & TZ_FLAG_NO_SCP) == 0) { |
774 | 778 |
775 /* call _SCP to set the new profile */ | 779 /* Call _SCP to set the new profile */ |
776 obj.Type = ACPI_TYPE_INTEGER; 777 obj.Integer.Value = (state == POWER_PROFILE_PERFORMANCE) ? 0 : 1; 778 args.Count = 1; 779 args.Pointer = &obj; | 780 obj.Type = ACPI_TYPE_INTEGER; 781 obj.Integer.Value = (state == POWER_PROFILE_PERFORMANCE) ? 0 : 1; 782 args.Count = 1; 783 args.Pointer = &obj; |
780 if (ACPI_FAILURE(status = AcpiEvaluateObject(sc->tz_handle, "_SCP", &args, NULL))) { | 784 status = AcpiEvaluateObject(sc->tz_handle, "_SCP", &args, NULL); 785 if (ACPI_FAILURE(status)) { |
781 if (status != AE_NOT_FOUND) | 786 if (status != AE_NOT_FOUND) |
782 ACPI_VPRINT(sc->tz_dev, acpi_device_get_parent_softc(sc->tz_dev), 783 "can't evaluate %s._SCP - %s\n", acpi_name(sc->tz_handle), 784 AcpiFormatException(status)); | 787 ACPI_VPRINT(sc->tz_dev, 788 acpi_device_get_parent_softc(sc->tz_dev), 789 "can't evaluate %s._SCP - %s\n", 790 acpi_name(sc->tz_handle), 791 AcpiFormatException(status)); |
785 sc->tz_flags |= TZ_FLAG_NO_SCP; 786 } else { | 792 sc->tz_flags |= TZ_FLAG_NO_SCP; 793 } else { |
787 /* we have to re-evaluate the entire zone now */ 788 AcpiOsQueueForExecution(OSD_PRIORITY_HIGH, (OSD_EXECUTION_CALLBACK)acpi_tz_establish, sc); | 794 /* We have to re-evaluate the entire zone now */ 795 AcpiOsQueueForExecution(OSD_PRIORITY_HIGH, 796 (OSD_EXECUTION_CALLBACK)acpi_tz_establish, 797 sc); |
789 } 790 } | 798 } 799 } |
800 |
|
791 ACPI_UNLOCK; 792} 793 794/* 795 * Thermal zone monitor thread. 796 */ 797static void 798acpi_tz_thread(void *arg) 799{ 800 device_t *devs; 801 int devcount, i; 802 ACPI_LOCK_DECL; 803 804 ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); 805 | 801 ACPI_UNLOCK; 802} 803 804/* 805 * Thermal zone monitor thread. 806 */ 807static void 808acpi_tz_thread(void *arg) 809{ 810 device_t *devs; 811 int devcount, i; 812 ACPI_LOCK_DECL; 813 814 ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); 815 |
806 | |
807 devs = NULL; 808 devcount = 0; 809 810 for (;;) { | 816 devs = NULL; 817 devcount = 0; 818 819 for (;;) { |
811 tsleep(&acpi_tz_proc, PZERO, "nothing", hz * acpi_tz_polling_rate); | 820 tsleep(&acpi_tz_proc, PZERO, "tzpoll", hz * acpi_tz_polling_rate); |
812 813#if __FreeBSD_version >= 500000 814 mtx_lock(&Giant); 815#endif 816 817 if (devcount == 0) 818 devclass_get_devices(acpi_tz_devclass, &devs, &devcount); 819 820 ACPI_LOCK; 821 for (i = 0; i < devcount; i++) 822 acpi_tz_timeout(device_get_softc(devs[i])); 823 ACPI_UNLOCK; 824 825#if __FreeBSD_version >= 500000 826 mtx_unlock(&Giant); 827#endif 828 } 829} | 821 822#if __FreeBSD_version >= 500000 823 mtx_lock(&Giant); 824#endif 825 826 if (devcount == 0) 827 devclass_get_devices(acpi_tz_devclass, &devs, &devcount); 828 829 ACPI_LOCK; 830 for (i = 0; i < devcount; i++) 831 acpi_tz_timeout(device_get_softc(devs[i])); 832 ACPI_UNLOCK; 833 834#if __FreeBSD_version >= 500000 835 mtx_unlock(&Giant); 836#endif 837 } 838} |