summaryrefslogtreecommitdiffstats
path: root/sys/dev/acpica/acpi_thermal.c
diff options
context:
space:
mode:
authoriwasaki <iwasaki@FreeBSD.org>2001-12-22 16:05:41 +0000
committeriwasaki <iwasaki@FreeBSD.org>2001-12-22 16:05:41 +0000
commit4c7abcd3372368396a11a120c259afdb0fe2b015 (patch)
tree7c96c678372cc5f9e23154023196e80b72311f86 /sys/dev/acpica/acpi_thermal.c
parent23a35cbf8dc1e76d3a4e856806e0ee472c65e5af (diff)
downloadFreeBSD-src-4c7abcd3372368396a11a120c259afdb0fe2b015.zip
FreeBSD-src-4c7abcd3372368396a11a120c259afdb0fe2b015.tar.gz
Add OS layer ACPI mutex and threading support.
- Temporary fix a bug of Intel ACPI CA core code. - Add OS layer ACPI mutex support. This can be disabled by specifying option ACPI_NO_SEMAPHORES. - Add ACPI threading support. Now that we have a dedicate taskqueue for ACPI tasks and more ACPI task threads can be created by specifying option ACPI_MAX_THREADS. - Change acpi_EvaluateIntoBuffer() behavior slightly to reuse given caller's buffer unless AE_BUFFER_OVERFLOW occurs. Also CM battery's evaluations were changed to use acpi_EvaluateIntoBuffer(). - Add new utility function acpi_ConvertBufferToInteger(). - Add simple locking for CM battery and temperature updating. - Fix a minor problem on EC locking. - Make the thermal zone polling rate to be changeable. - Change minor things on AcpiOsSignal(); in ACPI_SIGNAL_FATAL case, entering Debugger is easier to investigate the problem rather than panic.
Diffstat (limited to 'sys/dev/acpica/acpi_thermal.c')
-rw-r--r--sys/dev/acpica/acpi_thermal.c36
1 files changed, 31 insertions, 5 deletions
diff --git a/sys/dev/acpica/acpi_thermal.c b/sys/dev/acpica/acpi_thermal.c
index a2e10c8..9cde5f4 100644
--- a/sys/dev/acpica/acpi_thermal.c
+++ b/sys/dev/acpica/acpi_thermal.c
@@ -51,7 +51,7 @@ MODULE_NAME("THERMAL")
#define TZ_NOTIFY_DEVICES 0x81
#define TZ_NOTIFY_LEVELS 0x82
-#define TZ_POLLRATE (hz * 10) /* every ten seconds */
+#define TZ_POLLRATE 30 /* every 30 seconds by default */
#define TZ_NUMLEVELS 10 /* defined by ACPI spec */
struct acpi_tz_zone {
@@ -90,6 +90,8 @@ struct acpi_tz_softc {
struct sysctl_oid *tz_sysctl_tree;
struct acpi_tz_zone tz_zone; /* thermal zone parameters */
+ ACPI_BUFFER tz_tmp_buffer;
+ int tz_tmp_updating;
};
static int acpi_tz_probe(device_t dev);
@@ -127,6 +129,7 @@ static struct sysctl_ctx_list acpi_tz_sysctl_ctx;
static struct sysctl_oid *acpi_tz_sysctl_tree;
static int acpi_tz_min_runtime = 0;/* minimum cooling run time */
+static int acpi_tz_polling_rate = TZ_POLLRATE;
/*
* Match an ACPI thermal zone.
@@ -170,6 +173,8 @@ acpi_tz_attach(device_t dev)
sc->tz_dev = dev;
sc->tz_handle = acpi_get_handle(dev);
sc->tz_requested = TZ_ACTIVE_NONE;
+ bzero(&sc->tz_tmp_buffer, sizeof(sc->tz_tmp_buffer));
+ sc->tz_tmp_updating = 0;
/*
* Parse the current state of the thermal zone and build control
@@ -199,6 +204,10 @@ acpi_tz_attach(device_t dev)
SYSCTL_CHILDREN(acpi_tz_sysctl_tree),
OID_AUTO, "min_runtime", CTLFLAG_RD | CTLFLAG_RW,
&acpi_tz_min_runtime, 0, "minimum cooling run time in sec");
+ SYSCTL_ADD_INT(&acpi_tz_sysctl_ctx,
+ SYSCTL_CHILDREN(acpi_tz_sysctl_tree),
+ OID_AUTO, "polling_rate", CTLFLAG_RD | CTLFLAG_RW,
+ &acpi_tz_polling_rate, 0, "monitor polling rate");
}
sysctl_ctx_init(&sc->tz_sysctl_ctx);
sprintf(oidname, "tz%d", device_get_unit(dev));
@@ -249,7 +258,7 @@ acpi_tz_attach(device_t dev)
* Start the timeout routine, with enough delay for the rest of the
* subsystem to come up.
*/
- sc->tz_timeout = timeout(acpi_tz_timeout, sc, TZ_POLLRATE);
+ sc->tz_timeout = timeout(acpi_tz_timeout, sc, acpi_tz_polling_rate * hz);
return_VALUE(error);
}
@@ -288,6 +297,7 @@ acpi_tz_establish(struct acpi_tz_softc *sc)
sprintf(nbuf, "_AC%d", i);
acpi_tz_getparam(sc, nbuf, &sc->tz_zone.ac[i]);
sprintf(nbuf, "_AL%d", i);
+ bzero(&sc->tz_zone.al[i], sizeof(sc->tz_zone.al[i]));
acpi_EvaluateIntoBuffer(sc->tz_handle, nbuf, NULL, &sc->tz_zone.al[i]);
obj = (ACPI_OBJECT *)sc->tz_zone.al[i].Pointer;
if (obj != NULL) {
@@ -301,6 +311,7 @@ acpi_tz_establish(struct acpi_tz_softc *sc)
}
acpi_tz_getparam(sc, "_CRT", &sc->tz_zone.crt);
acpi_tz_getparam(sc, "_HOT", &sc->tz_zone.hot);
+ bzero(&sc->tz_zone.psl, sizeof(sc->tz_zone.psl));
acpi_EvaluateIntoBuffer(sc->tz_handle, "_PSL", NULL, &sc->tz_zone.psl);
acpi_tz_getparam(sc, "_PSV", &sc->tz_zone.psv);
acpi_tz_getparam(sc, "_TC1", &sc->tz_zone.tc1);
@@ -358,16 +369,29 @@ acpi_tz_monitor(struct acpi_tz_softc *sc)
ACPI_ASSERTLOCK;
+ if (sc->tz_tmp_updating) {
+ goto out;
+ }
+ sc->tz_tmp_updating = 1;
+
/*
* Get the current temperature.
*/
- if ((status = acpi_EvaluateInteger(sc->tz_handle, "_TMP", &temp)) != AE_OK) {
+ if ((status = acpi_EvaluateIntoBuffer(sc->tz_handle, "_TMP", NULL, &sc->tz_tmp_buffer)) != AE_OK) {
ACPI_VPRINT(sc->tz_dev, acpi_device_get_parent_softc(sc->tz_dev),
"error fetching current temperature -- %s\n",
AcpiFormatException(status));
/* XXX disable zone? go to max cooling? */
- return_VOID;
+ goto out;
}
+ if ((status = acpi_ConvertBufferToInteger(&sc->tz_tmp_buffer, &temp)) != AE_OK) {
+ ACPI_VPRINT(sc->tz_dev, acpi_device_get_parent_softc(sc->tz_dev),
+ "error fetching current temperature -- %s\n",
+ AcpiFormatException(status));
+ /* XXX disable zone? go to max cooling? */
+ goto out;
+ }
+
ACPI_DEBUG_PRINT((ACPI_DB_VALUES, "got %d.%dC\n", TZ_KELVTOC(temp)));
sc->tz_temperature = temp;
@@ -454,6 +478,8 @@ acpi_tz_monitor(struct acpi_tz_softc *sc)
}
sc->tz_thflags = newflags;
+out:
+ sc->tz_tmp_updating = 0;
return_VOID;
}
@@ -693,7 +719,7 @@ acpi_tz_timeout(void *arg)
/* XXX passive cooling actions? */
/* re-register ourself */
- sc->tz_timeout = timeout(acpi_tz_timeout, sc, TZ_POLLRATE);
+ sc->tz_timeout = timeout(acpi_tz_timeout, sc, acpi_tz_polling_rate * hz);
ACPI_UNLOCK;
}
OpenPOWER on IntegriCloud