ACPICA: Hardware: Enable 64-bit firmware waking vector for selected FACS
[firefly-linux-kernel-4.4.55.git] / drivers / acpi / acpica / hwxfsleep.c
1 /******************************************************************************
2  *
3  * Name: hwxfsleep.c - ACPI Hardware Sleep/Wake External Interfaces
4  *
5  *****************************************************************************/
6
7 /*
8  * Copyright (C) 2000 - 2015, Intel Corp.
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions, and the following disclaimer,
16  *    without modification.
17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18  *    substantially similar to the "NO WARRANTY" disclaimer below
19  *    ("Disclaimer") and any redistribution must be conditioned upon
20  *    including a substantially similar Disclaimer requirement for further
21  *    binary redistribution.
22  * 3. Neither the names of the above-listed copyright holders nor the names
23  *    of any contributors may be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * Alternatively, this software may be distributed under the terms of the
27  * GNU General Public License ("GPL") version 2 as published by the Free
28  * Software Foundation.
29  *
30  * NO WARRANTY
31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41  * POSSIBILITY OF SUCH DAMAGES.
42  */
43
44 #define EXPORT_ACPI_INTERFACES
45
46 #include <acpi/acpi.h>
47 #include "accommon.h"
48
49 #define _COMPONENT          ACPI_HARDWARE
50 ACPI_MODULE_NAME("hwxfsleep")
51
52 /* Local prototypes */
53 static acpi_status acpi_hw_sleep_dispatch(u8 sleep_state, u32 function_id);
54
55 /*
56  * Dispatch table used to efficiently branch to the various sleep
57  * functions.
58  */
59 #define ACPI_SLEEP_FUNCTION_ID         0
60 #define ACPI_WAKE_PREP_FUNCTION_ID     1
61 #define ACPI_WAKE_FUNCTION_ID          2
62
63 /* Legacy functions are optional, based upon ACPI_REDUCED_HARDWARE */
64
65 static struct acpi_sleep_functions acpi_sleep_dispatch[] = {
66         {ACPI_HW_OPTIONAL_FUNCTION(acpi_hw_legacy_sleep),
67          acpi_hw_extended_sleep},
68         {ACPI_HW_OPTIONAL_FUNCTION(acpi_hw_legacy_wake_prep),
69          acpi_hw_extended_wake_prep},
70         {ACPI_HW_OPTIONAL_FUNCTION(acpi_hw_legacy_wake), acpi_hw_extended_wake}
71 };
72
73 /*
74  * These functions are removed for the ACPI_REDUCED_HARDWARE case:
75  *      acpi_set_firmware_waking_vectors
76  *      acpi_set_firmware_waking_vector
77  *      acpi_set_firmware_waking_vector64
78  *      acpi_enter_sleep_state_s4bios
79  */
80
81 #if (!ACPI_REDUCED_HARDWARE)
82 /*******************************************************************************
83  *
84  * FUNCTION:    acpi_set_firmware_waking_vectors
85  *
86  * PARAMETERS:  physical_address    - 32-bit physical address of ACPI real mode
87  *                                    entry point.
88  *              physical_address64  - 64-bit physical address of ACPI protected
89  *                                    mode entry point.
90  *
91  * RETURN:      Status
92  *
93  * DESCRIPTION: Sets the firmware_waking_vector fields of the FACS
94  *
95  ******************************************************************************/
96
97 acpi_status
98 acpi_set_firmware_waking_vectors(acpi_physical_address physical_address,
99                                  acpi_physical_address physical_address64)
100 {
101         ACPI_FUNCTION_TRACE(acpi_set_firmware_waking_vectors);
102
103
104         /*
105          * According to the ACPI specification 2.0c and later, the 64-bit
106          * waking vector should be cleared and the 32-bit waking vector should
107          * be used, unless we want the wake-up code to be called by the BIOS in
108          * Protected Mode.  Some systems (for example HP dv5-1004nr) are known
109          * to fail to resume if the 64-bit vector is used.
110          */
111
112         /* Set the 32-bit vector */
113
114         acpi_gbl_FACS->firmware_waking_vector = (u32)physical_address;
115
116         if (acpi_gbl_FACS->length > 32) {
117                 if (acpi_gbl_FACS->version >= 1) {
118
119                         /* Set the 64-bit vector */
120
121                         acpi_gbl_FACS->xfirmware_waking_vector =
122                             physical_address64;
123                 } else {
124                         /* Clear the 64-bit vector if it exists */
125
126                         acpi_gbl_FACS->xfirmware_waking_vector = 0;
127                 }
128         }
129
130         return_ACPI_STATUS(AE_OK);
131 }
132
133 ACPI_EXPORT_SYMBOL(acpi_set_firmware_waking_vectors)
134
135 /*******************************************************************************
136  *
137  * FUNCTION:    acpi_set_firmware_waking_vector
138  *
139  * PARAMETERS:  physical_address    - 32-bit physical address of ACPI real mode
140  *                                    entry point.
141  *
142  * RETURN:      Status
143  *
144  * DESCRIPTION: Sets the 32-bit firmware_waking_vector field of the FACS
145  *
146  ******************************************************************************/
147 acpi_status acpi_set_firmware_waking_vector(u32 physical_address)
148 {
149         acpi_status status;
150
151         ACPI_FUNCTION_TRACE(acpi_set_firmware_waking_vector);
152
153         status = acpi_set_firmware_waking_vectors((acpi_physical_address)
154                                                   physical_address, 0);
155
156         return_ACPI_STATUS(status);
157 }
158
159 ACPI_EXPORT_SYMBOL(acpi_set_firmware_waking_vector)
160
161 #if ACPI_MACHINE_WIDTH == 64
162 /*******************************************************************************
163  *
164  * FUNCTION:    acpi_set_firmware_waking_vector64
165  *
166  * PARAMETERS:  physical_address    - 64-bit physical address of ACPI protected
167  *                                    mode entry point.
168  *
169  * RETURN:      Status
170  *
171  * DESCRIPTION: Sets the 64-bit X_firmware_waking_vector field of the FACS, if
172  *              it exists in the table. This function is intended for use with
173  *              64-bit host operating systems.
174  *
175  ******************************************************************************/
176 acpi_status acpi_set_firmware_waking_vector64(u64 physical_address)
177 {
178         acpi_status status;
179
180         ACPI_FUNCTION_TRACE(acpi_set_firmware_waking_vector64);
181
182         status = acpi_set_firmware_waking_vectors(0,
183                                                   (acpi_physical_address)
184                                                   physical_address);
185
186         return_ACPI_STATUS(status);
187 }
188
189 ACPI_EXPORT_SYMBOL(acpi_set_firmware_waking_vector64)
190 #endif
191 /*******************************************************************************
192  *
193  * FUNCTION:    acpi_enter_sleep_state_s4bios
194  *
195  * PARAMETERS:  None
196  *
197  * RETURN:      Status
198  *
199  * DESCRIPTION: Perform a S4 bios request.
200  *              THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED
201  *
202  ******************************************************************************/
203 acpi_status acpi_enter_sleep_state_s4bios(void)
204 {
205         u32 in_value;
206         acpi_status status;
207
208         ACPI_FUNCTION_TRACE(acpi_enter_sleep_state_s4bios);
209
210         /* Clear the wake status bit (PM1) */
211
212         status =
213             acpi_write_bit_register(ACPI_BITREG_WAKE_STATUS, ACPI_CLEAR_STATUS);
214         if (ACPI_FAILURE(status)) {
215                 return_ACPI_STATUS(status);
216         }
217
218         status = acpi_hw_clear_acpi_status();
219         if (ACPI_FAILURE(status)) {
220                 return_ACPI_STATUS(status);
221         }
222
223         /*
224          * 1) Disable/Clear all GPEs
225          * 2) Enable all wakeup GPEs
226          */
227         status = acpi_hw_disable_all_gpes();
228         if (ACPI_FAILURE(status)) {
229                 return_ACPI_STATUS(status);
230         }
231         acpi_gbl_system_awake_and_running = FALSE;
232
233         status = acpi_hw_enable_all_wakeup_gpes();
234         if (ACPI_FAILURE(status)) {
235                 return_ACPI_STATUS(status);
236         }
237
238         ACPI_FLUSH_CPU_CACHE();
239
240         status = acpi_hw_write_port(acpi_gbl_FADT.smi_command,
241                                     (u32)acpi_gbl_FADT.s4_bios_request, 8);
242
243         do {
244                 acpi_os_stall(ACPI_USEC_PER_MSEC);
245                 status =
246                     acpi_read_bit_register(ACPI_BITREG_WAKE_STATUS, &in_value);
247                 if (ACPI_FAILURE(status)) {
248                         return_ACPI_STATUS(status);
249                 }
250         } while (!in_value);
251
252         return_ACPI_STATUS(AE_OK);
253 }
254
255 ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state_s4bios)
256 #endif                          /* !ACPI_REDUCED_HARDWARE */
257 /*******************************************************************************
258  *
259  * FUNCTION:    acpi_hw_sleep_dispatch
260  *
261  * PARAMETERS:  sleep_state         - Which sleep state to enter/exit
262  *              function_id         - Sleep, wake_prep, or Wake
263  *
264  * RETURN:      Status from the invoked sleep handling function.
265  *
266  * DESCRIPTION: Dispatch a sleep/wake request to the appropriate handling
267  *              function.
268  *
269  ******************************************************************************/
270 static acpi_status acpi_hw_sleep_dispatch(u8 sleep_state, u32 function_id)
271 {
272         acpi_status status;
273         struct acpi_sleep_functions *sleep_functions =
274             &acpi_sleep_dispatch[function_id];
275
276 #if (!ACPI_REDUCED_HARDWARE)
277         /*
278          * If the Hardware Reduced flag is set (from the FADT), we must
279          * use the extended sleep registers (FADT). Note: As per the ACPI
280          * specification, these extended registers are to be used for HW-reduced
281          * platforms only. They are not general-purpose replacements for the
282          * legacy PM register sleep support.
283          */
284         if (acpi_gbl_reduced_hardware) {
285                 status = sleep_functions->extended_function(sleep_state);
286         } else {
287                 /* Legacy sleep */
288
289                 status = sleep_functions->legacy_function(sleep_state);
290         }
291
292         return (status);
293
294 #else
295         /*
296          * For the case where reduced-hardware-only code is being generated,
297          * we know that only the extended sleep registers are available
298          */
299         status = sleep_functions->extended_function(sleep_state);
300         return (status);
301
302 #endif                          /* !ACPI_REDUCED_HARDWARE */
303 }
304
305 /*******************************************************************************
306  *
307  * FUNCTION:    acpi_enter_sleep_state_prep
308  *
309  * PARAMETERS:  sleep_state         - Which sleep state to enter
310  *
311  * RETURN:      Status
312  *
313  * DESCRIPTION: Prepare to enter a system sleep state.
314  *              This function must execute with interrupts enabled.
315  *              We break sleeping into 2 stages so that OSPM can handle
316  *              various OS-specific tasks between the two steps.
317  *
318  ******************************************************************************/
319
320 acpi_status acpi_enter_sleep_state_prep(u8 sleep_state)
321 {
322         acpi_status status;
323         struct acpi_object_list arg_list;
324         union acpi_object arg;
325         u32 sst_value;
326
327         ACPI_FUNCTION_TRACE(acpi_enter_sleep_state_prep);
328
329         status = acpi_get_sleep_type_data(sleep_state,
330                                           &acpi_gbl_sleep_type_a,
331                                           &acpi_gbl_sleep_type_b);
332         if (ACPI_FAILURE(status)) {
333                 return_ACPI_STATUS(status);
334         }
335
336         /* Execute the _PTS method (Prepare To Sleep) */
337
338         arg_list.count = 1;
339         arg_list.pointer = &arg;
340         arg.type = ACPI_TYPE_INTEGER;
341         arg.integer.value = sleep_state;
342
343         status =
344             acpi_evaluate_object(NULL, METHOD_PATHNAME__PTS, &arg_list, NULL);
345         if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
346                 return_ACPI_STATUS(status);
347         }
348
349         /* Setup the argument to the _SST method (System STatus) */
350
351         switch (sleep_state) {
352         case ACPI_STATE_S0:
353
354                 sst_value = ACPI_SST_WORKING;
355                 break;
356
357         case ACPI_STATE_S1:
358         case ACPI_STATE_S2:
359         case ACPI_STATE_S3:
360
361                 sst_value = ACPI_SST_SLEEPING;
362                 break;
363
364         case ACPI_STATE_S4:
365
366                 sst_value = ACPI_SST_SLEEP_CONTEXT;
367                 break;
368
369         default:
370
371                 sst_value = ACPI_SST_INDICATOR_OFF;     /* Default is off */
372                 break;
373         }
374
375         /*
376          * Set the system indicators to show the desired sleep state.
377          * _SST is an optional method (return no error if not found)
378          */
379         acpi_hw_execute_sleep_method(METHOD_PATHNAME__SST, sst_value);
380         return_ACPI_STATUS(AE_OK);
381 }
382
383 ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state_prep)
384
385 /*******************************************************************************
386  *
387  * FUNCTION:    acpi_enter_sleep_state
388  *
389  * PARAMETERS:  sleep_state         - Which sleep state to enter
390  *
391  * RETURN:      Status
392  *
393  * DESCRIPTION: Enter a system sleep state
394  *              THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED
395  *
396  ******************************************************************************/
397 acpi_status acpi_enter_sleep_state(u8 sleep_state)
398 {
399         acpi_status status;
400
401         ACPI_FUNCTION_TRACE(acpi_enter_sleep_state);
402
403         if ((acpi_gbl_sleep_type_a > ACPI_SLEEP_TYPE_MAX) ||
404             (acpi_gbl_sleep_type_b > ACPI_SLEEP_TYPE_MAX)) {
405                 ACPI_ERROR((AE_INFO, "Sleep values out of range: A=0x%X B=0x%X",
406                             acpi_gbl_sleep_type_a, acpi_gbl_sleep_type_b));
407                 return_ACPI_STATUS(AE_AML_OPERAND_VALUE);
408         }
409
410         status = acpi_hw_sleep_dispatch(sleep_state, ACPI_SLEEP_FUNCTION_ID);
411         return_ACPI_STATUS(status);
412 }
413
414 ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state)
415
416 /*******************************************************************************
417  *
418  * FUNCTION:    acpi_leave_sleep_state_prep
419  *
420  * PARAMETERS:  sleep_state         - Which sleep state we are exiting
421  *
422  * RETURN:      Status
423  *
424  * DESCRIPTION: Perform the first state of OS-independent ACPI cleanup after a
425  *              sleep. Called with interrupts DISABLED.
426  *              We break wake/resume into 2 stages so that OSPM can handle
427  *              various OS-specific tasks between the two steps.
428  *
429  ******************************************************************************/
430 acpi_status acpi_leave_sleep_state_prep(u8 sleep_state)
431 {
432         acpi_status status;
433
434         ACPI_FUNCTION_TRACE(acpi_leave_sleep_state_prep);
435
436         status =
437             acpi_hw_sleep_dispatch(sleep_state, ACPI_WAKE_PREP_FUNCTION_ID);
438         return_ACPI_STATUS(status);
439 }
440
441 ACPI_EXPORT_SYMBOL(acpi_leave_sleep_state_prep)
442
443 /*******************************************************************************
444  *
445  * FUNCTION:    acpi_leave_sleep_state
446  *
447  * PARAMETERS:  sleep_state         - Which sleep state we are exiting
448  *
449  * RETURN:      Status
450  *
451  * DESCRIPTION: Perform OS-independent ACPI cleanup after a sleep
452  *              Called with interrupts ENABLED.
453  *
454  ******************************************************************************/
455 acpi_status acpi_leave_sleep_state(u8 sleep_state)
456 {
457         acpi_status status;
458
459         ACPI_FUNCTION_TRACE(acpi_leave_sleep_state);
460
461         status = acpi_hw_sleep_dispatch(sleep_state, ACPI_WAKE_FUNCTION_ID);
462         return_ACPI_STATUS(status);
463 }
464
465 ACPI_EXPORT_SYMBOL(acpi_leave_sleep_state)