diff options
author | njl <njl@FreeBSD.org> | 2007-06-03 00:40:56 +0000 |
---|---|---|
committer | njl <njl@FreeBSD.org> | 2007-06-03 00:40:56 +0000 |
commit | 9116a352cf2b6e47064388733125ed74864a08a9 (patch) | |
tree | f81939e5fc00d06f5dc96830f602699549b315aa | |
parent | 2f5bd0a21fc832c4fe2007ac0aca5b79b93cd898 (diff) | |
download | FreeBSD-src-9116a352cf2b6e47064388733125ed74864a08a9.zip FreeBSD-src-9116a352cf2b6e47064388733125ed74864a08a9.tar.gz |
Disable CPU idle states during suspend and reenable them during resume.
While in the suspend path, this means the idle thread will just return
immediately rather than trying to enter C1-n. This helps in the case where
the chipset is powered down before the rest of the system and reads from
the cpu sleep registers begin returning immediately, causing the logic that
catches bad C2/C3 behavior to kick in. Observed on my Panasonic Y4.
MFC after: 3 days
-rw-r--r-- | sys/dev/acpica/acpi_cpu.c | 31 |
1 files changed, 29 insertions, 2 deletions
diff --git a/sys/dev/acpica/acpi_cpu.c b/sys/dev/acpica/acpi_cpu.c index a3a4a98..b9a89d3 100644 --- a/sys/dev/acpica/acpi_cpu.c +++ b/sys/dev/acpica/acpi_cpu.c @@ -136,6 +136,8 @@ ACPI_SERIAL_DECL(cpu, "ACPI CPU"); static int acpi_cpu_probe(device_t dev); static int acpi_cpu_attach(device_t dev); +static int acpi_cpu_suspend(device_t dev); +static int acpi_cpu_resume(device_t dev); static int acpi_pcpu_get_id(uint32_t idx, uint32_t *acpi_id, uint32_t *cpu_id); static struct resource_list *acpi_cpu_get_rlist(device_t dev, device_t child); @@ -153,6 +155,7 @@ static void acpi_cpu_idle(void); static void acpi_cpu_notify(ACPI_HANDLE h, UINT32 notify, void *context); static int acpi_cpu_quirks(void); static int acpi_cpu_usage_sysctl(SYSCTL_HANDLER_ARGS); +static int acpi_cpu_set_cx_lowest(struct acpi_cpu_softc *sc, int val); static int acpi_cpu_cx_lowest_sysctl(SYSCTL_HANDLER_ARGS); static int acpi_cpu_global_cx_lowest_sysctl(SYSCTL_HANDLER_ARGS); @@ -162,8 +165,8 @@ static device_method_t acpi_cpu_methods[] = { DEVMETHOD(device_attach, acpi_cpu_attach), DEVMETHOD(device_detach, bus_generic_detach), DEVMETHOD(device_shutdown, acpi_cpu_shutdown), - DEVMETHOD(device_suspend, bus_generic_suspend), - DEVMETHOD(device_resume, bus_generic_resume), + DEVMETHOD(device_suspend, acpi_cpu_suspend), + DEVMETHOD(device_resume, acpi_cpu_resume), /* Bus interface */ DEVMETHOD(bus_add_child, acpi_cpu_add_child), @@ -357,6 +360,30 @@ acpi_cpu_attach(device_t dev) } /* + * Disable any entry to the idle function during suspend and re-enable it + * during resume. + */ +static int +acpi_cpu_suspend(device_t dev) +{ + int error; + + error = bus_generic_suspend(dev); + if (error) + return (error); + cpu_disable_idle = TRUE; + return (0); +} + +static int +acpi_cpu_resume(device_t dev) +{ + + cpu_disable_idle = FALSE; + return (bus_generic_resume(dev)); +} + +/* * Find the nth present CPU and return its pc_cpuid as well as set the * pc_acpi_id from the most reliable source. */ |