diff options
author | njl <njl@FreeBSD.org> | 2004-05-25 02:47:35 +0000 |
---|---|---|
committer | njl <njl@FreeBSD.org> | 2004-05-25 02:47:35 +0000 |
commit | 70e389d6cfb11f189060d16fde82012e8c1d8aeb (patch) | |
tree | 25ff73bb09231d547c140b54615b5edf5ba0f276 /sys/dev/acpica | |
parent | a714b78fea0d6c73e38a47e7db9e0b44c9814856 (diff) | |
download | FreeBSD-src-70e389d6cfb11f189060d16fde82012e8c1d8aeb.zip FreeBSD-src-70e389d6cfb11f189060d16fde82012e8c1d8aeb.tar.gz |
Changes to implement 20040514:
* Add calls to AcpiSetGpeType. We use wake/run as the type for lid and
button switches since wake-only causes Thinkpads to immediately wake on
the second suspend. Note that with wake/run, some systems return both
wake and device-specific notifies so we don't register for system notifies
for lid and button switches.
* Remove the hw.acpi.osi_method tunable since it is not needed.
* Always print unknown notifies for all types.
* Add more cleanup for the EC if it fails to attach.
* Use the GPE handle now that we parse it. This allows GPEs to be defined
in AML GPE blocks.
* Always use ACPI_NOT_ISR since it's ok to acquire a mutex in our thread
which processes queued requests.
Diffstat (limited to 'sys/dev/acpica')
-rw-r--r-- | sys/dev/acpica/acpi.c | 33 | ||||
-rw-r--r-- | sys/dev/acpica/acpi_acad.c | 7 | ||||
-rw-r--r-- | sys/dev/acpica/acpi_button.c | 11 | ||||
-rw-r--r-- | sys/dev/acpica/acpi_ec.c | 51 | ||||
-rw-r--r-- | sys/dev/acpica/acpi_lid.c | 10 |
5 files changed, 67 insertions, 45 deletions
diff --git a/sys/dev/acpica/acpi.c b/sys/dev/acpica/acpi.c index af035f2..53b643a 100644 --- a/sys/dev/acpica/acpi.c +++ b/sys/dev/acpica/acpi.c @@ -201,17 +201,6 @@ static int acpi_serialize_methods; TUNABLE_INT("hw.acpi.serialize_methods", &acpi_serialize_methods); /* - * Allow override of whether to support the _OSI method. This allows us - * to claim compatibility with various MS OSs without changing the value - * we report for _OS. This is enabled by default since it fixes some - * problems with interrupt routing although it can be disabled if it - * causes problems. See the definition of "AcpiGbl_ValidOsiStrings" for - * a list of systems we claim. - */ -static int acpi_osi_method = TRUE; -TUNABLE_INT("hw.acpi.osi_method", &acpi_osi_method); - -/* * ACPI can only be loaded as a module by the loader; activating it after * system bootstrap time is not useful, and can be fatal to the system. * It also cannot be unloaded, since the entire system bus heirarchy hangs @@ -261,11 +250,9 @@ acpi_Startup(void) /* * Set the globals from our tunables. This is needed because ACPI-CA - * uses UINT8 for some values and we have no tunable_uint8. + * uses UINT8 for some values and we have no tunable_byte. */ - AcpiGbl_AllMethodsSerialized = acpi_serialize_methods; - AcpiGbl_CreateOsiMethod = acpi_osi_method; - AcpiGbl_LeaveWakeGpesDisabled = FALSE; + AcpiGbl_AllMethodsSerialized = (UINT8)acpi_serialize_methods; /* Start up the ACPI CA subsystem. */ #ifdef ACPI_DEBUGGER @@ -2057,7 +2044,13 @@ acpi_device_enable_wake_event(ACPI_HANDLE h) * enabled for the wake event. */ gpe_bit = res->Package.Elements[0].Integer.Value; - status = AcpiEnableGpe(NULL, gpe_bit, ACPI_EVENT_WAKE_ENABLE); + status = AcpiSetGpeType(NULL, gpe_bit, ACPI_GPE_TYPE_WAKE_RUN); + if (ACPI_FAILURE(status)) { + printf("wake enable: AcpiSetGpeType failed for %u\n", + gpe_bit); + goto out; + } + status = AcpiEnableGpe(NULL, gpe_bit, ACPI_NOT_ISR); if (ACPI_FAILURE(status)) printf("wake enable: AcpiEnableGpe failed for %u\n", gpe_bit); @@ -2082,7 +2075,13 @@ acpi_device_enable_wake_event(ACPI_HANDLE h) handle = acpi_GetReference(NULL, &res2->Package.Elements[0]); if (handle == NULL || acpi_PkgInt32(res2, 1, &gpe_bit) != 0) goto out; - status = AcpiEnableGpe(handle, gpe_bit, ACPI_EVENT_WAKE_ENABLE); + status = AcpiSetGpeType(handle, gpe_bit, ACPI_GPE_TYPE_WAKE_RUN); + if (ACPI_FAILURE(status)) { + printf("wake enable: AcpiSetGpeType failed for %u\n", + gpe_bit); + goto out; + } + status = AcpiEnableGpe(handle, gpe_bit, ACPI_NOT_ISR); if (ACPI_FAILURE(status)) printf("wake enable: AcpiEnableGpe (package) failed for %u\n", gpe_bit); diff --git a/sys/dev/acpica/acpi_acad.c b/sys/dev/acpica/acpi_acad.c index af22286..d6b2e20 100644 --- a/sys/dev/acpica/acpi_acad.c +++ b/sys/dev/acpica/acpi_acad.c @@ -116,11 +116,9 @@ acpi_acad_get_status(void *context) static void acpi_acad_notify_handler(ACPI_HANDLE h, UINT32 notify, void *context) { - device_t dev = context; - - ACPI_VPRINT(dev, acpi_device_get_parent_softc(dev), - "Notify 0x%x\n", notify); + device_t dev; + dev = (device_t)context; switch (notify) { case ACPI_DEVICE_CHECK_PNP: case ACPI_DEVICE_CHECK_EXISTENCE: @@ -129,6 +127,7 @@ acpi_acad_notify_handler(ACPI_HANDLE h, UINT32 notify, void *context) AcpiOsQueueForExecution(OSD_PRIORITY_LO, acpi_acad_get_status, context); break; default: + device_printf(dev, "unknown notify %#x\n", notify); break; } } diff --git a/sys/dev/acpica/acpi_button.c b/sys/dev/acpica/acpi_button.c index 8071102..121ebec 100644 --- a/sys/dev/acpica/acpi_button.c +++ b/sys/dev/acpica/acpi_button.c @@ -141,6 +141,11 @@ acpi_button_attach(device_t dev) status = AcpiInstallFixedEventHandler(event, acpi_button_fixed_handler, sc); } else { + /* + * If a system does not get lid events, it may make sense to change + * the type to ACPI_ALL_NOTIFY. Some systems generate both a wake + * and runtime notify in that case though. + */ status = AcpiInstallNotifyHandler(sc->button_handle, ACPI_DEVICE_NOTIFY, acpi_button_notify_handler, sc); } @@ -231,10 +236,11 @@ acpi_button_notify_wakeup(void *arg) static void acpi_button_notify_handler(ACPI_HANDLE h, UINT32 notify, void *context) { - struct acpi_button_softc *sc = (struct acpi_button_softc *)context; + struct acpi_button_softc *sc; ACPI_FUNCTION_TRACE_U32((char *)(uintptr_t)__func__, notify); + sc = (struct acpi_button_softc *)context; switch (notify) { case ACPI_NOTIFY_BUTTON_PRESSED_FOR_SLEEP: AcpiOsQueueForExecution(OSD_PRIORITY_LO, @@ -245,7 +251,8 @@ acpi_button_notify_handler(ACPI_HANDLE h, UINT32 notify, void *context) acpi_button_notify_wakeup, sc); break; default: - break; /* unknown notification value */ + device_printf(sc->button_dev, "unknown notify %#x\n", notify); + break; } } diff --git a/sys/dev/acpica/acpi_ec.c b/sys/dev/acpica/acpi_ec.c index 7d65fc9..474f132 100644 --- a/sys/dev/acpica/acpi_ec.c +++ b/sys/dev/acpica/acpi_ec.c @@ -323,7 +323,7 @@ EcUnlock(struct acpi_ec_softc *sc) mtx_unlock(&sc->ec_mtx); } -static void EcGpeHandler(void *Context); +static uint32_t EcGpeHandler(void *Context); static ACPI_STATUS EcSpaceSetup(ACPI_HANDLE Region, UINT32 Function, void *Context, void **return_Context); static ACPI_STATUS EcSpaceHandler(UINT32 Function, @@ -540,7 +540,6 @@ acpi_ec_attach(device_t dev) struct acpi_ec_softc *sc; struct acpi_ec_params *params; ACPI_STATUS Status; - int errval = 0; ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); @@ -565,8 +564,7 @@ acpi_ec_attach(device_t dev) &sc->ec_data_rid, RF_ACTIVE); if (sc->ec_data_res == NULL) { device_printf(dev, "can't allocate data port\n"); - errval = ENXIO; - goto out; + goto error; } sc->ec_data_tag = rman_get_bustag(sc->ec_data_res); sc->ec_data_handle = rman_get_bushandle(sc->ec_data_res); @@ -576,8 +574,7 @@ acpi_ec_attach(device_t dev) &sc->ec_csr_rid, RF_ACTIVE); if (sc->ec_csr_res == NULL) { device_printf(dev, "can't allocate command/status port\n"); - errval = ENXIO; - goto out; + goto error; } sc->ec_csr_tag = rman_get_bustag(sc->ec_csr_res); sc->ec_csr_handle = rman_get_bushandle(sc->ec_csr_res); @@ -592,8 +589,7 @@ acpi_ec_attach(device_t dev) if (ACPI_FAILURE(Status)) { device_printf(dev, "can't install GPE handler for %s - %s\n", acpi_name(sc->ec_handle), AcpiFormatException(Status)); - errval = ENXIO; - goto out; + goto error; } /* @@ -605,18 +601,31 @@ acpi_ec_attach(device_t dev) if (ACPI_FAILURE(Status)) { device_printf(dev, "can't install address space handler for %s - %s\n", acpi_name(sc->ec_handle), AcpiFormatException(Status)); - Status = AcpiRemoveGpeHandler(sc->ec_gpehandle, sc->ec_gpebit, - &EcGpeHandler); - if (ACPI_FAILURE(Status)) - panic("Added GPE handler but can't remove it"); - errval = ENXIO; - goto out; + goto error; + } + + /* Enable runtime GPEs for the handler. */ + Status = AcpiSetGpeType(sc->ec_gpehandle, sc->ec_gpebit, + ACPI_GPE_TYPE_RUNTIME); + if (ACPI_FAILURE(Status)) { + device_printf(dev, "AcpiSetGpeType failed: %s\n", + AcpiFormatException(Status)); + goto error; + } + Status = AcpiEnableGpe(sc->ec_gpehandle, sc->ec_gpebit, ACPI_NOT_ISR); + if (ACPI_FAILURE(Status)) { + device_printf(dev, "AcpiEnableGpe failed: %s\n", + AcpiFormatException(Status)); + goto error; } ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "acpi_ec_attach complete\n")); return (0); - out: +error: + AcpiRemoveGpeHandler(sc->ec_gpehandle, sc->ec_gpebit, &EcGpeHandler); + AcpiRemoveAddressSpaceHandler(sc->ec_handle, ACPI_ADR_SPACE_EC, + EcSpaceHandler); if (sc->ec_csr_res) bus_release_resource(sc->ec_dev, SYS_RES_IOPORT, sc->ec_csr_rid, sc->ec_csr_res); @@ -624,7 +633,7 @@ acpi_ec_attach(device_t dev) bus_release_resource(sc->ec_dev, SYS_RES_IOPORT, sc->ec_data_rid, sc->ec_data_res); mtx_destroy(&sc->ec_mtx); - return (errval); + return (ENXIO); } static void @@ -689,7 +698,7 @@ EcGpeQueryHandler(void *Context) re_enable: /* Re-enable the GPE event so we'll get future requests. */ - Status = AcpiEnableGpe(NULL, sc->ec_gpebit, ACPI_NOT_ISR); + Status = AcpiEnableGpe(sc->ec_gpehandle, sc->ec_gpebit, ACPI_NOT_ISR); if (ACPI_FAILURE(Status)) printf("EcGpeQueryHandler: AcpiEnableEvent failed\n"); } @@ -699,7 +708,7 @@ re_enable: * be handled by polling in EcWaitEvent(). This is because some ECs * treat events as level when they should be edge-triggered. */ -static void +static uint32_t EcGpeHandler(void *Context) { struct acpi_ec_softc *sc = Context; @@ -708,17 +717,19 @@ EcGpeHandler(void *Context) KASSERT(Context != NULL, ("EcGpeHandler called with NULL")); /* Disable further GPEs while we handle this one. */ - AcpiDisableGpe(NULL, sc->ec_gpebit, ACPI_ISR); + AcpiDisableGpe(sc->ec_gpehandle, sc->ec_gpebit, ACPI_NOT_ISR); /* Schedule the GPE query handler. */ Status = AcpiOsQueueForExecution(OSD_PRIORITY_GPE, EcGpeQueryHandler, Context); if (ACPI_FAILURE(Status)) { printf("Queuing GPE query handler failed.\n"); - Status = AcpiEnableGpe(NULL, sc->ec_gpebit, ACPI_ISR); + Status = AcpiEnableGpe(sc->ec_gpehandle, sc->ec_gpebit, ACPI_NOT_ISR); if (ACPI_FAILURE(Status)) printf("EcGpeHandler: AcpiEnableEvent failed\n"); } + + return (0); } static ACPI_STATUS diff --git a/sys/dev/acpica/acpi_lid.c b/sys/dev/acpica/acpi_lid.c index 1758e17..5f64a62 100644 --- a/sys/dev/acpica/acpi_lid.c +++ b/sys/dev/acpica/acpi_lid.c @@ -100,7 +100,11 @@ acpi_lid_attach(device_t dev) sc->lid_dev = dev; sc->lid_handle = acpi_get_handle(dev); - /* Install notification handler */ + /* + * If a system does not get lid events, it may make sense to change + * the type to ACPI_ALL_NOTIFY. Some systems generate both a wake and + * runtime notify in that case though. + */ AcpiInstallNotifyHandler(sc->lid_handle, ACPI_DEVICE_NOTIFY, acpi_lid_notify_handler, sc); acpi_device_enable_wake_capability(sc->lid_handle, 1); @@ -167,16 +171,18 @@ acpi_lid_notify_status_changed(void *arg) static void acpi_lid_notify_handler(ACPI_HANDLE h, UINT32 notify, void *context) { - struct acpi_lid_softc *sc = (struct acpi_lid_softc *)context; + struct acpi_lid_softc *sc; ACPI_FUNCTION_TRACE_U32((char *)(uintptr_t)__func__, notify); + sc = (struct acpi_lid_softc *)context; switch (notify) { case ACPI_NOTIFY_STATUS_CHANGED: AcpiOsQueueForExecution(OSD_PRIORITY_LO, acpi_lid_notify_status_changed, sc); break; default: + device_printf(sc->lid_dev, "unknown notify %#x\n", notify); break; } |