1231798Sjkim/****************************************************************************** 2231798Sjkim * 3231798Sjkim * Name: hwesleep.c - ACPI Hardware Sleep/Wake Support functions for the 4231798Sjkim * extended FADT-V5 sleep registers. 5231798Sjkim * 6231798Sjkim *****************************************************************************/ 7231798Sjkim 8231798Sjkim/* 9245582Sjkim * Copyright (C) 2000 - 2013, Intel Corp. 10231798Sjkim * All rights reserved. 11231798Sjkim * 12231798Sjkim * Redistribution and use in source and binary forms, with or without 13231798Sjkim * modification, are permitted provided that the following conditions 14231798Sjkim * are met: 15231798Sjkim * 1. Redistributions of source code must retain the above copyright 16231798Sjkim * notice, this list of conditions, and the following disclaimer, 17231798Sjkim * without modification. 18231798Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 19231798Sjkim * substantially similar to the "NO WARRANTY" disclaimer below 20231798Sjkim * ("Disclaimer") and any redistribution must be conditioned upon 21231798Sjkim * including a substantially similar Disclaimer requirement for further 22231798Sjkim * binary redistribution. 23231798Sjkim * 3. Neither the names of the above-listed copyright holders nor the names 24231798Sjkim * of any contributors may be used to endorse or promote products derived 25231798Sjkim * from this software without specific prior written permission. 26231798Sjkim * 27231798Sjkim * Alternatively, this software may be distributed under the terms of the 28231798Sjkim * GNU General Public License ("GPL") version 2 as published by the Free 29231798Sjkim * Software Foundation. 30231798Sjkim * 31231798Sjkim * NO WARRANTY 32231798Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 33231798Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 34231798Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 35231798Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 36231798Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 37231798Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 38231798Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 39231798Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 40231798Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 41231798Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 42231798Sjkim * POSSIBILITY OF SUCH DAMAGES. 43231798Sjkim */ 44231798Sjkim 45231844Sjkim#include <contrib/dev/acpica/include/acpi.h> 46231844Sjkim#include <contrib/dev/acpica/include/accommon.h> 47231798Sjkim 48231798Sjkim#define _COMPONENT ACPI_HARDWARE 49231798Sjkim ACPI_MODULE_NAME ("hwesleep") 50231798Sjkim 51231798Sjkim 52231798Sjkim/******************************************************************************* 53231798Sjkim * 54231798Sjkim * FUNCTION: AcpiHwExecuteSleepMethod 55231798Sjkim * 56233250Sjkim * PARAMETERS: MethodPathname - Pathname of method to execute 57231798Sjkim * IntegerArgument - Argument to pass to the method 58231798Sjkim * 59231798Sjkim * RETURN: None 60231798Sjkim * 61231798Sjkim * DESCRIPTION: Execute a sleep/wake related method with one integer argument 62231798Sjkim * and no return value. 63231798Sjkim * 64231798Sjkim ******************************************************************************/ 65231798Sjkim 66231798Sjkimvoid 67231798SjkimAcpiHwExecuteSleepMethod ( 68233250Sjkim char *MethodPathname, 69231798Sjkim UINT32 IntegerArgument) 70231798Sjkim{ 71231798Sjkim ACPI_OBJECT_LIST ArgList; 72231798Sjkim ACPI_OBJECT Arg; 73231798Sjkim ACPI_STATUS Status; 74231798Sjkim 75231798Sjkim 76231798Sjkim ACPI_FUNCTION_TRACE (HwExecuteSleepMethod); 77231798Sjkim 78231798Sjkim 79231798Sjkim /* One argument, IntegerArgument; No return value expected */ 80231798Sjkim 81231798Sjkim ArgList.Count = 1; 82231798Sjkim ArgList.Pointer = &Arg; 83231798Sjkim Arg.Type = ACPI_TYPE_INTEGER; 84231798Sjkim Arg.Integer.Value = (UINT64) IntegerArgument; 85231798Sjkim 86233250Sjkim Status = AcpiEvaluateObject (NULL, MethodPathname, &ArgList, NULL); 87231798Sjkim if (ACPI_FAILURE (Status) && Status != AE_NOT_FOUND) 88231798Sjkim { 89231798Sjkim ACPI_EXCEPTION ((AE_INFO, Status, "While executing method %s", 90233250Sjkim MethodPathname)); 91231798Sjkim } 92231798Sjkim 93231798Sjkim return_VOID; 94231798Sjkim} 95231798Sjkim 96231798Sjkim 97231798Sjkim/******************************************************************************* 98231798Sjkim * 99231798Sjkim * FUNCTION: AcpiHwExtendedSleep 100231798Sjkim * 101231798Sjkim * PARAMETERS: SleepState - Which sleep state to enter 102231798Sjkim * 103231798Sjkim * RETURN: Status 104231798Sjkim * 105231798Sjkim * DESCRIPTION: Enter a system sleep state via the extended FADT sleep 106231798Sjkim * registers (V5 FADT). 107231798Sjkim * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED 108231798Sjkim * 109231798Sjkim ******************************************************************************/ 110231798Sjkim 111231798SjkimACPI_STATUS 112231798SjkimAcpiHwExtendedSleep ( 113239340Sjkim UINT8 SleepState) 114231798Sjkim{ 115231798Sjkim ACPI_STATUS Status; 116231798Sjkim UINT8 SleepTypeValue; 117231798Sjkim UINT64 SleepStatus; 118231798Sjkim 119231798Sjkim 120231798Sjkim ACPI_FUNCTION_TRACE (HwExtendedSleep); 121231798Sjkim 122231798Sjkim 123231798Sjkim /* Extended sleep registers must be valid */ 124231798Sjkim 125231798Sjkim if (!AcpiGbl_FADT.SleepControl.Address || 126231798Sjkim !AcpiGbl_FADT.SleepStatus.Address) 127231798Sjkim { 128231798Sjkim return_ACPI_STATUS (AE_NOT_EXIST); 129231798Sjkim } 130231798Sjkim 131231798Sjkim /* Clear wake status (WAK_STS) */ 132231798Sjkim 133234623Sjkim Status = AcpiWrite ((UINT64) ACPI_X_WAKE_STATUS, &AcpiGbl_FADT.SleepStatus); 134231798Sjkim if (ACPI_FAILURE (Status)) 135231798Sjkim { 136231798Sjkim return_ACPI_STATUS (Status); 137231798Sjkim } 138231798Sjkim 139231798Sjkim AcpiGbl_SystemAwakeAndRunning = FALSE; 140231798Sjkim 141231798Sjkim /* Flush caches, as per ACPI specification */ 142231798Sjkim 143231798Sjkim ACPI_FLUSH_CPU_CACHE (); 144231798Sjkim 145231798Sjkim /* 146231798Sjkim * Set the SLP_TYP and SLP_EN bits. 147231798Sjkim * 148231798Sjkim * Note: We only use the first value returned by the \_Sx method 149231798Sjkim * (AcpiGbl_SleepTypeA) - As per ACPI specification. 150231798Sjkim */ 151231798Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_INIT, 152231798Sjkim "Entering sleep state [S%u]\n", SleepState)); 153231798Sjkim 154231798Sjkim SleepTypeValue = ((AcpiGbl_SleepTypeA << ACPI_X_SLEEP_TYPE_POSITION) & 155231798Sjkim ACPI_X_SLEEP_TYPE_MASK); 156231798Sjkim 157234623Sjkim Status = AcpiWrite ((UINT64) (SleepTypeValue | ACPI_X_SLEEP_ENABLE), 158231798Sjkim &AcpiGbl_FADT.SleepControl); 159231798Sjkim if (ACPI_FAILURE (Status)) 160231798Sjkim { 161231798Sjkim return_ACPI_STATUS (Status); 162231798Sjkim } 163231798Sjkim 164231798Sjkim /* Wait for transition back to Working State */ 165231798Sjkim 166231798Sjkim do 167231798Sjkim { 168231798Sjkim Status = AcpiRead (&SleepStatus, &AcpiGbl_FADT.SleepStatus); 169231798Sjkim if (ACPI_FAILURE (Status)) 170231798Sjkim { 171231798Sjkim return_ACPI_STATUS (Status); 172231798Sjkim } 173231798Sjkim 174231798Sjkim } while (!(((UINT8) SleepStatus) & ACPI_X_WAKE_STATUS)); 175231798Sjkim 176231798Sjkim return_ACPI_STATUS (AE_OK); 177231798Sjkim} 178231798Sjkim 179231798Sjkim 180231798Sjkim/******************************************************************************* 181231798Sjkim * 182231798Sjkim * FUNCTION: AcpiHwExtendedWakePrep 183231798Sjkim * 184231798Sjkim * PARAMETERS: SleepState - Which sleep state we just exited 185231798Sjkim * 186231798Sjkim * RETURN: Status 187231798Sjkim * 188231798Sjkim * DESCRIPTION: Perform first part of OS-independent ACPI cleanup after 189231798Sjkim * a sleep. Called with interrupts ENABLED. 190231798Sjkim * 191231798Sjkim ******************************************************************************/ 192231798Sjkim 193231798SjkimACPI_STATUS 194231798SjkimAcpiHwExtendedWakePrep ( 195239340Sjkim UINT8 SleepState) 196231798Sjkim{ 197231798Sjkim ACPI_STATUS Status; 198231798Sjkim UINT8 SleepTypeValue; 199231798Sjkim 200231798Sjkim 201231798Sjkim ACPI_FUNCTION_TRACE (HwExtendedWakePrep); 202231798Sjkim 203231798Sjkim 204231798Sjkim Status = AcpiGetSleepTypeData (ACPI_STATE_S0, 205231798Sjkim &AcpiGbl_SleepTypeA, &AcpiGbl_SleepTypeB); 206231798Sjkim if (ACPI_SUCCESS (Status)) 207231798Sjkim { 208231798Sjkim SleepTypeValue = ((AcpiGbl_SleepTypeA << ACPI_X_SLEEP_TYPE_POSITION) & 209231798Sjkim ACPI_X_SLEEP_TYPE_MASK); 210231798Sjkim 211234623Sjkim (void) AcpiWrite ((UINT64) (SleepTypeValue | ACPI_X_SLEEP_ENABLE), 212231798Sjkim &AcpiGbl_FADT.SleepControl); 213231798Sjkim } 214231798Sjkim 215231798Sjkim return_ACPI_STATUS (AE_OK); 216231798Sjkim} 217231798Sjkim 218231798Sjkim 219231798Sjkim/******************************************************************************* 220231798Sjkim * 221231798Sjkim * FUNCTION: AcpiHwExtendedWake 222231798Sjkim * 223231798Sjkim * PARAMETERS: SleepState - Which sleep state we just exited 224231798Sjkim * 225231798Sjkim * RETURN: Status 226231798Sjkim * 227231798Sjkim * DESCRIPTION: Perform OS-independent ACPI cleanup after a sleep 228231798Sjkim * Called with interrupts ENABLED. 229231798Sjkim * 230231798Sjkim ******************************************************************************/ 231231798Sjkim 232231798SjkimACPI_STATUS 233231798SjkimAcpiHwExtendedWake ( 234239340Sjkim UINT8 SleepState) 235231798Sjkim{ 236231798Sjkim ACPI_FUNCTION_TRACE (HwExtendedWake); 237231798Sjkim 238231798Sjkim 239231798Sjkim /* Ensure EnterSleepStatePrep -> EnterSleepState ordering */ 240231798Sjkim 241231798Sjkim AcpiGbl_SleepTypeA = ACPI_SLEEP_TYPE_INVALID; 242231798Sjkim 243231798Sjkim /* Execute the wake methods */ 244231798Sjkim 245233250Sjkim AcpiHwExecuteSleepMethod (METHOD_PATHNAME__SST, ACPI_SST_WAKING); 246233250Sjkim AcpiHwExecuteSleepMethod (METHOD_PATHNAME__WAK, SleepState); 247231798Sjkim 248231798Sjkim /* 249231798Sjkim * Some BIOS code assumes that WAK_STS will be cleared on resume 250231798Sjkim * and use it to determine whether the system is rebooting or 251231798Sjkim * resuming. Clear WAK_STS for compatibility. 252231798Sjkim */ 253234623Sjkim (void) AcpiWrite ((UINT64) ACPI_X_WAKE_STATUS, &AcpiGbl_FADT.SleepStatus); 254231798Sjkim AcpiGbl_SystemAwakeAndRunning = TRUE; 255231798Sjkim 256233250Sjkim AcpiHwExecuteSleepMethod (METHOD_PATHNAME__SST, ACPI_SST_WORKING); 257231798Sjkim return_ACPI_STATUS (AE_OK); 258231798Sjkim} 259