Add support for _CR3 critical standby (S3) threshold.
Along with _PSV, _HOT, and _CRT, ACPI supports the _CR3 threshold which specifies a temperature above which a system should transition to the S3 standby state. On FreeBSD, this is more useful than _HOT, which specifies the S4 transition threshold temperature (since FreeBSD does not generally support the S4 state), or, in many cases, _CRT, since after transitioning to S3 the system can cool and then be resumed. Reviewed by: jhb, bcr (manpages) Relnotes: yes Differential Revision: https://reviews.freebsd.org/D35980
This commit is contained in:
parent
20a66ab4bf
commit
b8a0dfb17e
@ -24,7 +24,7 @@
|
|||||||
.\"
|
.\"
|
||||||
.\" $FreeBSD$
|
.\" $FreeBSD$
|
||||||
.\"
|
.\"
|
||||||
.Dd March 17, 2007
|
.Dd November 21, 2022
|
||||||
.Dt ACPI_THERMAL 4
|
.Dt ACPI_THERMAL 4
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -84,6 +84,9 @@ Current temperature for this zone.
|
|||||||
.It Va hw.acpi.thermal.tz%d._PSV
|
.It Va hw.acpi.thermal.tz%d._PSV
|
||||||
Temperature to start passive cooling by throttling down CPU, etc.
|
Temperature to start passive cooling by throttling down CPU, etc.
|
||||||
This value can be overridden by the user.
|
This value can be overridden by the user.
|
||||||
|
.It Va hw.acpi.thermal.tz%d._CR3
|
||||||
|
Temperature to start critical suspend to RAM (S3).
|
||||||
|
This value can be overridden by the user.
|
||||||
.It Va hw.acpi.thermal.tz%d._HOT
|
.It Va hw.acpi.thermal.tz%d._HOT
|
||||||
Temperature to start critical suspend to disk (S4).
|
Temperature to start critical suspend to disk (S4).
|
||||||
This value can be overridden by the user.
|
This value can be overridden by the user.
|
||||||
|
@ -60,7 +60,7 @@ ACPI_MODULE_NAME("THERMAL")
|
|||||||
#define TZ_NOTIFY_TEMPERATURE 0x80 /* Temperature changed. */
|
#define TZ_NOTIFY_TEMPERATURE 0x80 /* Temperature changed. */
|
||||||
#define TZ_NOTIFY_LEVELS 0x81 /* Cooling levels changed. */
|
#define TZ_NOTIFY_LEVELS 0x81 /* Cooling levels changed. */
|
||||||
#define TZ_NOTIFY_DEVICES 0x82 /* Device lists changed. */
|
#define TZ_NOTIFY_DEVICES 0x82 /* Device lists changed. */
|
||||||
#define TZ_NOTIFY_CRITICAL 0xcc /* Fake notify that _CRT/_HOT reached. */
|
#define TZ_NOTIFY_CRITICAL 0xcc /* Fake notify that _CRT/_HOT/_CR3 reached. */
|
||||||
|
|
||||||
/* Check for temperature changes every 10 seconds by default */
|
/* Check for temperature changes every 10 seconds by default */
|
||||||
#define TZ_POLLRATE 10
|
#define TZ_POLLRATE 10
|
||||||
@ -78,6 +78,7 @@ struct acpi_tz_zone {
|
|||||||
ACPI_BUFFER al[TZ_NUMLEVELS];
|
ACPI_BUFFER al[TZ_NUMLEVELS];
|
||||||
int crt;
|
int crt;
|
||||||
int hot;
|
int hot;
|
||||||
|
int cr3;
|
||||||
ACPI_BUFFER psl;
|
ACPI_BUFFER psl;
|
||||||
int psv;
|
int psv;
|
||||||
int tc1;
|
int tc1;
|
||||||
@ -97,8 +98,9 @@ struct acpi_tz_softc {
|
|||||||
int tz_thflags; /*Current temp-related flags*/
|
int tz_thflags; /*Current temp-related flags*/
|
||||||
#define TZ_THFLAG_NONE 0
|
#define TZ_THFLAG_NONE 0
|
||||||
#define TZ_THFLAG_PSV (1<<0)
|
#define TZ_THFLAG_PSV (1<<0)
|
||||||
#define TZ_THFLAG_HOT (1<<2)
|
#define TZ_THFLAG_CR3 (1<<2)
|
||||||
#define TZ_THFLAG_CRT (1<<3)
|
#define TZ_THFLAG_HOT (1<<3)
|
||||||
|
#define TZ_THFLAG_CRT (1<<4)
|
||||||
int tz_flags;
|
int tz_flags;
|
||||||
#define TZ_FLAG_NO_SCP (1<<0) /*No _SCP method*/
|
#define TZ_FLAG_NO_SCP (1<<0) /*No _SCP method*/
|
||||||
#define TZ_FLAG_GETPROFILE (1<<1) /*Get power_profile in timeout*/
|
#define TZ_FLAG_GETPROFILE (1<<1) /*Get power_profile in timeout*/
|
||||||
@ -281,6 +283,10 @@ acpi_tz_attach(device_t dev)
|
|||||||
OID_AUTO, "_PSV", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE, sc,
|
OID_AUTO, "_PSV", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE, sc,
|
||||||
offsetof(struct acpi_tz_softc, tz_zone.psv), acpi_tz_temp_sysctl, "IK",
|
offsetof(struct acpi_tz_softc, tz_zone.psv), acpi_tz_temp_sysctl, "IK",
|
||||||
"passive cooling temp setpoint");
|
"passive cooling temp setpoint");
|
||||||
|
SYSCTL_ADD_PROC(&sc->tz_sysctl_ctx, SYSCTL_CHILDREN(sc->tz_sysctl_tree),
|
||||||
|
OID_AUTO, "_CR3", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE, sc,
|
||||||
|
offsetof(struct acpi_tz_softc, tz_zone.cr3), acpi_tz_temp_sysctl, "IK",
|
||||||
|
"too warm temp setpoint (standby now)");
|
||||||
SYSCTL_ADD_PROC(&sc->tz_sysctl_ctx, SYSCTL_CHILDREN(sc->tz_sysctl_tree),
|
SYSCTL_ADD_PROC(&sc->tz_sysctl_ctx, SYSCTL_CHILDREN(sc->tz_sysctl_tree),
|
||||||
OID_AUTO, "_HOT", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE, sc,
|
OID_AUTO, "_HOT", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE, sc,
|
||||||
offsetof(struct acpi_tz_softc, tz_zone.hot), acpi_tz_temp_sysctl, "IK",
|
offsetof(struct acpi_tz_softc, tz_zone.hot), acpi_tz_temp_sysctl, "IK",
|
||||||
@ -420,6 +426,7 @@ acpi_tz_establish(struct acpi_tz_softc *sc)
|
|||||||
}
|
}
|
||||||
acpi_tz_getparam(sc, "_CRT", &sc->tz_zone.crt);
|
acpi_tz_getparam(sc, "_CRT", &sc->tz_zone.crt);
|
||||||
acpi_tz_getparam(sc, "_HOT", &sc->tz_zone.hot);
|
acpi_tz_getparam(sc, "_HOT", &sc->tz_zone.hot);
|
||||||
|
acpi_tz_getparam(sc, "_CR3", &sc->tz_zone.cr3);
|
||||||
sc->tz_zone.psl.Length = ACPI_ALLOCATE_BUFFER;
|
sc->tz_zone.psl.Length = ACPI_ALLOCATE_BUFFER;
|
||||||
sc->tz_zone.psl.Pointer = NULL;
|
sc->tz_zone.psl.Pointer = NULL;
|
||||||
AcpiEvaluateObject(sc->tz_handle, "_PSL", NULL, &sc->tz_zone.psl);
|
AcpiEvaluateObject(sc->tz_handle, "_PSL", NULL, &sc->tz_zone.psl);
|
||||||
@ -437,6 +444,7 @@ acpi_tz_establish(struct acpi_tz_softc *sc)
|
|||||||
*/
|
*/
|
||||||
acpi_tz_sanity(sc, &sc->tz_zone.crt, "_CRT");
|
acpi_tz_sanity(sc, &sc->tz_zone.crt, "_CRT");
|
||||||
acpi_tz_sanity(sc, &sc->tz_zone.hot, "_HOT");
|
acpi_tz_sanity(sc, &sc->tz_zone.hot, "_HOT");
|
||||||
|
acpi_tz_sanity(sc, &sc->tz_zone.cr3, "_CR3");
|
||||||
acpi_tz_sanity(sc, &sc->tz_zone.psv, "_PSV");
|
acpi_tz_sanity(sc, &sc->tz_zone.psv, "_PSV");
|
||||||
for (i = 0; i < TZ_NUMLEVELS; i++)
|
for (i = 0; i < TZ_NUMLEVELS; i++)
|
||||||
acpi_tz_sanity(sc, &sc->tz_zone.ac[i], "_ACx");
|
acpi_tz_sanity(sc, &sc->tz_zone.ac[i], "_ACx");
|
||||||
@ -494,6 +502,7 @@ acpi_tz_get_temperature(struct acpi_tz_softc *sc)
|
|||||||
static void
|
static void
|
||||||
acpi_tz_monitor(void *Context)
|
acpi_tz_monitor(void *Context)
|
||||||
{
|
{
|
||||||
|
struct acpi_softc *acpi_sc;
|
||||||
struct acpi_tz_softc *sc;
|
struct acpi_tz_softc *sc;
|
||||||
struct timespec curtime;
|
struct timespec curtime;
|
||||||
int temp;
|
int temp;
|
||||||
@ -544,6 +553,8 @@ acpi_tz_monitor(void *Context)
|
|||||||
newflags = TZ_THFLAG_NONE;
|
newflags = TZ_THFLAG_NONE;
|
||||||
if (sc->tz_zone.psv != -1 && temp >= sc->tz_zone.psv)
|
if (sc->tz_zone.psv != -1 && temp >= sc->tz_zone.psv)
|
||||||
newflags |= TZ_THFLAG_PSV;
|
newflags |= TZ_THFLAG_PSV;
|
||||||
|
if (sc->tz_zone.cr3 != -1 && temp >= sc->tz_zone.cr3)
|
||||||
|
newflags |= TZ_THFLAG_CR3;
|
||||||
if (sc->tz_zone.hot != -1 && temp >= sc->tz_zone.hot)
|
if (sc->tz_zone.hot != -1 && temp >= sc->tz_zone.hot)
|
||||||
newflags |= TZ_THFLAG_HOT;
|
newflags |= TZ_THFLAG_HOT;
|
||||||
if (sc->tz_zone.crt != -1 && temp >= sc->tz_zone.crt)
|
if (sc->tz_zone.crt != -1 && temp >= sc->tz_zone.crt)
|
||||||
@ -603,13 +614,18 @@ acpi_tz_monitor(void *Context)
|
|||||||
*
|
*
|
||||||
* If we're almost at that threshold, notify the user through devd(8).
|
* If we're almost at that threshold, notify the user through devd(8).
|
||||||
*/
|
*/
|
||||||
if ((newflags & (TZ_THFLAG_HOT | TZ_THFLAG_CRT)) != 0) {
|
if ((newflags & (TZ_THFLAG_CR3 | TZ_THFLAG_HOT | TZ_THFLAG_CRT)) != 0) {
|
||||||
sc->tz_validchecks++;
|
sc->tz_validchecks++;
|
||||||
if (sc->tz_validchecks == TZ_VALIDCHECKS) {
|
if (sc->tz_validchecks == TZ_VALIDCHECKS) {
|
||||||
device_printf(sc->tz_dev,
|
device_printf(sc->tz_dev,
|
||||||
"WARNING - current temperature (%d.%dC) exceeds safe limits\n",
|
"WARNING - current temperature (%d.%dC) exceeds safe limits\n",
|
||||||
TZ_KELVTOC(sc->tz_temperature));
|
TZ_KELVTOC(sc->tz_temperature));
|
||||||
shutdown_nice(RB_POWEROFF);
|
if ((newflags & (TZ_THFLAG_HOT | TZ_THFLAG_CRT)) != 0)
|
||||||
|
shutdown_nice(RB_POWEROFF);
|
||||||
|
else {
|
||||||
|
acpi_sc = acpi_device_get_parent_softc(sc->tz_dev);
|
||||||
|
acpi_ReqSleepState(acpi_sc, ACPI_STATE_S3);
|
||||||
|
}
|
||||||
} else if (sc->tz_validchecks == TZ_NOTIFYCOUNT)
|
} else if (sc->tz_validchecks == TZ_NOTIFYCOUNT)
|
||||||
acpi_UserNotify("Thermal", sc->tz_handle, TZ_NOTIFY_CRITICAL);
|
acpi_UserNotify("Thermal", sc->tz_handle, TZ_NOTIFY_CRITICAL);
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
Reference in New Issue
Block a user