summaryrefslogtreecommitdiffstats
path: root/sys/dev/acpica
diff options
context:
space:
mode:
authorjkim <jkim@FreeBSD.org>2010-11-12 17:10:12 +0000
committerjkim <jkim@FreeBSD.org>2010-11-12 17:10:12 +0000
commit3a6dc60694c21fc86d69acee733dc631b64447dc (patch)
tree6ab8b768bcd88129eac89b3e9b1420ac2d410551 /sys/dev/acpica
parente871048a21da1caace46ec1a84983294506ae9c9 (diff)
downloadFreeBSD-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.c30
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);
}
OpenPOWER on IntegriCloud