summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornjl <njl@FreeBSD.org>2007-06-03 00:40:56 +0000
committernjl <njl@FreeBSD.org>2007-06-03 00:40:56 +0000
commit9116a352cf2b6e47064388733125ed74864a08a9 (patch)
treef81939e5fc00d06f5dc96830f602699549b315aa
parent2f5bd0a21fc832c4fe2007ac0aca5b79b93cd898 (diff)
downloadFreeBSD-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.c31
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.
*/
OpenPOWER on IntegriCloud