Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/acpi Add ACPI ECDT (Embedded Controller Description ...
details: https://anonhg.NetBSD.org/src/rev/0595dd38caaa
branches: trunk
changeset: 565139:0595dd38caaa
user: kochi <kochi%NetBSD.org@localhost>
date: Tue Mar 30 15:18:55 2004 +0000
description:
Add ACPI ECDT (Embedded Controller Description Table) support.
This will enable usage of EC in early stage of ACPI initialization.
diffstat:
sys/dev/acpi/acpi.c | 8 +-
sys/dev/acpi/acpi_ec.c | 177 ++++++++++++++++++++++++++++++++++++++++--------
sys/dev/acpi/acpivar.h | 4 +-
3 files changed, 154 insertions(+), 35 deletions(-)
diffs (truncated from 355 to 300 lines):
diff -r 53134dce4e05 -r 0595dd38caaa sys/dev/acpi/acpi.c
--- a/sys/dev/acpi/acpi.c Tue Mar 30 15:16:17 2004 +0000
+++ b/sys/dev/acpi/acpi.c Tue Mar 30 15:18:55 2004 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: acpi.c,v 1.59 2004/03/23 19:00:03 drochner Exp $ */
+/* $NetBSD: acpi.c,v 1.60 2004/03/30 15:18:55 kochi Exp $ */
/*-
* Copyright (c) 2003 The NetBSD Foundation, Inc.
@@ -77,7 +77,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: acpi.c,v 1.59 2004/03/23 19:00:03 drochner Exp $");
+__KERNEL_RCSID(0, "$NetBSD: acpi.c,v 1.60 2004/03/30 15:18:55 kochi Exp $");
#include "opt_acpi.h"
@@ -292,6 +292,10 @@
sc->sc_dev.dv_xname, AcpiFormatException(rv));
return;
}
+
+ /* early EC handler initialization if ECDT table is available */
+ acpiec_early_attach(&sc->sc_dev);
+
rv = AcpiInitializeObjects(0);
if (ACPI_FAILURE(rv)) {
printf("%s: unable to initialize ACPI objects: %s\n",
diff -r 53134dce4e05 -r 0595dd38caaa sys/dev/acpi/acpi_ec.c
--- a/sys/dev/acpi/acpi_ec.c Tue Mar 30 15:16:17 2004 +0000
+++ b/sys/dev/acpi/acpi_ec.c Tue Mar 30 15:18:55 2004 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: acpi_ec.c,v 1.22 2004/03/24 14:47:19 kanaoka Exp $ */
+/* $NetBSD: acpi_ec.c,v 1.23 2004/03/30 15:18:56 kochi Exp $ */
/*
* Copyright 2001 Wasabi Systems, Inc.
@@ -172,11 +172,12 @@
*****************************************************************************/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: acpi_ec.c,v 1.22 2004/03/24 14:47:19 kanaoka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: acpi_ec.c,v 1.23 2004/03/30 15:18:56 kochi Exp $");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/device.h>
+#include <sys/malloc.h>
#include <sys/proc.h>
#include <sys/kernel.h>
@@ -187,12 +188,14 @@
#include <dev/acpi/acpivar.h>
#include <dev/acpi/acpi_ecreg.h>
+MALLOC_DECLARE(M_ACPI);
+
#define _COMPONENT ACPI_EC_COMPONENT
ACPI_MODULE_NAME("EC")
struct acpi_ec_softc {
struct device sc_dev; /* base device glue */
- struct acpi_devnode *sc_node; /* our ACPI devnode */
+ ACPI_HANDLE sc_handle; /* ACPI handle */
struct acpi_resources sc_res; /* our bus resources */
@@ -207,12 +210,13 @@
int sc_flags; /* see below */
uint32_t sc_csrvalue; /* saved control register */
+ uint32_t sc_uid; /* _UID in namespace (ECDT only) */
struct lock sc_lock; /* serialize operations to this EC */
struct simplelock sc_slock; /* protect against interrupts */
UINT32 sc_glkhandle; /* global lock handle */
UINT32 sc_glk; /* need global lock? */
-} *acpiec_ecdt_softc;
+};
static const char * const ec_hid[] = {
"PNP0C09",
@@ -272,6 +276,8 @@
CFATTACH_DECL(acpiec, sizeof(struct acpi_ec_softc),
acpiec_match, acpiec_attach, NULL, NULL);
+static struct acpi_ec_softc *ecdt_sc;
+
static __inline int
EcIsLocked(struct acpi_ec_softc *sc)
{
@@ -360,33 +366,107 @@
return (acpi_match_hid(aa->aa_node->ad_devinfo, ec_hid));
}
-#if 0
void
acpiec_early_attach(struct device *parent)
{
+ struct acpi_softc *sc = (struct acpi_softc *)parent;
EC_BOOT_RESOURCES *ep;
ACPI_HANDLE handle;
+ ACPI_STATUS rv;
+ ACPI_INTEGER tmp;
- status = AcpiGetFirmwareTable("ECDT", 1, ACPI_LOGICAL_ADDRESSING,
- (ACPI_TABLE_HEADER **)&ep;
- if (ACPI_FAILURE(status))
+ rv = AcpiGetFirmwareTable("ECDT", 1, ACPI_LOGICAL_ADDRESSING,
+ (void *)&ep);
+ if (ACPI_FAILURE(rv))
return;
if (ep->EcControl.RegisterBitWidth != 8 ||
ep->EcData.RegisterBitWidth != 8) {
printf("%s: ECDT data is invalid, RegisterBitWidth=%d/%d\n",
+ parent->dv_xname,
ep->EcControl.RegisterBitWidth, ep->EcData.RegisterBitWidth);
return;
}
- status = AcpiGetHandle(ACPI_ROOT_OBJECT, ep->EcId, &handle);
- if (ACPI_FAILURE(status)) {
- printf("%s: failed to look up EC object %s: %s\n", ep->EcId,
- AcpiFormatExeception(status));
- return (status);
+ rv = AcpiGetHandle(ACPI_ROOT_OBJECT, ep->EcId, &handle);
+ if (ACPI_FAILURE(rv)) {
+ printf("%s: failed to look up EC object %s: %s\n",
+ parent->dv_xname,
+ ep->EcId, AcpiFormatException(rv));
+ return;
+ }
+
+ ecdt_sc = malloc(sizeof(*ecdt_sc), M_ACPI, M_ZERO);
+
+ strcpy(ecdt_sc->sc_dev.dv_xname, "acpiecdt0"); /* XXX */
+ ecdt_sc->sc_handle = handle;
+
+ ecdt_sc->sc_gpebit = ep->GpeBit;
+ ecdt_sc->sc_uid = ep->Uid;
+
+ ecdt_sc->sc_data_st = sc->sc_iot;
+ if (bus_space_map(ecdt_sc->sc_data_st,
+ (bus_addr_t)(ep->EcData.Address), 1, 0,
+ &ecdt_sc->sc_data_sh) != 0) {
+ printf("%s: bus_space_map failed for EC data.\n",
+ parent->dv_xname);
+ goto out1;
+ }
+
+ ecdt_sc->sc_csr_st = sc->sc_iot;
+ if (bus_space_map(ecdt_sc->sc_csr_st,
+ (bus_addr_t)(ep->EcControl.Address), 1, 0,
+ &ecdt_sc->sc_csr_sh) != 0) {
+ printf("%s: bus_space_map failed for EC control.\n",
+ parent->dv_xname);
+ goto out2;
}
+
+ rv = acpi_eval_integer(handle, "_GLK", &tmp);
+ if (ACPI_SUCCESS(rv) && tmp == 1)
+ ecdt_sc->sc_glk = 1;
+
+ rv = AcpiInstallGpeHandler(NULL, ecdt_sc->sc_gpebit,
+ ACPI_EVENT_EDGE_TRIGGERED, EcGpeHandler, ecdt_sc);
+ if (ACPI_FAILURE(rv)) {
+ printf("%s: unable to install GPE handler: %s\n",
+ parent->dv_xname,
+ AcpiFormatException(rv));
+ goto out3;
+ }
+
+ rv = AcpiInstallAddressSpaceHandler(ACPI_ROOT_OBJECT,
+ ACPI_ADR_SPACE_EC, EcSpaceHandler, EcSpaceSetup, ecdt_sc);
+ if (ACPI_FAILURE(rv)) {
+ printf("%s: unable to install address space handler: %s\n",
+ parent->dv_xname,
+ AcpiFormatException(rv));
+ goto out4;
+ }
+
+ printf("%s: found ECDT, GPE %d\n", parent->dv_xname,
+ ecdt_sc->sc_gpebit);
+
+ lockinit(&ecdt_sc->sc_lock, PWAIT, "eclock", 0, 0);
+ simple_lock_init(&ecdt_sc->sc_slock);
+
+ AcpiOsUnmapMemory(ep, ep->Length);
+ return;
+
+ out4:
+ AcpiRemoveGpeHandler(NULL, ecdt_sc->sc_gpebit, EcGpeHandler);
+ out3:
+ bus_space_unmap(ecdt_sc->sc_csr_st, ecdt_sc->sc_csr_sh, 1);
+ out2:
+ bus_space_unmap(ecdt_sc->sc_data_st, ecdt_sc->sc_data_sh, 1);
+ out1:
+ free(ecdt_sc, M_ACPI);
+ ecdt_sc = NULL;
+
+ AcpiOsUnmapMemory(ep, ep->Length);
+
+ return;
}
-#endif
/*
* acpiec_attach:
@@ -409,15 +489,41 @@
lockinit(&sc->sc_lock, PWAIT, "eclock", 0, 0);
simple_lock_init(&sc->sc_slock);
- sc->sc_node = aa->aa_node;
+ sc->sc_handle = aa->aa_node->ad_handle;
/* Parse our resources. */
ACPI_DEBUG_PRINT((ACPI_DB_RESOURCES, "parsing EC resources\n"));
- rv = acpi_resource_parse(&sc->sc_dev, sc->sc_node, &sc->sc_res,
+ rv = acpi_resource_parse(&sc->sc_dev, aa->aa_node, &sc->sc_res,
&acpi_resource_parse_ops_default);
if (ACPI_FAILURE(rv))
return;
+ rv = acpi_eval_integer(aa->aa_node->ad_handle, "_UID", &v);
+
+ /* check if we already attached EC via ECDT */
+ if (ACPI_SUCCESS(rv) && ecdt_sc && ecdt_sc->sc_uid == v) {
+
+ /* detach all ECDT handles */
+ rv = AcpiRemoveAddressSpaceHandler(ACPI_ROOT_OBJECT,
+ ACPI_ADR_SPACE_EC, EcSpaceHandler);
+ if (ACPI_FAILURE(rv))
+ printf("ERROR: RemoveAddressSpaceHandler: %s\n",
+ AcpiFormatException(rv));
+ rv = AcpiRemoveGpeHandler(NULL, ecdt_sc->sc_gpebit,
+ EcGpeHandler);
+ if (ACPI_FAILURE(rv))
+ printf("ERROR: RemoveAddressSpaceHandler: %s\n",
+ AcpiFormatException(rv));
+
+ bus_space_unmap(ecdt_sc->sc_csr_st,
+ ecdt_sc->sc_csr_sh, 1);
+ bus_space_unmap(ecdt_sc->sc_data_st,
+ ecdt_sc->sc_data_sh, 1);
+
+ free(ecdt_sc, M_ACPI);
+ ecdt_sc = NULL;
+ }
+
sc->sc_data_st = aa->aa_iot;
io0 = acpi_res_io(&sc->sc_res, 0);
if (io0 == NULL) {
@@ -447,12 +553,26 @@
}
/*
+ * evaluate _GLK to see if we should acquire global lock
+ * when accessing the EC.
+ */
+ rv = acpi_eval_integer(sc->sc_handle, "_GLK", &v);
+ if (ACPI_FAILURE(rv)) {
+ if (rv != AE_NOT_FOUND)
+ printf("%s: unable to evaluate _GLK: %s\n",
+ sc->sc_dev.dv_xname,
+ AcpiFormatException(rv));
+ sc->sc_glk = 0;
+ } else
+ sc->sc_glk = v;
+
+ /*
* Install GPE handler.
*
* We evaluate the _GPE method to find the GPE bit used by the
* Embedded Controller to signal status (SCI).
*/
- rv = acpi_eval_integer(sc->sc_node->ad_handle, "_GPE", &v);
+ rv = acpi_eval_integer(sc->sc_handle, "_GPE", &v);
if (ACPI_FAILURE(rv)) {
printf("%s: unable to evaluate _GPE: %s\n",
sc->sc_dev.dv_xname, AcpiFormatException(rv));
@@ -461,18 +581,6 @@
sc->sc_gpebit = v;
/*
- * evaluate _GLK to see if we should acquire global lock
- * when accessing the EC.
- */
- rv = acpi_eval_integer(sc->sc_node->ad_handle, "_GLK", &v);
- if (ACPI_FAILURE(rv)) {
- if (rv != AE_NOT_FOUND)
- printf("%s: unable to evaluate _GLK: %s\n",
- sc->sc_dev.dv_xname, AcpiFormatException(rv));
- sc->sc_glk = 0;
- } else
- sc->sc_glk = v;
- /*
* Install a handler for this EC's GPE bit. Note that EC SCIs are
* treated as both edge- and level-triggered interrupts; in other words
Home |
Main Index |
Thread Index |
Old Index