diff options
author | Jordan Hargrave <jordan@cvs.openbsd.org> | 2010-07-27 05:17:37 +0000 |
---|---|---|
committer | Jordan Hargrave <jordan@cvs.openbsd.org> | 2010-07-27 05:17:37 +0000 |
commit | 4c50f7d542c4500a9e813cab1b6ad000e08f1eae (patch) | |
tree | 70297f6cb70ed532d8774175dd919c8baa9e4cdd | |
parent | cb13e3a366f7b8d6d41ebc02956fab5846ba7c16 (diff) |
Early initialization of acpiec if ECDT table exists
Fixes hang when booting thinkpads while docked
ok deraadt
-rw-r--r-- | sys/dev/acpi/acpi.c | 6 | ||||
-rw-r--r-- | sys/dev/acpi/acpiec.c | 27 |
2 files changed, 31 insertions, 2 deletions
diff --git a/sys/dev/acpi/acpi.c b/sys/dev/acpi/acpi.c index 95bd0bf7586..bdad3679554 100644 --- a/sys/dev/acpi/acpi.c +++ b/sys/dev/acpi/acpi.c @@ -1,4 +1,4 @@ -/* $OpenBSD: acpi.c,v 1.189 2010/07/26 17:25:44 deraadt Exp $ */ +/* $OpenBSD: acpi.c,v 1.190 2010/07/27 05:17:36 jordan Exp $ */ /* * Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com> * Copyright (c) 2005 Jordan Hargrave <jordan@openbsd.org> @@ -2127,6 +2127,10 @@ acpi_foundec(struct aml_node *node, void *arg) if (strcmp(dev, ACPI_DEV_ECD)) return 0; + /* Check if we're already attached */ + if (sc->sc_ec && sc->sc_ec->sc_devnode == node->parent) + return 0; + memset(&aaa, 0, sizeof(aaa)); aaa.aaa_iot = sc->sc_iot; aaa.aaa_memt = sc->sc_memt; diff --git a/sys/dev/acpi/acpiec.c b/sys/dev/acpi/acpiec.c index abe76b6e466..34679479d2d 100644 --- a/sys/dev/acpi/acpiec.c +++ b/sys/dev/acpi/acpiec.c @@ -1,4 +1,4 @@ -/* $OpenBSD: acpiec.c,v 1.34 2010/07/23 20:21:58 jordan Exp $ */ +/* $OpenBSD: acpiec.c,v 1.35 2010/07/27 05:17:36 jordan Exp $ */ /* * Copyright (c) 2006 Can Erkin Acar <canacar@openbsd.org> * @@ -245,6 +245,11 @@ acpiec_match(struct device *parent, void *match, void *aux) { struct acpi_attach_args *aa = aux; struct cfdata *cf = match; + struct acpi_ecdt *ecdt = aa->aaa_table; + + /* Check for early ECDT table attach */ + if (ecdt && !memcmp(ecdt->hdr.signature, ECDT_SIG, sizeof(ECDT_SIG) - 1)) + return (1); /* sanity */ return (acpi_matchhids(aa, acpiec_hids, cf->cf_driver->cd_name)); @@ -384,6 +389,25 @@ acpiec_getcrs(struct acpiec_softc *sc, struct acpi_attach_args *aa) char *buf; int size, ret; int64_t gpe; + struct acpi_ecdt *ecdt = aa->aaa_table; + extern struct aml_node aml_root; + + /* Check if this is ECDT initialization */ + if (ecdt) { + /* Get GPE, Data and Control segments */ + sc->sc_gpe = ecdt->gpe_bit; + + ctype = ecdt->ec_control.address_space_id; + ec_sc = ecdt->ec_control.address; + + dtype = ecdt->ec_data.address_space_id; + ec_data = ecdt->ec_data.address; + + /* Get devnode from header */ + sc->sc_devnode = aml_searchname(&aml_root, ecdt->ec_id); + + goto ecdtdone; + } if (aml_evalinteger(sc->sc_acpi, sc->sc_devnode, "_GPE", 0, NULL, &gpe)) { dnprintf(10, "%s: no _GPE\n", DEVNAME(sc)); @@ -439,6 +463,7 @@ acpiec_getcrs(struct acpiec_softc *sc, struct acpi_attach_args *aa) aml_freevalue(&res); /* XXX: todo - validate _CRS checksum? */ +ecdtdone: dnprintf(10, "%s: Data: 0x%x, S/C: 0x%x\n", DEVNAME(sc), ec_data, ec_sc); |