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 #include #include +#include #include #include @@ -187,6 +188,8 @@ #include #include +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);