summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJordan Hargrave <jordan@cvs.openbsd.org>2010-07-27 05:17:37 +0000
committerJordan Hargrave <jordan@cvs.openbsd.org>2010-07-27 05:17:37 +0000
commit4c50f7d542c4500a9e813cab1b6ad000e08f1eae (patch)
tree70297f6cb70ed532d8774175dd919c8baa9e4cdd
parentcb13e3a366f7b8d6d41ebc02956fab5846ba7c16 (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.c6
-rw-r--r--sys/dev/acpi/acpiec.c27
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);