diff options
author | takawata <takawata@FreeBSD.org> | 2001-07-20 06:07:34 +0000 |
---|---|---|
committer | takawata <takawata@FreeBSD.org> | 2001-07-20 06:07:34 +0000 |
commit | d3d1b151d3f3f67385b5e5adbbafd20527daa156 (patch) | |
tree | fb4e3d6b249e14e537e8681949888f823fa67602 /sys/dev | |
parent | c3d97bef4d7f5c6ef78bbe34ac08731d7e2a9b0f (diff) | |
download | FreeBSD-src-d3d1b151d3f3f67385b5e5adbbafd20527daa156.zip FreeBSD-src-d3d1b151d3f3f67385b5e5adbbafd20527daa156.tar.gz |
Add ACPI S2-S4BIOS Suspend/Resume code.
Some problems may remain.
Reviewed by:iwasaki
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/acpica/acpi.c | 60 | ||||
-rw-r--r-- | sys/dev/acpica/acpivar.h | 11 |
2 files changed, 48 insertions, 23 deletions
diff --git a/sys/dev/acpica/acpi.c b/sys/dev/acpica/acpi.c index 7edb687..54426f4 100644 --- a/sys/dev/acpica/acpi.c +++ b/sys/dev/acpica/acpi.c @@ -262,6 +262,8 @@ acpi_attach(device_t dev) bzero(sc, sizeof(*sc)); sc->acpi_dev = dev; + acpi_install_wakeup_handler(sc); + #ifdef ENABLE_DEBUGGER if (debugpoint && !strcmp(debugpoint, "spaces")) acpi_EnterDebugger(); @@ -959,7 +961,6 @@ acpi_FindIndexedResource(ACPI_RESOURCE *resbuf, int index, ACPI_RESOURCE **resp) static ACPI_STATUS __inline acpi_wakeup(UINT8 state) { - UINT16 Count; ACPI_STATUS Status; ACPI_OBJECT_LIST Arg_list; ACPI_OBJECT Arg; @@ -968,21 +969,6 @@ acpi_wakeup(UINT8 state) FUNCTION_TRACE_U32(__func__, state); ACPI_ASSERTLOCK; - - /* wait for the WAK_STS bit */ - Count = 0; - while (!(AcpiHwRegisterBitAccess(ACPI_READ, ACPI_MTX_LOCK, WAK_STS))) { - AcpiOsSleepUsec(1000); - /* - * Some BIOSes don't set WAK_STS at all, - * give up waiting for wakeup if we time out. - */ - if (Count > 1000) { - printf("ACPI: timed out waiting for WAK_STS, continuing\n"); - break; /* giving up */ - } - Count++; - } /* * Evaluate the _WAK method @@ -1056,6 +1042,7 @@ ACPI_STATUS acpi_SetSleepState(struct acpi_softc *sc, int state) { ACPI_STATUS status = AE_OK; + UINT16 Count; FUNCTION_TRACE_U32(__func__, state); ACPI_ASSERTLOCK; @@ -1069,6 +1056,9 @@ acpi_SetSleepState(struct acpi_softc *sc, int state) break; case ACPI_STATE_S1: + case ACPI_STATE_S2: + case ACPI_STATE_S3: + case ACPI_STATE_S4: /* * Inform all devices that we are going to sleep. */ @@ -1084,10 +1074,37 @@ acpi_SetSleepState(struct acpi_softc *sc, int state) return_ACPI_STATUS(AE_ERROR); } sc->acpi_sstate = state; - status = AcpiEnterSleepState((UINT8)state); - if (status != AE_OK) { - device_printf(sc->acpi_dev, "AcpiEnterSleepState failed - %s\n", acpi_strerror(status)); - break; + + if (state != ACPI_STATE_S1) { + acpi_sleep_machdep(sc, state); + + /* AcpiEnterSleepState() maybe incompleted, unlock here. */ + AcpiUtReleaseMutex(ACPI_MTX_HARDWARE); + + /* Re-enable ACPI hardware on wakeup from sleep state 4. */ + if (state >= ACPI_STATE_S4) { + acpi_Disable(sc); + acpi_Enable(sc); + } + } else { + status = AcpiEnterSleepState((UINT8)state); + if (status != AE_OK) { + device_printf(sc->acpi_dev, "AcpiEnterSleepState failed - %s\n", acpi_strerror(status)); + break; + } + /* wait for the WAK_STS bit */ + Count = 0; + while (!(AcpiHwRegisterBitAccess(ACPI_READ, ACPI_MTX_LOCK, WAK_STS))) { + AcpiOsSleepUsec(1000); + /* + * Some BIOSes don't set WAK_STS at all, + * give up waiting for wakeup if we time out. + */ + if (Count > 1000) { + break; /* giving up */ + } + Count++; + } } acpi_wakeup((UINT8)state); DEVICE_RESUME(root_bus); @@ -1095,9 +1112,6 @@ acpi_SetSleepState(struct acpi_softc *sc, int state) acpi_enable_fixed_events(sc); break; - case ACPI_STATE_S3: - acpi_off_state = ACPI_STATE_S3; - /* FALLTHROUGH */ case ACPI_STATE_S5: /* * Shut down cleanly and power off. This will call us back through the diff --git a/sys/dev/acpica/acpivar.h b/sys/dev/acpica/acpivar.h index a8bc37b..5a6f737 100644 --- a/sys/dev/acpica/acpivar.h +++ b/sys/dev/acpica/acpivar.h @@ -32,6 +32,9 @@ #include <sys/eventhandler.h> #include <sys/sysctl.h> +#include <machine/bus.h> +#include <machine/resource.h> + extern devclass_t acpi_devclass; struct acpi_softc { @@ -54,6 +57,11 @@ struct acpi_softc { int acpi_sleep_button_sx; int acpi_lid_switch_sx; + bus_dma_tag_t acpi_waketag; + bus_dmamap_t acpi_wakemap; + vm_offset_t acpi_wakeaddr; + vm_offset_t acpi_wakephys; + struct sysctl_ctx_list acpi_battery_sysctl_ctx; struct sysctl_oid *acpi_battery_sysctl_tree; }; @@ -267,6 +275,9 @@ extern char *acpi_name(ACPI_HANDLE handle); extern int acpi_avoid(ACPI_HANDLE handle); extern int acpi_disabled(char *subsys); +extern void acpi_install_wakeup_handler(struct acpi_softc *sc); +extern int acpi_sleep_machdep(struct acpi_softc *sc, int state); + /* * Battery Abstruction. */ |