ACPICA: Add function to handle PM1 control registers
[linux-2.6.git] / drivers / acpi / acpica / hwsleep.c
1
2 /******************************************************************************
3  *
4  * Name: hwsleep.c - ACPI Hardware Sleep/Wake Interface
5  *
6  *****************************************************************************/
7
8 /*
9  * Copyright (C) 2000 - 2008, Intel Corp.
10  * All rights reserved.
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
15  * 1. Redistributions of source code must retain the above copyright
16  *    notice, this list of conditions, and the following disclaimer,
17  *    without modification.
18  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19  *    substantially similar to the "NO WARRANTY" disclaimer below
20  *    ("Disclaimer") and any redistribution must be conditioned upon
21  *    including a substantially similar Disclaimer requirement for further
22  *    binary redistribution.
23  * 3. Neither the names of the above-listed copyright holders nor the names
24  *    of any contributors may be used to endorse or promote products derived
25  *    from this software without specific prior written permission.
26  *
27  * Alternatively, this software may be distributed under the terms of the
28  * GNU General Public License ("GPL") version 2 as published by the Free
29  * Software Foundation.
30  *
31  * NO WARRANTY
32  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42  * POSSIBILITY OF SUCH DAMAGES.
43  */
44
45 #include <acpi/acpi.h>
46 #include "accommon.h"
47 #include "actables.h"
48
49 #define _COMPONENT          ACPI_HARDWARE
50 ACPI_MODULE_NAME("hwsleep")
51
52 /*******************************************************************************
53  *
54  * FUNCTION:    acpi_set_firmware_waking_vector
55  *
56  * PARAMETERS:  physical_address    - 32-bit physical address of ACPI real mode
57  *                                    entry point.
58  *
59  * RETURN:      Status
60  *
61  * DESCRIPTION: Sets the 32-bit firmware_waking_vector field of the FACS
62  *
63  ******************************************************************************/
64 acpi_status
65 acpi_set_firmware_waking_vector(u32 physical_address)
66 {
67         ACPI_FUNCTION_TRACE(acpi_set_firmware_waking_vector);
68
69
70         /*
71          * According to the ACPI specification 2.0c and later, the 64-bit
72          * waking vector should be cleared and the 32-bit waking vector should
73          * be used, unless we want the wake-up code to be called by the BIOS in
74          * Protected Mode.  Some systems (for example HP dv5-1004nr) are known
75          * to fail to resume if the 64-bit vector is used.
76          */
77
78         /* Set the 32-bit vector */
79
80         acpi_gbl_FACS->firmware_waking_vector = physical_address;
81
82         /* Clear the 64-bit vector if it exists */
83
84         if ((acpi_gbl_FACS->length > 32) && (acpi_gbl_FACS->version >= 1)) {
85                 acpi_gbl_FACS->xfirmware_waking_vector = 0;
86         }
87
88         return_ACPI_STATUS(AE_OK);
89 }
90
91 ACPI_EXPORT_SYMBOL(acpi_set_firmware_waking_vector)
92
93 /*******************************************************************************
94  *
95  * FUNCTION:    acpi_set_firmware_waking_vector64
96  *
97  * PARAMETERS:  physical_address    - 64-bit physical address of ACPI protected
98  *                                    mode entry point.
99  *
100  * RETURN:      Status
101  *
102  * DESCRIPTION: Sets the 64-bit X_firmware_waking_vector field of the FACS, if
103  *              it exists in the table.
104  *
105  ******************************************************************************/
106 acpi_status
107 acpi_set_firmware_waking_vector64(u64 physical_address)
108 {
109         ACPI_FUNCTION_TRACE(acpi_set_firmware_waking_vector64);
110
111
112         /* Determine if the 64-bit vector actually exists */
113
114         if ((acpi_gbl_FACS->length <= 32) || (acpi_gbl_FACS->version < 1)) {
115                 return_ACPI_STATUS(AE_NOT_EXIST);
116         }
117
118         /* Clear 32-bit vector, set the 64-bit X_ vector */
119
120         acpi_gbl_FACS->firmware_waking_vector = 0;
121         acpi_gbl_FACS->xfirmware_waking_vector = physical_address;
122
123         return_ACPI_STATUS(AE_OK);
124 }
125
126 ACPI_EXPORT_SYMBOL(acpi_set_firmware_waking_vector64)
127
128 /*******************************************************************************
129  *
130  * FUNCTION:    acpi_enter_sleep_state_prep
131  *
132  * PARAMETERS:  sleep_state         - Which sleep state to enter
133  *
134  * RETURN:      Status
135  *
136  * DESCRIPTION: Prepare to enter a system sleep state (see ACPI 2.0 spec p 231)
137  *              This function must execute with interrupts enabled.
138  *              We break sleeping into 2 stages so that OSPM can handle
139  *              various OS-specific tasks between the two steps.
140  *
141  ******************************************************************************/
142 acpi_status acpi_enter_sleep_state_prep(u8 sleep_state)
143 {
144         acpi_status status;
145         struct acpi_object_list arg_list;
146         union acpi_object arg;
147
148         ACPI_FUNCTION_TRACE(acpi_enter_sleep_state_prep);
149
150         /* _PSW methods could be run here to enable wake-on keyboard, LAN, etc. */
151
152         status = acpi_get_sleep_type_data(sleep_state,
153                                           &acpi_gbl_sleep_type_a,
154                                           &acpi_gbl_sleep_type_b);
155         if (ACPI_FAILURE(status)) {
156                 return_ACPI_STATUS(status);
157         }
158
159         /* Setup parameter object */
160
161         arg_list.count = 1;
162         arg_list.pointer = &arg;
163
164         arg.type = ACPI_TYPE_INTEGER;
165         arg.integer.value = sleep_state;
166
167         /* Run the _PTS method */
168
169         status = acpi_evaluate_object(NULL, METHOD_NAME__PTS, &arg_list, NULL);
170         if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
171                 return_ACPI_STATUS(status);
172         }
173
174         /* Setup the argument to _SST */
175
176         switch (sleep_state) {
177         case ACPI_STATE_S0:
178                 arg.integer.value = ACPI_SST_WORKING;
179                 break;
180
181         case ACPI_STATE_S1:
182         case ACPI_STATE_S2:
183         case ACPI_STATE_S3:
184                 arg.integer.value = ACPI_SST_SLEEPING;
185                 break;
186
187         case ACPI_STATE_S4:
188                 arg.integer.value = ACPI_SST_SLEEP_CONTEXT;
189                 break;
190
191         default:
192                 arg.integer.value = ACPI_SST_INDICATOR_OFF;     /* Default is off */
193                 break;
194         }
195
196         /*
197          * Set the system indicators to show the desired sleep state.
198          * _SST is an optional method (return no error if not found)
199          */
200         status = acpi_evaluate_object(NULL, METHOD_NAME__SST, &arg_list, NULL);
201         if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
202                 ACPI_EXCEPTION((AE_INFO, status,
203                                 "While executing method _SST"));
204         }
205
206         return_ACPI_STATUS(AE_OK);
207 }
208
209 ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state_prep)
210
211 /*******************************************************************************
212  *
213  * FUNCTION:    acpi_enter_sleep_state
214  *
215  * PARAMETERS:  sleep_state         - Which sleep state to enter
216  *
217  * RETURN:      Status
218  *
219  * DESCRIPTION: Enter a system sleep state (see ACPI 2.0 spec p 231)
220  *              THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED
221  *
222  ******************************************************************************/
223 acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
224 {
225         u32 pm1a_control;
226         u32 pm1b_control;
227         struct acpi_bit_register_info *sleep_type_reg_info;
228         struct acpi_bit_register_info *sleep_enable_reg_info;
229         u32 in_value;
230         struct acpi_object_list arg_list;
231         union acpi_object arg;
232         acpi_status status;
233
234         ACPI_FUNCTION_TRACE(acpi_enter_sleep_state);
235
236         if ((acpi_gbl_sleep_type_a > ACPI_SLEEP_TYPE_MAX) ||
237             (acpi_gbl_sleep_type_b > ACPI_SLEEP_TYPE_MAX)) {
238                 ACPI_ERROR((AE_INFO, "Sleep values out of range: A=%X B=%X",
239                             acpi_gbl_sleep_type_a, acpi_gbl_sleep_type_b));
240                 return_ACPI_STATUS(AE_AML_OPERAND_VALUE);
241         }
242
243         sleep_type_reg_info =
244             acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_TYPE);
245         sleep_enable_reg_info =
246             acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_ENABLE);
247
248         /* Clear wake status */
249
250         status = acpi_set_register(ACPI_BITREG_WAKE_STATUS, 1);
251         if (ACPI_FAILURE(status)) {
252                 return_ACPI_STATUS(status);
253         }
254
255         /* Clear all fixed and general purpose status bits */
256
257         status = acpi_hw_clear_acpi_status();
258         if (ACPI_FAILURE(status)) {
259                 return_ACPI_STATUS(status);
260         }
261
262         /*
263          * 1) Disable/Clear all GPEs
264          * 2) Enable all wakeup GPEs
265          */
266         status = acpi_hw_disable_all_gpes();
267         if (ACPI_FAILURE(status)) {
268                 return_ACPI_STATUS(status);
269         }
270         acpi_gbl_system_awake_and_running = FALSE;
271
272         status = acpi_hw_enable_all_wakeup_gpes();
273         if (ACPI_FAILURE(status)) {
274                 return_ACPI_STATUS(status);
275         }
276
277         /* Execute the _GTS method */
278
279         arg_list.count = 1;
280         arg_list.pointer = &arg;
281         arg.type = ACPI_TYPE_INTEGER;
282         arg.integer.value = sleep_state;
283
284         status = acpi_evaluate_object(NULL, METHOD_NAME__GTS, &arg_list, NULL);
285         if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
286                 return_ACPI_STATUS(status);
287         }
288
289         /* Get current value of PM1A control */
290
291         status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL,
292                                        &pm1a_control);
293         if (ACPI_FAILURE(status)) {
294                 return_ACPI_STATUS(status);
295         }
296         ACPI_DEBUG_PRINT((ACPI_DB_INIT,
297                           "Entering sleep state [S%d]\n", sleep_state));
298
299         /* Clear the SLP_EN and SLP_TYP fields */
300
301         pm1a_control &= ~(sleep_type_reg_info->access_bit_mask |
302                           sleep_enable_reg_info->access_bit_mask);
303         pm1b_control = pm1a_control;
304
305         /* Insert the SLP_TYP bits */
306
307         pm1a_control |=
308             (acpi_gbl_sleep_type_a << sleep_type_reg_info->bit_position);
309         pm1b_control |=
310             (acpi_gbl_sleep_type_b << sleep_type_reg_info->bit_position);
311
312         /*
313          * We split the writes of SLP_TYP and SLP_EN to workaround
314          * poorly implemented hardware.
315          */
316
317         /* Write #1: write the SLP_TYP data to the PM1 Control registers */
318
319         status = acpi_hw_write_pm1_control(pm1a_control, pm1b_control);
320         if (ACPI_FAILURE(status)) {
321                 return_ACPI_STATUS(status);
322         }
323
324         /* Insert the sleep enable (SLP_EN) bit */
325
326         pm1a_control |= sleep_enable_reg_info->access_bit_mask;
327         pm1b_control |= sleep_enable_reg_info->access_bit_mask;
328
329         /* Flush caches, as per ACPI specification */
330
331         ACPI_FLUSH_CPU_CACHE();
332
333         /* Write #2: Write both SLP_TYP + SLP_EN */
334
335         status = acpi_hw_write_pm1_control(pm1a_control, pm1b_control);
336         if (ACPI_FAILURE(status)) {
337                 return_ACPI_STATUS(status);
338         }
339
340         if (sleep_state > ACPI_STATE_S3) {
341                 /*
342                  * We wanted to sleep > S3, but it didn't happen (by virtue of the
343                  * fact that we are still executing!)
344                  *
345                  * Wait ten seconds, then try again. This is to get S4/S5 to work on
346                  * all machines.
347                  *
348                  * We wait so long to allow chipsets that poll this reg very slowly to
349                  * still read the right value. Ideally, this block would go
350                  * away entirely.
351                  */
352                 acpi_os_stall(10000000);
353
354                 status = acpi_hw_register_write(ACPI_REGISTER_PM1_CONTROL,
355                                                 sleep_enable_reg_info->
356                                                 access_bit_mask);
357                 if (ACPI_FAILURE(status)) {
358                         return_ACPI_STATUS(status);
359                 }
360         }
361
362         /* Wait until we enter sleep state */
363
364         do {
365                 status = acpi_get_register_unlocked(ACPI_BITREG_WAKE_STATUS,
366                                                     &in_value);
367                 if (ACPI_FAILURE(status)) {
368                         return_ACPI_STATUS(status);
369                 }
370
371                 /* Spin until we wake */
372
373         } while (!in_value);
374
375         return_ACPI_STATUS(AE_OK);
376 }
377
378 ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state)
379
380 /*******************************************************************************
381  *
382  * FUNCTION:    acpi_enter_sleep_state_s4bios
383  *
384  * PARAMETERS:  None
385  *
386  * RETURN:      Status
387  *
388  * DESCRIPTION: Perform a S4 bios request.
389  *              THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED
390  *
391  ******************************************************************************/
392 acpi_status asmlinkage acpi_enter_sleep_state_s4bios(void)
393 {
394         u32 in_value;
395         acpi_status status;
396
397         ACPI_FUNCTION_TRACE(acpi_enter_sleep_state_s4bios);
398
399         status = acpi_set_register(ACPI_BITREG_WAKE_STATUS, 1);
400         if (ACPI_FAILURE(status)) {
401                 return_ACPI_STATUS(status);
402         }
403
404         status = acpi_hw_clear_acpi_status();
405         if (ACPI_FAILURE(status)) {
406                 return_ACPI_STATUS(status);
407         }
408
409         /*
410          * 1) Disable/Clear all GPEs
411          * 2) Enable all wakeup GPEs
412          */
413         status = acpi_hw_disable_all_gpes();
414         if (ACPI_FAILURE(status)) {
415                 return_ACPI_STATUS(status);
416         }
417         acpi_gbl_system_awake_and_running = FALSE;
418
419         status = acpi_hw_enable_all_wakeup_gpes();
420         if (ACPI_FAILURE(status)) {
421                 return_ACPI_STATUS(status);
422         }
423
424         ACPI_FLUSH_CPU_CACHE();
425
426         status = acpi_os_write_port(acpi_gbl_FADT.smi_command,
427                                     (u32) acpi_gbl_FADT.S4bios_request, 8);
428
429         do {
430                 acpi_os_stall(1000);
431                 status = acpi_get_register(ACPI_BITREG_WAKE_STATUS, &in_value);
432                 if (ACPI_FAILURE(status)) {
433                         return_ACPI_STATUS(status);
434                 }
435         } while (!in_value);
436
437         return_ACPI_STATUS(AE_OK);
438 }
439
440 ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state_s4bios)
441
442 /*******************************************************************************
443  *
444  * FUNCTION:    acpi_leave_sleep_state_prep
445  *
446  * PARAMETERS:  sleep_state         - Which sleep state we are exiting
447  *
448  * RETURN:      Status
449  *
450  * DESCRIPTION: Perform the first state of OS-independent ACPI cleanup after a
451  *              sleep.
452  *              Called with interrupts DISABLED.
453  *
454  ******************************************************************************/
455 acpi_status acpi_leave_sleep_state_prep(u8 sleep_state)
456 {
457         struct acpi_object_list arg_list;
458         union acpi_object arg;
459         acpi_status status;
460         struct acpi_bit_register_info *sleep_type_reg_info;
461         struct acpi_bit_register_info *sleep_enable_reg_info;
462         u32 pm1a_control;
463         u32 pm1b_control;
464
465         ACPI_FUNCTION_TRACE(acpi_leave_sleep_state_prep);
466
467         /*
468          * Set SLP_TYPE and SLP_EN to state S0.
469          * This is unclear from the ACPI Spec, but it is required
470          * by some machines.
471          */
472         status = acpi_get_sleep_type_data(ACPI_STATE_S0,
473                                           &acpi_gbl_sleep_type_a,
474                                           &acpi_gbl_sleep_type_b);
475         if (ACPI_SUCCESS(status)) {
476                 sleep_type_reg_info =
477                     acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_TYPE);
478                 sleep_enable_reg_info =
479                     acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_ENABLE);
480
481                 /* Get current value of PM1A control */
482
483                 status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL,
484                                                &pm1a_control);
485                 if (ACPI_SUCCESS(status)) {
486
487                         /* Clear the SLP_EN and SLP_TYP fields */
488
489                         pm1a_control &= ~(sleep_type_reg_info->access_bit_mask |
490                                           sleep_enable_reg_info->
491                                           access_bit_mask);
492                         pm1b_control = pm1a_control;
493
494                         /* Insert the SLP_TYP bits */
495
496                         pm1a_control |=
497                             (acpi_gbl_sleep_type_a << sleep_type_reg_info->
498                              bit_position);
499                         pm1b_control |=
500                             (acpi_gbl_sleep_type_b << sleep_type_reg_info->
501                              bit_position);
502
503                         /* Write the control registers and ignore any errors */
504
505                         (void)acpi_hw_write_pm1_control(pm1a_control,
506                                                         pm1b_control);
507                 }
508         }
509
510         /* Execute the _BFS method */
511
512         arg_list.count = 1;
513         arg_list.pointer = &arg;
514         arg.type = ACPI_TYPE_INTEGER;
515         arg.integer.value = sleep_state;
516
517         status = acpi_evaluate_object(NULL, METHOD_NAME__BFS, &arg_list, NULL);
518         if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
519                 ACPI_EXCEPTION((AE_INFO, status, "During Method _BFS"));
520         }
521
522         return_ACPI_STATUS(status);
523 }
524
525 /*******************************************************************************
526  *
527  * FUNCTION:    acpi_leave_sleep_state
528  *
529  * PARAMETERS:  sleep_state         - Which sleep state we just exited
530  *
531  * RETURN:      Status
532  *
533  * DESCRIPTION: Perform OS-independent ACPI cleanup after a sleep
534  *              Called with interrupts ENABLED.
535  *
536  ******************************************************************************/
537 acpi_status acpi_leave_sleep_state(u8 sleep_state)
538 {
539         struct acpi_object_list arg_list;
540         union acpi_object arg;
541         acpi_status status;
542
543         ACPI_FUNCTION_TRACE(acpi_leave_sleep_state);
544
545         /* Ensure enter_sleep_state_prep -> enter_sleep_state ordering */
546
547         acpi_gbl_sleep_type_a = ACPI_SLEEP_TYPE_INVALID;
548
549         /* Setup parameter object */
550
551         arg_list.count = 1;
552         arg_list.pointer = &arg;
553         arg.type = ACPI_TYPE_INTEGER;
554
555         /* Ignore any errors from these methods */
556
557         arg.integer.value = ACPI_SST_WAKING;
558         status = acpi_evaluate_object(NULL, METHOD_NAME__SST, &arg_list, NULL);
559         if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
560                 ACPI_EXCEPTION((AE_INFO, status, "During Method _SST"));
561         }
562
563         /*
564          * GPEs must be enabled before _WAK is called as GPEs
565          * might get fired there
566          *
567          * Restore the GPEs:
568          * 1) Disable/Clear all GPEs
569          * 2) Enable all runtime GPEs
570          */
571         status = acpi_hw_disable_all_gpes();
572         if (ACPI_FAILURE(status)) {
573                 return_ACPI_STATUS(status);
574         }
575         status = acpi_hw_enable_all_runtime_gpes();
576         if (ACPI_FAILURE(status)) {
577                 return_ACPI_STATUS(status);
578         }
579
580         arg.integer.value = sleep_state;
581         status = acpi_evaluate_object(NULL, METHOD_NAME__WAK, &arg_list, NULL);
582         if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
583                 ACPI_EXCEPTION((AE_INFO, status, "During Method _WAK"));
584         }
585         /* TBD: _WAK "sometimes" returns stuff - do we want to look at it? */
586
587         /*
588          * Some BIOSes assume that WAK_STS will be cleared on resume and use
589          * it to determine whether the system is rebooting or resuming. Clear
590          * it for compatibility.
591          */
592         acpi_set_register(ACPI_BITREG_WAKE_STATUS, 1);
593
594         acpi_gbl_system_awake_and_running = TRUE;
595
596         /* Enable power button */
597
598         (void)
599             acpi_set_register(acpi_gbl_fixed_event_info
600                               [ACPI_EVENT_POWER_BUTTON].enable_register_id, 1);
601
602         (void)
603             acpi_set_register(acpi_gbl_fixed_event_info
604                               [ACPI_EVENT_POWER_BUTTON].status_register_id, 1);
605
606         arg.integer.value = ACPI_SST_WORKING;
607         status = acpi_evaluate_object(NULL, METHOD_NAME__SST, &arg_list, NULL);
608         if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
609                 ACPI_EXCEPTION((AE_INFO, status, "During Method _SST"));
610         }
611
612         return_ACPI_STATUS(status);
613 }
614
615 ACPI_EXPORT_SYMBOL(acpi_leave_sleep_state)