summaryrefslogtreecommitdiffstats
path: root/sys/dev/acpica/acpi_thermal.c
diff options
context:
space:
mode:
authormsmith <msmith@FreeBSD.org>2001-06-29 21:20:46 +0000
committermsmith <msmith@FreeBSD.org>2001-06-29 21:20:46 +0000
commit92a1c67dda98625aca215a53cb7b24237a93ecfa (patch)
treea20e640ab3550bef1e299b06a57e4533ebe35a70 /sys/dev/acpica/acpi_thermal.c
parentde71153c8ea0b32cd0de55f5f83fa55e71f1584a (diff)
downloadFreeBSD-src-92a1c67dda98625aca215a53cb7b24237a93ecfa.zip
FreeBSD-src-92a1c67dda98625aca215a53cb7b24237a93ecfa.tar.gz
Add ACPI lock support.
Pass the softc, not the device_t to the Notify handler. Don't invoke the Interpreter from callout context, as it may sleep. Use AcpiOsQueueForExecution, which is called from taskqueue_swi.
Diffstat (limited to 'sys/dev/acpica/acpi_thermal.c')
-rw-r--r--sys/dev/acpica/acpi_thermal.c65
1 files changed, 52 insertions, 13 deletions
diff --git a/sys/dev/acpica/acpi_thermal.c b/sys/dev/acpica/acpi_thermal.c
index d381b5d..6dd6da0 100644
--- a/sys/dev/acpica/acpi_thermal.c
+++ b/sys/dev/acpica/acpi_thermal.c
@@ -40,7 +40,7 @@
/*
* Hooks for the ACPI CA debugging infrastructure
*/
-#define _COMPONENT ACPI_THERMAL_ZONE
+#define _COMPONENT ACPI_THERMAL
MODULE_NAME("THERMAL")
#define TZ_ZEROC 2732
@@ -84,6 +84,7 @@ struct acpi_tz_softc {
static int acpi_tz_probe(device_t dev);
static int acpi_tz_attach(device_t dev);
static int acpi_tz_establish(struct acpi_tz_softc *sc);
+static void acpi_tz_monitor(struct acpi_tz_softc *sc);
static void acpi_tz_all_off(struct acpi_tz_softc *sc);
static void acpi_tz_switch_cooler_off(ACPI_OBJECT *obj, void *arg);
static void acpi_tz_switch_cooler_on(ACPI_OBJECT *obj, void *arg);
@@ -114,15 +115,21 @@ DRIVER_MODULE(acpi_tz, acpi, acpi_tz_driver, acpi_tz_devclass, 0, 0);
static int
acpi_tz_probe(device_t dev)
{
-
+ int result;
+
+ ACPI_LOCK;
+
/* no FUNCTION_TRACE - too noisy */
if ((acpi_get_type(dev) == ACPI_TYPE_THERMAL) &&
!acpi_disabled("thermal")) {
device_set_desc(dev, "thermal zone");
- return(-10);
+ result = -10;
+ } else {
+ result = ENXIO;
}
- return(ENXIO);
+ ACPI_UNLOCK;
+ return(result);
}
/*
@@ -136,6 +143,8 @@ acpi_tz_attach(device_t dev)
FUNCTION_TRACE(__func__);
+ ACPI_LOCK;
+
sc = device_get_softc(dev);
sc->tz_dev = dev;
sc->tz_handle = acpi_get_handle(dev);
@@ -145,19 +154,22 @@ acpi_tz_attach(device_t dev)
* structures.
*/
if ((error = acpi_tz_establish(sc)) != 0)
- return_VALUE(error);
+ goto out;
/*
* Register for any Notify events sent to this zone.
*/
AcpiInstallNotifyHandler(sc->tz_handle, ACPI_DEVICE_NOTIFY,
- acpi_tz_notify_handler, dev);
+ acpi_tz_notify_handler, sc);
/*
* Don't bother evaluating/printing the temperature at this point;
* on many systems it'll be bogus until the EC is running.
*/
- return_VALUE(0);
+
+ out:
+ ACPI_UNLOCK;
+ return_VALUE(error);
}
/*
@@ -174,6 +186,8 @@ acpi_tz_establish(struct acpi_tz_softc *sc)
FUNCTION_TRACE(__func__);
+ ACPI_ASSERTLOCK;
+
/*
* Power everything off and erase any existing state.
*/
@@ -242,6 +256,8 @@ acpi_tz_monitor(struct acpi_tz_softc *sc)
FUNCTION_TRACE(__func__);
+ ACPI_ASSERTLOCK;
+
/*
* Get the current temperature.
*/
@@ -250,6 +266,7 @@ acpi_tz_monitor(struct acpi_tz_softc *sc)
/* XXX disable zone? go to max cooling? */
return_VOID;
}
+ DEBUG_PRINT(TRACE_VALUES, ("got %d.%dC\n", TZ_KELVTOC(temp)));
/*
* Work out what we ought to be doing right now.
@@ -319,6 +336,8 @@ acpi_tz_all_off(struct acpi_tz_softc *sc)
int i;
FUNCTION_TRACE(__func__);
+
+ ACPI_ASSERTLOCK;
/*
* Scan all the _AL objects, and turn them all off.
@@ -350,6 +369,8 @@ acpi_tz_switch_cooler_off(ACPI_OBJECT *obj, void *arg)
FUNCTION_TRACE(__func__);
+ ACPI_ASSERTLOCK;
+
switch(obj->Type) {
case ACPI_TYPE_STRING:
DEBUG_PRINT(TRACE_OBJECTS, ("called to turn %s off\n", obj->String.Pointer));
@@ -383,16 +404,24 @@ static void
acpi_tz_switch_cooler_on(ACPI_OBJECT *obj, void *arg)
{
struct acpi_tz_softc *sc = (struct acpi_tz_softc *)arg;
- ACPI_HANDLE cooler, parent;
+ ACPI_HANDLE cooler;
FUNCTION_TRACE(__func__);
+ ACPI_ASSERTLOCK;
+
switch(obj->Type) {
case ACPI_TYPE_STRING:
DEBUG_PRINT(TRACE_OBJECTS, ("called to turn %s off\n", obj->String.Pointer));
- /* find the handle for the device and turn it off */
- if (acpi_GetHandleInScope(sc->tz_handle, obj->String.Pointer, &cooler) == AE_OK)
+ /*
+ * Find the handle for the device and turn it off.
+ * The String object here seems to contain a fully-qualified path, so we
+ * don't have to search for it in our parents.
+ *
+ * XXX This may not always be the case.
+ */
+ if (AcpiGetHandle(obj->String.Pointer, NULL, &cooler) == AE_OK)
acpi_pwr_switch_consumer(cooler, ACPI_STATE_D0);
break;
@@ -413,6 +442,8 @@ acpi_tz_getparam(struct acpi_tz_softc *sc, char *node, int *data)
FUNCTION_TRACE(__func__);
+ ACPI_ASSERTLOCK;
+
if (acpi_EvaluateInteger(sc->tz_handle, node, data) != AE_OK) {
*data = -1;
} else {
@@ -432,13 +463,17 @@ acpi_tz_notify_handler(ACPI_HANDLE h, UINT32 notify, void *context)
FUNCTION_TRACE(__func__);
+ ACPI_ASSERTLOCK;
+
switch(notify) {
case TZ_NOTIFY_TEMPERATURE:
- acpi_tz_monitor(sc); /* temperature change occurred */
+ /* temperature change occurred */
+ AcpiOsQueueForExecution(OSD_PRIORITY_HIGH, (OSD_EXECUTION_CALLBACK)acpi_tz_monitor, sc);
break;
case TZ_NOTIFY_DEVICES:
case TZ_NOTIFY_LEVELS:
- acpi_tz_establish(sc); /* zone devices/setpoints changed */
+ /* zone devices/setpoints changed */
+ AcpiOsQueueForExecution(OSD_PRIORITY_HIGH, (OSD_EXECUTION_CALLBACK)acpi_tz_establish, sc);
break;
default:
device_printf(sc->tz_dev, "unknown Notify event 0x%x\n", notify);
@@ -455,11 +490,15 @@ acpi_tz_timeout(void *arg)
{
struct acpi_tz_softc *sc = (struct acpi_tz_softc *)arg;
+ ACPI_LOCK;
+
/* check temperature, take action */
- acpi_tz_monitor(sc);
+ AcpiOsQueueForExecution(OSD_PRIORITY_HIGH, (OSD_EXECUTION_CALLBACK)acpi_tz_monitor, sc);
/* XXX passive cooling actions? */
/* re-register ourself */
sc->tz_timeout = timeout(acpi_tz_timeout, sc, TZ_POLLRATE);
+
+ ACPI_UNLOCK;
}
OpenPOWER on IntegriCloud