summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoravg <avg@FreeBSD.org>2013-02-02 12:42:07 +0000
committeravg <avg@FreeBSD.org>2013-02-02 12:42:07 +0000
commit1db4c39d41d9a95dcf5f9ce5a594c8887ccfc4d2 (patch)
treeaf46be011275ca1ea8930e19fd5d1e0326693d1e
parent2e2156704e3464a21d9828a2a25672095f24255d (diff)
downloadFreeBSD-src-1db4c39d41d9a95dcf5f9ce5a594c8887ccfc4d2.zip
FreeBSD-src-1db4c39d41d9a95dcf5f9ce5a594c8887ccfc4d2.tar.gz
acpi: after wakeup from a state > S1 re-enable SCI_EN with a direct write
This hack is picked up from Linux, which claims that it follows Windows behavior. PR: amd64/174409 Tested by: Sergey V. Dyatko <sergey.dyatko@gmail.com>, KAHO Toshikazu <kaho@elam.kais.kyoto-u.ac.jp>, Slawa Olhovchenkov <slw@zxy.spb.ru> MFC after: 13 days
-rw-r--r--sys/dev/acpica/acpi.c17
1 files changed, 15 insertions, 2 deletions
diff --git a/sys/dev/acpica/acpi.c b/sys/dev/acpica/acpi.c
index 086ea26..c380adf 100644
--- a/sys/dev/acpica/acpi.c
+++ b/sys/dev/acpica/acpi.c
@@ -278,7 +278,7 @@ TUNABLE_INT("debug.acpi.interpreter_slack", &acpi_interpreter_slack);
SYSCTL_INT(_debug_acpi, OID_AUTO, interpreter_slack, CTLFLAG_RDTUN,
&acpi_interpreter_slack, 1, "Turn on interpreter slack mode.");
-#ifdef __amd64__
+#if defined(__amd64__) || defined(__i386__)
/* Reset system clock while resuming. XXX Remove once tested. */
static int acpi_reset_clock = 1;
TUNABLE_INT("debug.acpi.reset_clock", &acpi_reset_clock);
@@ -2744,6 +2744,19 @@ acpi_EnterSleepState(struct acpi_softc *sc, int state)
if (state != ACPI_STATE_S1) {
sleep_result = acpi_sleep_machdep(sc, state);
acpi_wakeup_machdep(sc, state, sleep_result, 0);
+
+ /*
+ * XXX According to ACPI specification SCI_EN bit should be restored
+ * by ACPI platform (BIOS, firmware) to its pre-sleep state.
+ * Unfortunately some BIOSes fail to do that and that leads to
+ * unexpected and serious consequences during wake up like a system
+ * getting stuck in SMI handlers.
+ * This hack is picked up from Linux, which claims that it follows
+ * Windows behavior.
+ */
+ if (sleep_result == 1 && state != ACPI_STATE_S4)
+ AcpiWriteBitRegister(ACPI_BITREG_SCI_ENABLE, ACPI_ENABLE_EVENT);
+
AcpiLeaveSleepStatePrep(state);
intr_restore(intr);
@@ -2810,7 +2823,7 @@ backout:
static void
acpi_resync_clock(struct acpi_softc *sc)
{
-#ifdef __amd64__
+#if defined(__amd64__) || defined(__i386__)
if (!acpi_reset_clock)
return;
OpenPOWER on IntegriCloud