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);
