1*385cc6b4SJerry Jelinek /******************************************************************************
2*385cc6b4SJerry Jelinek *
3*385cc6b4SJerry Jelinek * Name: hwesleep.c - ACPI Hardware Sleep/Wake Support functions for the
4*385cc6b4SJerry Jelinek * extended FADT-V5 sleep registers.
5*385cc6b4SJerry Jelinek *
6*385cc6b4SJerry Jelinek *****************************************************************************/
7*385cc6b4SJerry Jelinek
8*385cc6b4SJerry Jelinek /*
9*385cc6b4SJerry Jelinek * Copyright (C) 2000 - 2016, Intel Corp.
10*385cc6b4SJerry Jelinek * All rights reserved.
11*385cc6b4SJerry Jelinek *
12*385cc6b4SJerry Jelinek * Redistribution and use in source and binary forms, with or without
13*385cc6b4SJerry Jelinek * modification, are permitted provided that the following conditions
14*385cc6b4SJerry Jelinek * are met:
15*385cc6b4SJerry Jelinek * 1. Redistributions of source code must retain the above copyright
16*385cc6b4SJerry Jelinek * notice, this list of conditions, and the following disclaimer,
17*385cc6b4SJerry Jelinek * without modification.
18*385cc6b4SJerry Jelinek * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19*385cc6b4SJerry Jelinek * substantially similar to the "NO WARRANTY" disclaimer below
20*385cc6b4SJerry Jelinek * ("Disclaimer") and any redistribution must be conditioned upon
21*385cc6b4SJerry Jelinek * including a substantially similar Disclaimer requirement for further
22*385cc6b4SJerry Jelinek * binary redistribution.
23*385cc6b4SJerry Jelinek * 3. Neither the names of the above-listed copyright holders nor the names
24*385cc6b4SJerry Jelinek * of any contributors may be used to endorse or promote products derived
25*385cc6b4SJerry Jelinek * from this software without specific prior written permission.
26*385cc6b4SJerry Jelinek *
27*385cc6b4SJerry Jelinek * Alternatively, this software may be distributed under the terms of the
28*385cc6b4SJerry Jelinek * GNU General Public License ("GPL") version 2 as published by the Free
29*385cc6b4SJerry Jelinek * Software Foundation.
30*385cc6b4SJerry Jelinek *
31*385cc6b4SJerry Jelinek * NO WARRANTY
32*385cc6b4SJerry Jelinek * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33*385cc6b4SJerry Jelinek * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34*385cc6b4SJerry Jelinek * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35*385cc6b4SJerry Jelinek * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36*385cc6b4SJerry Jelinek * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37*385cc6b4SJerry Jelinek * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38*385cc6b4SJerry Jelinek * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39*385cc6b4SJerry Jelinek * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40*385cc6b4SJerry Jelinek * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41*385cc6b4SJerry Jelinek * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42*385cc6b4SJerry Jelinek * POSSIBILITY OF SUCH DAMAGES.
43*385cc6b4SJerry Jelinek */
44*385cc6b4SJerry Jelinek
45*385cc6b4SJerry Jelinek #include "acpi.h"
46*385cc6b4SJerry Jelinek #include "accommon.h"
47*385cc6b4SJerry Jelinek
48*385cc6b4SJerry Jelinek #define _COMPONENT ACPI_HARDWARE
49*385cc6b4SJerry Jelinek ACPI_MODULE_NAME ("hwesleep")
50*385cc6b4SJerry Jelinek
51*385cc6b4SJerry Jelinek
52*385cc6b4SJerry Jelinek /*******************************************************************************
53*385cc6b4SJerry Jelinek *
54*385cc6b4SJerry Jelinek * FUNCTION: AcpiHwExecuteSleepMethod
55*385cc6b4SJerry Jelinek *
56*385cc6b4SJerry Jelinek * PARAMETERS: MethodPathname - Pathname of method to execute
57*385cc6b4SJerry Jelinek * IntegerArgument - Argument to pass to the method
58*385cc6b4SJerry Jelinek *
59*385cc6b4SJerry Jelinek * RETURN: None
60*385cc6b4SJerry Jelinek *
61*385cc6b4SJerry Jelinek * DESCRIPTION: Execute a sleep/wake related method with one integer argument
62*385cc6b4SJerry Jelinek * and no return value.
63*385cc6b4SJerry Jelinek *
64*385cc6b4SJerry Jelinek ******************************************************************************/
65*385cc6b4SJerry Jelinek
66*385cc6b4SJerry Jelinek void
AcpiHwExecuteSleepMethod(char * MethodPathname,UINT32 IntegerArgument)67*385cc6b4SJerry Jelinek AcpiHwExecuteSleepMethod (
68*385cc6b4SJerry Jelinek char *MethodPathname,
69*385cc6b4SJerry Jelinek UINT32 IntegerArgument)
70*385cc6b4SJerry Jelinek {
71*385cc6b4SJerry Jelinek ACPI_OBJECT_LIST ArgList;
72*385cc6b4SJerry Jelinek ACPI_OBJECT Arg;
73*385cc6b4SJerry Jelinek ACPI_STATUS Status;
74*385cc6b4SJerry Jelinek
75*385cc6b4SJerry Jelinek
76*385cc6b4SJerry Jelinek ACPI_FUNCTION_TRACE (HwExecuteSleepMethod);
77*385cc6b4SJerry Jelinek
78*385cc6b4SJerry Jelinek
79*385cc6b4SJerry Jelinek /* One argument, IntegerArgument; No return value expected */
80*385cc6b4SJerry Jelinek
81*385cc6b4SJerry Jelinek ArgList.Count = 1;
82*385cc6b4SJerry Jelinek ArgList.Pointer = &Arg;
83*385cc6b4SJerry Jelinek Arg.Type = ACPI_TYPE_INTEGER;
84*385cc6b4SJerry Jelinek Arg.Integer.Value = (UINT64) IntegerArgument;
85*385cc6b4SJerry Jelinek
86*385cc6b4SJerry Jelinek Status = AcpiEvaluateObject (NULL, MethodPathname, &ArgList, NULL);
87*385cc6b4SJerry Jelinek if (ACPI_FAILURE (Status) && Status != AE_NOT_FOUND)
88*385cc6b4SJerry Jelinek {
89*385cc6b4SJerry Jelinek ACPI_EXCEPTION ((AE_INFO, Status, "While executing method %s",
90*385cc6b4SJerry Jelinek MethodPathname));
91*385cc6b4SJerry Jelinek }
92*385cc6b4SJerry Jelinek
93*385cc6b4SJerry Jelinek return_VOID;
94*385cc6b4SJerry Jelinek }
95*385cc6b4SJerry Jelinek
96*385cc6b4SJerry Jelinek
97*385cc6b4SJerry Jelinek /*******************************************************************************
98*385cc6b4SJerry Jelinek *
99*385cc6b4SJerry Jelinek * FUNCTION: AcpiHwExtendedSleep
100*385cc6b4SJerry Jelinek *
101*385cc6b4SJerry Jelinek * PARAMETERS: SleepState - Which sleep state to enter
102*385cc6b4SJerry Jelinek *
103*385cc6b4SJerry Jelinek * RETURN: Status
104*385cc6b4SJerry Jelinek *
105*385cc6b4SJerry Jelinek * DESCRIPTION: Enter a system sleep state via the extended FADT sleep
106*385cc6b4SJerry Jelinek * registers (V5 FADT).
107*385cc6b4SJerry Jelinek * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED
108*385cc6b4SJerry Jelinek *
109*385cc6b4SJerry Jelinek ******************************************************************************/
110*385cc6b4SJerry Jelinek
111*385cc6b4SJerry Jelinek ACPI_STATUS
AcpiHwExtendedSleep(UINT8 SleepState)112*385cc6b4SJerry Jelinek AcpiHwExtendedSleep (
113*385cc6b4SJerry Jelinek UINT8 SleepState)
114*385cc6b4SJerry Jelinek {
115*385cc6b4SJerry Jelinek ACPI_STATUS Status;
116*385cc6b4SJerry Jelinek UINT8 SleepTypeValue;
117*385cc6b4SJerry Jelinek UINT64 SleepStatus;
118*385cc6b4SJerry Jelinek
119*385cc6b4SJerry Jelinek
120*385cc6b4SJerry Jelinek ACPI_FUNCTION_TRACE (HwExtendedSleep);
121*385cc6b4SJerry Jelinek
122*385cc6b4SJerry Jelinek
123*385cc6b4SJerry Jelinek /* Extended sleep registers must be valid */
124*385cc6b4SJerry Jelinek
125*385cc6b4SJerry Jelinek if (!AcpiGbl_FADT.SleepControl.Address ||
126*385cc6b4SJerry Jelinek !AcpiGbl_FADT.SleepStatus.Address)
127*385cc6b4SJerry Jelinek {
128*385cc6b4SJerry Jelinek return_ACPI_STATUS (AE_NOT_EXIST);
129*385cc6b4SJerry Jelinek }
130*385cc6b4SJerry Jelinek
131*385cc6b4SJerry Jelinek /* Clear wake status (WAK_STS) */
132*385cc6b4SJerry Jelinek
133*385cc6b4SJerry Jelinek Status = AcpiWrite ((UINT64) ACPI_X_WAKE_STATUS,
134*385cc6b4SJerry Jelinek &AcpiGbl_FADT.SleepStatus);
135*385cc6b4SJerry Jelinek if (ACPI_FAILURE (Status))
136*385cc6b4SJerry Jelinek {
137*385cc6b4SJerry Jelinek return_ACPI_STATUS (Status);
138*385cc6b4SJerry Jelinek }
139*385cc6b4SJerry Jelinek
140*385cc6b4SJerry Jelinek AcpiGbl_SystemAwakeAndRunning = FALSE;
141*385cc6b4SJerry Jelinek
142*385cc6b4SJerry Jelinek /* Flush caches, as per ACPI specification */
143*385cc6b4SJerry Jelinek
144*385cc6b4SJerry Jelinek ACPI_FLUSH_CPU_CACHE ();
145*385cc6b4SJerry Jelinek
146*385cc6b4SJerry Jelinek /*
147*385cc6b4SJerry Jelinek * Set the SLP_TYP and SLP_EN bits.
148*385cc6b4SJerry Jelinek *
149*385cc6b4SJerry Jelinek * Note: We only use the first value returned by the \_Sx method
150*385cc6b4SJerry Jelinek * (AcpiGbl_SleepTypeA) - As per ACPI specification.
151*385cc6b4SJerry Jelinek */
152*385cc6b4SJerry Jelinek ACPI_DEBUG_PRINT ((ACPI_DB_INIT,
153*385cc6b4SJerry Jelinek "Entering sleep state [S%u]\n", SleepState));
154*385cc6b4SJerry Jelinek
155*385cc6b4SJerry Jelinek SleepTypeValue = ((AcpiGbl_SleepTypeA << ACPI_X_SLEEP_TYPE_POSITION) &
156*385cc6b4SJerry Jelinek ACPI_X_SLEEP_TYPE_MASK);
157*385cc6b4SJerry Jelinek
158*385cc6b4SJerry Jelinek Status = AcpiWrite ((UINT64) (SleepTypeValue | ACPI_X_SLEEP_ENABLE),
159*385cc6b4SJerry Jelinek &AcpiGbl_FADT.SleepControl);
160*385cc6b4SJerry Jelinek if (ACPI_FAILURE (Status))
161*385cc6b4SJerry Jelinek {
162*385cc6b4SJerry Jelinek return_ACPI_STATUS (Status);
163*385cc6b4SJerry Jelinek }
164*385cc6b4SJerry Jelinek
165*385cc6b4SJerry Jelinek /* Wait for transition back to Working State */
166*385cc6b4SJerry Jelinek
167*385cc6b4SJerry Jelinek do
168*385cc6b4SJerry Jelinek {
169*385cc6b4SJerry Jelinek Status = AcpiRead (&SleepStatus, &AcpiGbl_FADT.SleepStatus);
170*385cc6b4SJerry Jelinek if (ACPI_FAILURE (Status))
171*385cc6b4SJerry Jelinek {
172*385cc6b4SJerry Jelinek return_ACPI_STATUS (Status);
173*385cc6b4SJerry Jelinek }
174*385cc6b4SJerry Jelinek
175*385cc6b4SJerry Jelinek } while (!(((UINT8) SleepStatus) & ACPI_X_WAKE_STATUS));
176*385cc6b4SJerry Jelinek
177*385cc6b4SJerry Jelinek return_ACPI_STATUS (AE_OK);
178*385cc6b4SJerry Jelinek }
179*385cc6b4SJerry Jelinek
180*385cc6b4SJerry Jelinek
181*385cc6b4SJerry Jelinek /*******************************************************************************
182*385cc6b4SJerry Jelinek *
183*385cc6b4SJerry Jelinek * FUNCTION: AcpiHwExtendedWakePrep
184*385cc6b4SJerry Jelinek *
185*385cc6b4SJerry Jelinek * PARAMETERS: SleepState - Which sleep state we just exited
186*385cc6b4SJerry Jelinek *
187*385cc6b4SJerry Jelinek * RETURN: Status
188*385cc6b4SJerry Jelinek *
189*385cc6b4SJerry Jelinek * DESCRIPTION: Perform first part of OS-independent ACPI cleanup after
190*385cc6b4SJerry Jelinek * a sleep. Called with interrupts ENABLED.
191*385cc6b4SJerry Jelinek *
192*385cc6b4SJerry Jelinek ******************************************************************************/
193*385cc6b4SJerry Jelinek
194*385cc6b4SJerry Jelinek ACPI_STATUS
AcpiHwExtendedWakePrep(UINT8 SleepState)195*385cc6b4SJerry Jelinek AcpiHwExtendedWakePrep (
196*385cc6b4SJerry Jelinek UINT8 SleepState)
197*385cc6b4SJerry Jelinek {
198*385cc6b4SJerry Jelinek ACPI_STATUS Status;
199*385cc6b4SJerry Jelinek UINT8 SleepTypeValue;
200*385cc6b4SJerry Jelinek
201*385cc6b4SJerry Jelinek
202*385cc6b4SJerry Jelinek ACPI_FUNCTION_TRACE (HwExtendedWakePrep);
203*385cc6b4SJerry Jelinek
204*385cc6b4SJerry Jelinek
205*385cc6b4SJerry Jelinek Status = AcpiGetSleepTypeData (ACPI_STATE_S0,
206*385cc6b4SJerry Jelinek &AcpiGbl_SleepTypeA, &AcpiGbl_SleepTypeB);
207*385cc6b4SJerry Jelinek if (ACPI_SUCCESS (Status))
208*385cc6b4SJerry Jelinek {
209*385cc6b4SJerry Jelinek SleepTypeValue = ((AcpiGbl_SleepTypeA << ACPI_X_SLEEP_TYPE_POSITION) &
210*385cc6b4SJerry Jelinek ACPI_X_SLEEP_TYPE_MASK);
211*385cc6b4SJerry Jelinek
212*385cc6b4SJerry Jelinek (void) AcpiWrite ((UINT64) (SleepTypeValue | ACPI_X_SLEEP_ENABLE),
213*385cc6b4SJerry Jelinek &AcpiGbl_FADT.SleepControl);
214*385cc6b4SJerry Jelinek }
215*385cc6b4SJerry Jelinek
216*385cc6b4SJerry Jelinek return_ACPI_STATUS (AE_OK);
217*385cc6b4SJerry Jelinek }
218*385cc6b4SJerry Jelinek
219*385cc6b4SJerry Jelinek
220*385cc6b4SJerry Jelinek /*******************************************************************************
221*385cc6b4SJerry Jelinek *
222*385cc6b4SJerry Jelinek * FUNCTION: AcpiHwExtendedWake
223*385cc6b4SJerry Jelinek *
224*385cc6b4SJerry Jelinek * PARAMETERS: SleepState - Which sleep state we just exited
225*385cc6b4SJerry Jelinek *
226*385cc6b4SJerry Jelinek * RETURN: Status
227*385cc6b4SJerry Jelinek *
228*385cc6b4SJerry Jelinek * DESCRIPTION: Perform OS-independent ACPI cleanup after a sleep
229*385cc6b4SJerry Jelinek * Called with interrupts ENABLED.
230*385cc6b4SJerry Jelinek *
231*385cc6b4SJerry Jelinek ******************************************************************************/
232*385cc6b4SJerry Jelinek
233*385cc6b4SJerry Jelinek ACPI_STATUS
AcpiHwExtendedWake(UINT8 SleepState)234*385cc6b4SJerry Jelinek AcpiHwExtendedWake (
235*385cc6b4SJerry Jelinek UINT8 SleepState)
236*385cc6b4SJerry Jelinek {
237*385cc6b4SJerry Jelinek ACPI_FUNCTION_TRACE (HwExtendedWake);
238*385cc6b4SJerry Jelinek
239*385cc6b4SJerry Jelinek
240*385cc6b4SJerry Jelinek /* Ensure EnterSleepStatePrep -> EnterSleepState ordering */
241*385cc6b4SJerry Jelinek
242*385cc6b4SJerry Jelinek AcpiGbl_SleepTypeA = ACPI_SLEEP_TYPE_INVALID;
243*385cc6b4SJerry Jelinek
244*385cc6b4SJerry Jelinek /* Execute the wake methods */
245*385cc6b4SJerry Jelinek
246*385cc6b4SJerry Jelinek AcpiHwExecuteSleepMethod (METHOD_PATHNAME__SST, ACPI_SST_WAKING);
247*385cc6b4SJerry Jelinek AcpiHwExecuteSleepMethod (METHOD_PATHNAME__WAK, SleepState);
248*385cc6b4SJerry Jelinek
249*385cc6b4SJerry Jelinek /*
250*385cc6b4SJerry Jelinek * Some BIOS code assumes that WAK_STS will be cleared on resume
251*385cc6b4SJerry Jelinek * and use it to determine whether the system is rebooting or
252*385cc6b4SJerry Jelinek * resuming. Clear WAK_STS for compatibility.
253*385cc6b4SJerry Jelinek */
254*385cc6b4SJerry Jelinek (void) AcpiWrite ((UINT64) ACPI_X_WAKE_STATUS, &AcpiGbl_FADT.SleepStatus);
255*385cc6b4SJerry Jelinek AcpiGbl_SystemAwakeAndRunning = TRUE;
256*385cc6b4SJerry Jelinek
257*385cc6b4SJerry Jelinek AcpiHwExecuteSleepMethod (METHOD_PATHNAME__SST, ACPI_SST_WORKING);
258*385cc6b4SJerry Jelinek return_ACPI_STATUS (AE_OK);
259*385cc6b4SJerry Jelinek }
260