summaryrefslogtreecommitdiffstats
path: root/sys/dev/acpica/acpi_ec.c
diff options
context:
space:
mode:
authornjl <njl@FreeBSD.org>2004-05-25 02:47:35 +0000
committernjl <njl@FreeBSD.org>2004-05-25 02:47:35 +0000
commit70e389d6cfb11f189060d16fde82012e8c1d8aeb (patch)
tree25ff73bb09231d547c140b54615b5edf5ba0f276 /sys/dev/acpica/acpi_ec.c
parenta714b78fea0d6c73e38a47e7db9e0b44c9814856 (diff)
downloadFreeBSD-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/acpi_ec.c')
-rw-r--r--sys/dev/acpica/acpi_ec.c51
1 files changed, 31 insertions, 20 deletions
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
OpenPOWER on IntegriCloud