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