Index: acpi.c
===================================================================
RCS file: /cvsroot/src/sys/dev/acpi/acpi.c,v
retrieving revision 1.57
diff -u -r1.57 acpi.c
--- acpi.c 3 Nov 2003 18:51:31 -0000 1.57
+++ acpi.c 21 Dec 2003 09:10:25 -0000
@@ -293,6 +293,10 @@
sc->sc_dev.dv_xname, AcpiFormatException(rv));
return;
}
+
+ /* early EC handler initialization if ECDT table is available */
+ acpiec_early_attach(sc);
+
rv = AcpiInitializeObjects(0);
if (ACPI_FAILURE(rv)) {
printf("%s: unable to initialize ACPI objects: %s\n",
Index: acpi_ec.c
===================================================================
RCS file: /cvsroot/src/sys/dev/acpi/acpi_ec.c,v
retrieving revision 1.20
diff -u -r1.20 acpi_ec.c
--- acpi_ec.c 12 Nov 2003 13:59:23 -0000 1.20
+++ acpi_ec.c 21 Dec 2003 09:10:26 -0000
@@ -177,6 +177,7 @@
#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,6 +188,8 @@
#include <dev/acpi/acpivar.h>
#include <dev/acpi/acpi_ecreg.h>
+MALLOC_DECLARE(M_ACPI);
+
#define _COMPONENT ACPI_EC_COMPONENT
ACPI_MODULE_NAME("EC")
@@ -207,12 +210,13 @@
int sc_flags; /* see below */
uint32_t sc_csrvalue; /* saved control register */
+ uint32_t sc_uid; /* unique id in namespace */
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",
@@ -360,33 +364,107 @@
return (acpi_match_hid(aa->aa_node->ad_devinfo, ec_hid));
}
-#if 0
+struct acpi_ec_softc *ecdt_sc;
+struct acpi_devnode *ecdt_node;
+
void
-acpiec_early_attach(struct device *parent)
+acpiec_early_attach(struct acpi_softc *parent)
{
EC_BOOT_RESOURCES *ep;
ACPI_HANDLE handle;
+ ACPI_STATUS rv;
+ int 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->sc_dev.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->sc_dev.dv_xname,
+ ep->EcId, AcpiFormatException(rv));
+ return;
+ }
+
+ ecdt_sc = malloc(sizeof(*ecdt_sc), M_ACPI, M_ZERO);
+ ecdt_node = malloc(sizeof(*ecdt_node), M_ACPI, M_ZERO);
+
+ strcpy(ecdt_sc->sc_dev.dv_xname, "acpiecdt0"); /* XXX */
+ ecdt_node->ad_handle = handle;
+ ecdt_sc->sc_node = ecdt_node;
+
+ ecdt_sc->sc_gpebit = ep->GpeBit;
+ ecdt_sc->sc_uid = ep->Uid;
+
+ ecdt_sc->sc_data_st = parent->sc_iot;
+ if (bus_space_map(ecdt_sc->sc_data_st, ep->EcData.Address, 1, 0,
+ &ecdt_sc->sc_data_sh) != 0) {
+ printf("%s: bus_space_map failed for EC data.\n",
+ parent->sc_dev.dv_xname);
+ goto err_exit1;
+ }
+
+ ecdt_sc->sc_csr_st = parent->sc_iot;
+ if (bus_space_map(ecdt_sc->sc_csr_st, ep->EcControl.Address, 1, 0,
+ &ecdt_sc->sc_csr_sh) != 0) {
+ printf("%s: bus_space_map failed for EC control.\n",
+ parent->sc_dev.dv_xname);
+ goto err_exit2;
+ }
+
+ rv = acpi_eval_integer(handle, "_GLK", &tmp);
+ if (ACPI_SUCCESS(rv) && tmp == 1)
+ ecdt_sc->sc_glk = 1;
+
+ rv = AcpiInstallAddressSpaceHandler(handle,
+ ACPI_ADR_SPACE_EC, EcSpaceHandler, EcSpaceSetup, ecdt_sc);
+
+ if (ACPI_FAILURE(rv)) {
+ printf("%s: unable to install address space handler: %s\n",
+ parent->sc_dev.dv_xname,
+ AcpiFormatException(rv));
+ goto err_exit3;
}
+
+ 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->sc_dev.dv_xname,
+ AcpiFormatException(rv));
+ goto err_exit4;
+ }
+
+ printf("%s: using GPE %d for EC\n", parent->sc_dev.dv_xname,
+ ecdt_sc->sc_gpebit);
+ return;
+
+ err_exit4:
+ AcpiRemoveAddressSpaceHandler(ecdt_sc->sc_node->ad_handle,
+ ACPI_ADR_SPACE_EC, EcSpaceHandler);
+ err_exit3:
+ bus_space_unmap(ecdt_sc->sc_csr_st, ecdt_sc->sc_csr_sh, 1);
+ err_exit2:
+ bus_space_unmap(ecdt_sc->sc_data_st, ecdt_sc->sc_data_sh, 1);
+ err_exit1:
+ ecdt_sc->sc_node = NULL;
+ free(ecdt_node, M_ACPI);
+ free(ecdt_sc, M_ACPI);
+ ecdt_sc = NULL;
+
+ return;
}
-#endif
/*
* acpiec_attach:
@@ -405,6 +483,29 @@
printf(": ACPI Embedded Controller\n");
+#if 0
+ if (ecdt_sc) {
+ int uid;
+ rv = acpi_eval_integer(aa->aa_node->ad_handle, "_UID", &uid);
+
+ if (ecdt_sc->sc_uid == uid) {
+ (void)AcpiRemoveAddressSpaceHandler(
+ ecdt_sc->sc_node->ad_handle,
+ ACPI_ADR_SPACE_EC, EcSpaceHandler);
+ (void)AcpiRemoveGpeHandler(NULL, ecdt_sc->sc_gpebit,
+ EcGpeHandler);
+ 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);
+ ecdt_sc->sc_node = NULL;
+ free(ecdt_node, M_ACPI);
+ free(ecdt_sc, M_ACPI);
+ ecdt_sc = NULL;
+ }
+ }
+#endif
+
lockinit(&sc->sc_lock, PWAIT, "eclock", 0, 0);
simple_lock_init(&sc->sc_slock);
Index: acpivar.h
===================================================================
RCS file: /cvsroot/src/sys/dev/acpi/acpivar.h,v
retrieving revision 1.14
diff -u -r1.14 acpivar.h
--- acpivar.h 3 Nov 2003 06:03:47 -0000 1.14
+++ acpivar.h 21 Dec 2003 09:10:26 -0000
@@ -272,6 +272,8 @@
void *, const struct acpi_resource_parse_ops *);
void acpi_resource_print(struct device *, struct acpi_resources *);
+void acpiec_early_attach(struct acpi_softc *);
+
struct acpi_io *acpi_res_io(struct acpi_resources *, int);
struct acpi_iorange *acpi_res_iorange(struct acpi_resources *, int);
struct acpi_mem *acpi_res_mem(struct acpi_resources *, int);