diff options
author | jkim <jkim@FreeBSD.org> | 2010-11-12 17:10:12 +0000 |
---|---|---|
committer | jkim <jkim@FreeBSD.org> | 2010-11-12 17:10:12 +0000 |
commit | 3a6dc60694c21fc86d69acee733dc631b64447dc (patch) | |
tree | 6ab8b768bcd88129eac89b3e9b1420ac2d410551 /sys/dev/acpica | |
parent | e871048a21da1caace46ec1a84983294506ae9c9 (diff) | |
download | FreeBSD-src-3a6dc60694c21fc86d69acee733dc631b64447dc.zip FreeBSD-src-3a6dc60694c21fc86d69acee733dc631b64447dc.tar.gz |
Create C1 state when _CST is valid but _CST does not have one. Some BIOSes
do not report C1 state in _CST object, probably because it is a mandatory
state with or without existence of the optional _CST.
Reviewed by: avg
Diffstat (limited to 'sys/dev/acpica')
-rw-r--r-- | sys/dev/acpica/acpi_cpu.c | 30 |
1 files changed, 26 insertions, 4 deletions
diff --git a/sys/dev/acpica/acpi_cpu.c b/sys/dev/acpica/acpi_cpu.c index 52934af..eb34753 100644 --- a/sys/dev/acpica/acpi_cpu.c +++ b/sys/dev/acpica/acpi_cpu.c @@ -668,9 +668,19 @@ acpi_cpu_cx_cst(struct acpi_cpu_softc *sc) count = MAX_CX_STATES; } - /* Set up all valid states. */ + sc->cpu_non_c3 = 0; sc->cpu_cx_count = 0; cx_ptr = sc->cpu_cx_states; + + /* + * C1 has been required since just after ACPI 1.0. + * Reserve the first slot for it. + */ + cx_ptr->type = ACPI_STATE_C0; + cx_ptr++; + sc->cpu_cx_count++; + + /* Set up all valid states. */ for (i = 0; i < count; i++) { pkg = &top->Package.Elements[i + 1]; if (!ACPI_PKG_VALID(pkg, 4) || @@ -685,9 +695,14 @@ acpi_cpu_cx_cst(struct acpi_cpu_softc *sc) /* Validate the state to see if we should use it. */ switch (cx_ptr->type) { case ACPI_STATE_C1: - sc->cpu_non_c3 = i; - cx_ptr++; - sc->cpu_cx_count++; + if (sc->cpu_cx_states[0].type == ACPI_STATE_C0) { + /* This is the first C1 state. Use the reserved slot. */ + sc->cpu_cx_states[0] = *cx_ptr; + } else { + sc->cpu_non_c3 = i; + cx_ptr++; + sc->cpu_cx_count++; + } continue; case ACPI_STATE_C2: sc->cpu_non_c3 = i; @@ -726,6 +741,13 @@ acpi_cpu_cx_cst(struct acpi_cpu_softc *sc) } AcpiOsFree(buf.Pointer); + /* If C1 state was not found, we need one now. */ + cx_ptr = sc->cpu_cx_states; + if (cx_ptr->type == ACPI_STATE_C0) { + cx_ptr->type = ACPI_STATE_C1; + cx_ptr->trans_lat = 0; + } + return (0); } |