diff options
author | msmith <msmith@FreeBSD.org> | 2001-06-29 21:20:46 +0000 |
---|---|---|
committer | msmith <msmith@FreeBSD.org> | 2001-06-29 21:20:46 +0000 |
commit | 92a1c67dda98625aca215a53cb7b24237a93ecfa (patch) | |
tree | a20e640ab3550bef1e299b06a57e4533ebe35a70 /sys/dev/acpica/acpi_thermal.c | |
parent | de71153c8ea0b32cd0de55f5f83fa55e71f1584a (diff) | |
download | FreeBSD-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.c | 65 |
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; } |