ACPI: Early acpiec initialization diff

Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]
From: Jordan Hargrave
Date: Friday, July 23, 2010 - 1:00 pm

This patch will allow acpiec to initialize earlier if a ECDT table is
found.  This fixes a lockup if booting on some Thinkpads while docked.

You can tell if your system supports ECDT by scanning the ACPI tables
line in dmesg.  There should be a line like this:
acpi0: tables DSDT FACP SSDT ECDT TCPA APIC MCFG HPET SLIC BOOT ASF! SSDT SSDT SSDT SSDT

ECDT will be one of the entries if the early initialization is supported.

If scanning dmesg, acpiec0 will now also initialize earlier (near acpitimer
and acpimadt) instead of after acpiprt. 

Index: acpi.c
===================================================================
RCS file: /cvs/src/sys/dev/acpi/acpi.c,v
retrieving revision 1.187
diff -u -p -u -p -b -r1.187 acpi.c
--- acpi.c	22 Jul 2010 14:19:47 -0000	1.187
+++ acpi.c	23 Jul 2010 19:55:29 -0000
@@ -2123,6 +2123,10 @@ acpi_foundec(struct aml_node *node, void
 	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;
Index: acpiec.c
===================================================================
RCS file: /cvs/src/sys/dev/acpi/acpiec.c,v
retrieving revision 1.32
diff -u -p -u -p -b -r1.32 acpiec.c
--- acpiec.c	20 Jul 2010 12:15:24 -0000	1.32
+++ acpiec.c	23 Jul 2010 19:55:29 -0000
@@ -245,6 +245,11 @@ acpiec_match(struct device *parent, void
 {
 	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));
@@ -263,7 +268,6 @@ acpiec_attach(struct device *parent, str
 		printf(": Only single EC is supported\n");
 		return;
 	}
-	sc->sc_acpi->sc_ec = sc;
 
 	if (acpiec_getcrs(sc, aa)) {
 		printf(": Failed to read resource settings\n");
@@ -275,6 +279,7 @@ acpiec_attach(struct device *parent, str
 		return;
 	}
 
+	sc->sc_acpi->sc_ec = sc;
 	acpiec_get_events(sc);
 
 	dnprintf(10, "%s: GPE: %d\n", DEVNAME(sc), sc->sc_gpe);
@@ -384,6 +389,24 @@ acpiec_getcrs(struct acpiec_softc *sc, s
 	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;
+
+		type1 = ecdt->ec_control.address_space_id;
+		ec_sc = ecdt->ec_control.address;
+
+		type2 = 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));
@@ -409,7 +432,7 @@ acpiec_getcrs(struct acpiec_softc *sc, s
 	size = res.length;
 	buf = res.v_buffer;
 
-	ret = acpiec_getregister(buf, size, &type1, &ec_data);
+	ret = acpiec_getregister(buf, size, &type2, &ec_data);
 	if (ret <= 0) {
 		dnprintf(10, "%s: failed to read DATA from _CRS\n",
 		    DEVNAME(sc));
@@ -420,7 +443,7 @@ acpiec_getcrs(struct acpiec_softc *sc, s
 	buf += ret;
 	size -= ret;
 
-	ret = acpiec_getregister(buf, size, &type2,  &ec_sc);
+	ret = acpiec_getregister(buf, size, &type1,  &ec_sc);
 	if (ret <= 0) {
 		dnprintf(10, "%s: failed to read S/C from _CRS\n",
 		    DEVNAME(sc));
@@ -439,6 +462,7 @@ acpiec_getcrs(struct acpiec_softc *sc, s
 	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);
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]

Messages in current thread:
ACPI: Early acpiec initialization diff, Jordan Hargrave, (Fri Jul 23, 1:00 pm)