diff options
Diffstat (limited to 'sys/contrib/dev/acpica/hwsleep.c')
-rw-r--r-- | sys/contrib/dev/acpica/hwsleep.c | 86 |
1 files changed, 59 insertions, 27 deletions
diff --git a/sys/contrib/dev/acpica/hwsleep.c b/sys/contrib/dev/acpica/hwsleep.c index 7cbb6c8..8a18138 100644 --- a/sys/contrib/dev/acpica/hwsleep.c +++ b/sys/contrib/dev/acpica/hwsleep.c @@ -2,7 +2,7 @@ /****************************************************************************** * * Name: hwsleep.c - ACPI Hardware Sleep/Wake Interface - * $Revision: 22 $ + * $Revision: 25 $ * *****************************************************************************/ @@ -122,6 +122,9 @@ #define _COMPONENT ACPI_HARDWARE MODULE_NAME ("hwsleep") +static UINT8 SleepTypeA; +static UINT8 SleepTypeB; + /****************************************************************************** * @@ -214,41 +217,39 @@ AcpiGetFirmwareWakingVector ( return_ACPI_STATUS (AE_OK); } + /****************************************************************************** * - * FUNCTION: AcpiEnterSleepState + * FUNCTION: AcpiEnterSleepStatePrep * * PARAMETERS: SleepState - Which sleep state to enter * * RETURN: Status * - * DESCRIPTION: Enter a system sleep state (see ACPI 2.0 spec p 231) + * DESCRIPTION: Prepare to enter a system sleep state (see ACPI 2.0 spec p 231) + * This function must execute with interrupts enabled. + * We break sleeping into 2 stages so that OSPM can handle + * various OS-specific tasks between the two steps. * ******************************************************************************/ ACPI_STATUS -AcpiEnterSleepState ( +AcpiEnterSleepStatePrep ( UINT8 SleepState) { ACPI_STATUS Status; ACPI_OBJECT_LIST ArgList; ACPI_OBJECT Arg; - UINT8 TypeA; - UINT8 TypeB; - UINT16 PM1AControl; - UINT16 PM1BControl; - - - FUNCTION_TRACE ("AcpiEnterSleepState"); + FUNCTION_TRACE ("AcpiEnterSleepStatePrep"); /* * _PSW methods could be run here to enable wake-on keyboard, LAN, etc. */ - Status = AcpiHwObtainSleepTypeRegisterData (SleepState, &TypeA, &TypeB); + Status = AcpiHwObtainSleepTypeRegisterData (SleepState, &SleepTypeA, &SleepTypeB); if (!ACPI_SUCCESS (Status)) { - return Status; + return_ACPI_STATUS (Status); } /* run the _PTS and _GTS methods */ @@ -264,11 +265,49 @@ AcpiEnterSleepState ( AcpiEvaluateObject (NULL, "\\_PTS", &ArgList, NULL); AcpiEvaluateObject (NULL, "\\_GTS", &ArgList, NULL); + return_ACPI_STATUS (AE_OK); +} + + + +/****************************************************************************** + * + * FUNCTION: AcpiEnterSleepState + * + * PARAMETERS: SleepState - Which sleep state to enter + * + * RETURN: Status + * + * DESCRIPTION: Enter a system sleep state (see ACPI 2.0 spec p 231) + * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED + * + ******************************************************************************/ + +ACPI_STATUS +AcpiEnterSleepState ( + UINT8 SleepState) +{ + UINT16 PM1AControl; + UINT16 PM1BControl; + + + FUNCTION_TRACE ("AcpiEnterSleepState"); + + if ((SleepTypeA > ACPI_SLEEP_TYPE_MAX) || + (SleepTypeB > ACPI_SLEEP_TYPE_MAX)) + { + REPORT_ERROR (("Sleep values out of range: A=%x B=%x\n", + SleepTypeA, SleepTypeB)); + return_ACPI_STATUS (AE_ERROR); + } + /* clear wake status */ AcpiHwRegisterBitAccess (ACPI_WRITE, ACPI_MTX_LOCK, WAK_STS, 1); - disable (); + AcpiHwClearAcpiStatus(); + + /* disable arbitration here? */ AcpiHwDisableNonWakeupGpes(); @@ -283,8 +322,8 @@ AcpiEnterSleepState ( /* mask in SLP_TYP */ - PM1AControl |= (TypeA << AcpiHwGetBitShift (SLP_TYPE_X_MASK)); - PM1BControl |= (TypeB << AcpiHwGetBitShift (SLP_TYPE_X_MASK)); + PM1AControl |= (SleepTypeA << AcpiHwGetBitShift (SLP_TYPE_X_MASK)); + PM1BControl |= (SleepTypeB << AcpiHwGetBitShift (SLP_TYPE_X_MASK)); /* write #1: fill in SLP_TYP data */ @@ -296,10 +335,6 @@ AcpiEnterSleepState ( PM1AControl |= (1 << AcpiHwGetBitShift (SLP_EN_MASK)); PM1BControl |= (1 << AcpiHwGetBitShift (SLP_EN_MASK)); - /* flush caches */ - - wbinvd(); - /* write #2: SLP_TYP + SLP_EN */ AcpiHwRegisterWrite (ACPI_MTX_LOCK, PM1A_CONTROL, PM1AControl); @@ -318,15 +353,10 @@ AcpiEnterSleepState ( /* wait until we enter sleep state */ - do + while (!AcpiHwRegisterBitAccess (ACPI_READ, ACPI_MTX_LOCK, WAK_STS)) { - AcpiOsStall(10000); + /* spin until we wake */ } - while (!AcpiHwRegisterBitAccess (ACPI_READ, ACPI_MTX_LOCK, WAK_STS)); - - AcpiHwEnableNonWakeupGpes(); - - enable (); return_ACPI_STATUS (AE_OK); } @@ -353,6 +383,8 @@ AcpiLeaveSleepState ( FUNCTION_TRACE ("AcpiLeaveSleepState"); + /* Ensure EnterSleepStatePrep -> EnterSleepState ordering */ + SleepTypeA = ACPI_SLEEP_TYPE_INVALID; MEMSET (&ArgList, 0, sizeof(ArgList)); ArgList.Count = 1; |