vserver 1.9.5.x5
[linux-2.6.git] / drivers / acpi / hardware / hwsleep.c
1
2 /******************************************************************************
3  *
4  * Name: hwsleep.c - ACPI Hardware Sleep/Wake Interface
5  *
6  *****************************************************************************/
7
8 /*
9  * Copyright (C) 2000 - 2005, R. Byron Moore
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 <linux/module.h>
46
47 #include <acpi/acpi.h>
48
49 #define _COMPONENT          ACPI_HARDWARE
50          ACPI_MODULE_NAME    ("hwsleep")
51
52
53 #define METHOD_NAME__BFS        "\\_BFS"
54 #define METHOD_NAME__GTS        "\\_GTS"
55 #define METHOD_NAME__PTS        "\\_PTS"
56 #define METHOD_NAME__SST        "\\_SI._SST"
57 #define METHOD_NAME__WAK        "\\_WAK"
58
59 #define ACPI_SST_INDICATOR_OFF  0
60 #define ACPI_SST_WORKING        1
61 #define ACPI_SST_WAKING         2
62 #define ACPI_SST_SLEEPING       3
63 #define ACPI_SST_SLEEP_CONTEXT  4
64
65
66 /******************************************************************************
67  *
68  * FUNCTION:    acpi_set_firmware_waking_vector
69  *
70  * PARAMETERS:  physical_address    - Physical address of ACPI real mode
71  *                                    entry point.
72  *
73  * RETURN:      Status
74  *
75  * DESCRIPTION: access function for d_firmware_waking_vector field in FACS
76  *
77  ******************************************************************************/
78
79 acpi_status
80 acpi_set_firmware_waking_vector (
81         acpi_physical_address physical_address)
82 {
83
84         ACPI_FUNCTION_TRACE ("acpi_set_firmware_waking_vector");
85
86
87         /* Set the vector */
88
89         if (acpi_gbl_common_fACS.vector_width == 32) {
90                 *(ACPI_CAST_PTR (u32, acpi_gbl_common_fACS.firmware_waking_vector))
91                                 = (u32) physical_address;
92         }
93         else {
94                 *acpi_gbl_common_fACS.firmware_waking_vector
95                                 = physical_address;
96         }
97
98         return_ACPI_STATUS (AE_OK);
99 }
100
101
102 /******************************************************************************
103  *
104  * FUNCTION:    acpi_get_firmware_waking_vector
105  *
106  * PARAMETERS:  *physical_address   - Output buffer where contents of
107  *                                    the firmware_waking_vector field of
108  *                                    the FACS will be stored.
109  *
110  * RETURN:      Status
111  *
112  * DESCRIPTION: Access function for firmware_waking_vector field in FACS
113  *
114  ******************************************************************************/
115 #ifdef ACPI_FUTURE_USAGE
116 acpi_status
117 acpi_get_firmware_waking_vector (
118         acpi_physical_address *physical_address)
119 {
120
121         ACPI_FUNCTION_TRACE ("acpi_get_firmware_waking_vector");
122
123
124         if (!physical_address) {
125                 return_ACPI_STATUS (AE_BAD_PARAMETER);
126         }
127
128         /* Get the vector */
129
130         if (acpi_gbl_common_fACS.vector_width == 32) {
131                 *physical_address = (acpi_physical_address)
132                         *(ACPI_CAST_PTR (u32, acpi_gbl_common_fACS.firmware_waking_vector));
133         }
134         else {
135                 *physical_address =
136                         *acpi_gbl_common_fACS.firmware_waking_vector;
137         }
138
139         return_ACPI_STATUS (AE_OK);
140 }
141 #endif
142
143
144 /******************************************************************************
145  *
146  * FUNCTION:    acpi_enter_sleep_state_prep
147  *
148  * PARAMETERS:  sleep_state         - Which sleep state to enter
149  *
150  * RETURN:      Status
151  *
152  * DESCRIPTION: Prepare to enter a system sleep state (see ACPI 2.0 spec p 231)
153  *              This function must execute with interrupts enabled.
154  *              We break sleeping into 2 stages so that OSPM can handle
155  *              various OS-specific tasks between the two steps.
156  *
157  ******************************************************************************/
158
159 acpi_status
160 acpi_enter_sleep_state_prep (
161         u8                          sleep_state)
162 {
163         acpi_status                 status;
164         struct acpi_object_list     arg_list;
165         union acpi_object           arg;
166
167
168         ACPI_FUNCTION_TRACE ("acpi_enter_sleep_state_prep");
169
170
171         /*
172          * _PSW methods could be run here to enable wake-on keyboard, LAN, etc.
173          */
174         status = acpi_get_sleep_type_data (sleep_state,
175                           &acpi_gbl_sleep_type_a, &acpi_gbl_sleep_type_b);
176         if (ACPI_FAILURE (status)) {
177                 return_ACPI_STATUS (status);
178         }
179
180         /* Setup parameter object */
181
182         arg_list.count = 1;
183         arg_list.pointer = &arg;
184
185         arg.type = ACPI_TYPE_INTEGER;
186         arg.integer.value = sleep_state;
187
188         /* Run the _PTS and _GTS methods */
189
190         status = acpi_evaluate_object (NULL, METHOD_NAME__PTS, &arg_list, NULL);
191         if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) {
192                 return_ACPI_STATUS (status);
193         }
194
195         status = acpi_evaluate_object (NULL, METHOD_NAME__GTS, &arg_list, NULL);
196         if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) {
197                 return_ACPI_STATUS (status);
198         }
199
200         /* Setup the argument to _SST */
201
202         switch (sleep_state) {
203         case ACPI_STATE_S0:
204                 arg.integer.value = ACPI_SST_WORKING;
205                 break;
206
207         case ACPI_STATE_S1:
208         case ACPI_STATE_S2:
209         case ACPI_STATE_S3:
210                 arg.integer.value = ACPI_SST_SLEEPING;
211                 break;
212
213         case ACPI_STATE_S4:
214                 arg.integer.value = ACPI_SST_SLEEP_CONTEXT;
215                 break;
216
217         default:
218                 arg.integer.value = ACPI_SST_INDICATOR_OFF; /* Default is indicator off */
219                 break;
220         }
221
222         /* Set the system indicators to show the desired sleep state. */
223
224         status = acpi_evaluate_object (NULL, METHOD_NAME__SST, &arg_list, NULL);
225         if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) {
226                  ACPI_REPORT_ERROR (("Method _SST failed, %s\n", acpi_format_exception (status)));
227         }
228
229         return_ACPI_STATUS (AE_OK);
230 }
231
232
233 /******************************************************************************
234  *
235  * FUNCTION:    acpi_enter_sleep_state
236  *
237  * PARAMETERS:  sleep_state         - Which sleep state to enter
238  *
239  * RETURN:      Status
240  *
241  * DESCRIPTION: Enter a system sleep state (see ACPI 2.0 spec p 231)
242  *              THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED
243  *
244  ******************************************************************************/
245
246 acpi_status asmlinkage
247 acpi_enter_sleep_state (
248         u8                              sleep_state)
249 {
250         u32                             PM1Acontrol;
251         u32                             PM1Bcontrol;
252         struct acpi_bit_register_info   *sleep_type_reg_info;
253         struct acpi_bit_register_info   *sleep_enable_reg_info;
254         u32                             in_value;
255         acpi_status                     status;
256
257
258         ACPI_FUNCTION_TRACE ("acpi_enter_sleep_state");
259
260
261         if ((acpi_gbl_sleep_type_a > ACPI_SLEEP_TYPE_MAX) ||
262                 (acpi_gbl_sleep_type_b > ACPI_SLEEP_TYPE_MAX)) {
263                 ACPI_REPORT_ERROR (("Sleep values out of range: A=%X B=%X\n",
264                         acpi_gbl_sleep_type_a, acpi_gbl_sleep_type_b));
265                 return_ACPI_STATUS (AE_AML_OPERAND_VALUE);
266         }
267
268         sleep_type_reg_info = acpi_hw_get_bit_register_info (ACPI_BITREG_SLEEP_TYPE_A);
269         sleep_enable_reg_info = acpi_hw_get_bit_register_info (ACPI_BITREG_SLEEP_ENABLE);
270
271         /* Clear wake status */
272
273         status = acpi_set_register (ACPI_BITREG_WAKE_STATUS, 1, ACPI_MTX_DO_NOT_LOCK);
274         if (ACPI_FAILURE (status)) {
275                 return_ACPI_STATUS (status);
276         }
277
278         /* Clear all fixed and general purpose status bits */
279
280         status = acpi_hw_clear_acpi_status (ACPI_MTX_DO_NOT_LOCK);
281         if (ACPI_FAILURE (status)) {
282                 return_ACPI_STATUS (status);
283         }
284
285         /*
286          * 1) Disable/Clear all GPEs
287          * 2) Enable all wakeup GPEs
288          */
289         status = acpi_hw_disable_all_gpes (ACPI_ISR);
290         if (ACPI_FAILURE (status)) {
291                 return_ACPI_STATUS (status);
292         }
293         acpi_gbl_system_awake_and_running = FALSE;
294
295         status = acpi_hw_enable_all_wakeup_gpes (ACPI_ISR);
296         if (ACPI_FAILURE (status)) {
297                 return_ACPI_STATUS (status);
298         }
299
300         /* Get current value of PM1A control */
301
302         status = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1_CONTROL, &PM1Acontrol);
303         if (ACPI_FAILURE (status)) {
304                 return_ACPI_STATUS (status);
305         }
306         ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "Entering sleep state [S%d]\n", sleep_state));
307
308         /* Clear SLP_EN and SLP_TYP fields */
309
310         PM1Acontrol &= ~(sleep_type_reg_info->access_bit_mask | sleep_enable_reg_info->access_bit_mask);
311         PM1Bcontrol = PM1Acontrol;
312
313         /* Insert SLP_TYP bits */
314
315         PM1Acontrol |= (acpi_gbl_sleep_type_a << sleep_type_reg_info->bit_position);
316         PM1Bcontrol |= (acpi_gbl_sleep_type_b << sleep_type_reg_info->bit_position);
317
318         /*
319          * We split the writes of SLP_TYP and SLP_EN to workaround
320          * poorly implemented hardware.
321          */
322
323         /* Write #1: fill in SLP_TYP data */
324
325         status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1A_CONTROL, PM1Acontrol);
326         if (ACPI_FAILURE (status)) {
327                 return_ACPI_STATUS (status);
328         }
329
330         status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1B_CONTROL, PM1Bcontrol);
331         if (ACPI_FAILURE (status)) {
332                 return_ACPI_STATUS (status);
333         }
334
335         /* Insert SLP_ENABLE bit */
336
337         PM1Acontrol |= sleep_enable_reg_info->access_bit_mask;
338         PM1Bcontrol |= sleep_enable_reg_info->access_bit_mask;
339
340         /* Write #2: SLP_TYP + SLP_EN */
341
342         ACPI_FLUSH_CPU_CACHE ();
343
344         status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1A_CONTROL, PM1Acontrol);
345         if (ACPI_FAILURE (status)) {
346                 return_ACPI_STATUS (status);
347         }
348
349         status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1B_CONTROL, PM1Bcontrol);
350         if (ACPI_FAILURE (status)) {
351                 return_ACPI_STATUS (status);
352         }
353
354         if (sleep_state > ACPI_STATE_S3) {
355                 /*
356                  * We wanted to sleep > S3, but it didn't happen (by virtue of the fact that
357                  * we are still executing!)
358                  *
359                  * Wait ten seconds, then try again. This is to get S4/S5 to work on all machines.
360                  *
361                  * We wait so long to allow chipsets that poll this reg very slowly to
362                  * still read the right value. Ideally, this block would go
363                  * away entirely.
364                  */
365                 acpi_os_stall (10000000);
366
367                 status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1_CONTROL,
368                                  sleep_enable_reg_info->access_bit_mask);
369                 if (ACPI_FAILURE (status)) {
370                         return_ACPI_STATUS (status);
371                 }
372         }
373
374         /* Wait until we enter sleep state */
375
376         do {
377                 status = acpi_get_register (ACPI_BITREG_WAKE_STATUS, &in_value, ACPI_MTX_DO_NOT_LOCK);
378                 if (ACPI_FAILURE (status)) {
379                         return_ACPI_STATUS (status);
380                 }
381
382                 /* Spin until we wake */
383
384         } while (!in_value);
385
386         return_ACPI_STATUS (AE_OK);
387 }
388 EXPORT_SYMBOL(acpi_enter_sleep_state);
389
390
391 /******************************************************************************
392  *
393  * FUNCTION:    acpi_enter_sleep_state_s4bios
394  *
395  * PARAMETERS:  None
396  *
397  * RETURN:      Status
398  *
399  * DESCRIPTION: Perform a S4 bios request.
400  *              THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED
401  *
402  ******************************************************************************/
403
404 acpi_status asmlinkage
405 acpi_enter_sleep_state_s4bios (
406         void)
407 {
408         u32                             in_value;
409         acpi_status                     status;
410
411
412         ACPI_FUNCTION_TRACE ("acpi_enter_sleep_state_s4bios");
413
414
415         status = acpi_set_register (ACPI_BITREG_WAKE_STATUS, 1, ACPI_MTX_DO_NOT_LOCK);
416         if (ACPI_FAILURE (status)) {
417                 return_ACPI_STATUS (status);
418         }
419
420         status = acpi_hw_clear_acpi_status (ACPI_MTX_DO_NOT_LOCK);
421         if (ACPI_FAILURE (status)) {
422                 return_ACPI_STATUS (status);
423         }
424
425         /*
426          * 1) Disable/Clear all GPEs
427          * 2) Enable all wakeup GPEs
428          */
429         status = acpi_hw_disable_all_gpes (ACPI_ISR);
430         if (ACPI_FAILURE (status)) {
431                 return_ACPI_STATUS (status);
432         }
433         acpi_gbl_system_awake_and_running = FALSE;
434
435         status = acpi_hw_enable_all_wakeup_gpes (ACPI_ISR);
436         if (ACPI_FAILURE (status)) {
437                 return_ACPI_STATUS (status);
438         }
439
440         ACPI_FLUSH_CPU_CACHE ();
441
442         status = acpi_os_write_port (acpi_gbl_FADT->smi_cmd, (u32) acpi_gbl_FADT->S4bios_req, 8);
443
444         do {
445                 acpi_os_stall(1000);
446                 status = acpi_get_register (ACPI_BITREG_WAKE_STATUS, &in_value, ACPI_MTX_DO_NOT_LOCK);
447                 if (ACPI_FAILURE (status)) {
448                         return_ACPI_STATUS (status);
449                 }
450         } while (!in_value);
451
452         return_ACPI_STATUS (AE_OK);
453 }
454 EXPORT_SYMBOL(acpi_enter_sleep_state_s4bios);
455
456
457 /******************************************************************************
458  *
459  * FUNCTION:    acpi_leave_sleep_state
460  *
461  * PARAMETERS:  sleep_state         - Which sleep state we just exited
462  *
463  * RETURN:      Status
464  *
465  * DESCRIPTION: Perform OS-independent ACPI cleanup after a sleep
466  *              Called with interrupts ENABLED.
467  *
468  ******************************************************************************/
469
470 acpi_status
471 acpi_leave_sleep_state (
472         u8                              sleep_state)
473 {
474         struct acpi_object_list         arg_list;
475         union acpi_object               arg;
476         acpi_status                     status;
477         struct acpi_bit_register_info   *sleep_type_reg_info;
478         struct acpi_bit_register_info   *sleep_enable_reg_info;
479         u32                             PM1Acontrol;
480         u32                             PM1Bcontrol;
481
482
483         ACPI_FUNCTION_TRACE ("acpi_leave_sleep_state");
484
485
486         /*
487          * Set SLP_TYPE and SLP_EN to state S0.
488          * This is unclear from the ACPI Spec, but it is required
489          * by some machines.
490          */
491         status = acpi_get_sleep_type_data (ACPI_STATE_S0,
492                           &acpi_gbl_sleep_type_a, &acpi_gbl_sleep_type_b);
493         if (ACPI_SUCCESS (status)) {
494                 sleep_type_reg_info = acpi_hw_get_bit_register_info (ACPI_BITREG_SLEEP_TYPE_A);
495                 sleep_enable_reg_info = acpi_hw_get_bit_register_info (ACPI_BITREG_SLEEP_ENABLE);
496
497                 /* Get current value of PM1A control */
498
499                 status = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK,
500                                  ACPI_REGISTER_PM1_CONTROL, &PM1Acontrol);
501                 if (ACPI_SUCCESS (status)) {
502                         /* Clear SLP_EN and SLP_TYP fields */
503
504                         PM1Acontrol &= ~(sleep_type_reg_info->access_bit_mask |
505                                            sleep_enable_reg_info->access_bit_mask);
506                         PM1Bcontrol = PM1Acontrol;
507
508                         /* Insert SLP_TYP bits */
509
510                         PM1Acontrol |= (acpi_gbl_sleep_type_a << sleep_type_reg_info->bit_position);
511                         PM1Bcontrol |= (acpi_gbl_sleep_type_b << sleep_type_reg_info->bit_position);
512
513                         /* Just ignore any errors */
514
515                         (void) acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK,
516                                           ACPI_REGISTER_PM1A_CONTROL, PM1Acontrol);
517                         (void) acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK,
518                                           ACPI_REGISTER_PM1B_CONTROL, PM1Bcontrol);
519                 }
520         }
521
522         /* Ensure enter_sleep_state_prep -> enter_sleep_state ordering */
523
524         acpi_gbl_sleep_type_a = ACPI_SLEEP_TYPE_INVALID;
525
526         /* Setup parameter object */
527
528         arg_list.count = 1;
529         arg_list.pointer = &arg;
530         arg.type = ACPI_TYPE_INTEGER;
531
532         /* Ignore any errors from these methods */
533
534         arg.integer.value = ACPI_SST_WAKING;
535         status = acpi_evaluate_object (NULL, METHOD_NAME__SST, &arg_list, NULL);
536         if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) {
537                 ACPI_REPORT_ERROR (("Method _SST failed, %s\n", acpi_format_exception (status)));
538         }
539
540         arg.integer.value = sleep_state;
541         status = acpi_evaluate_object (NULL, METHOD_NAME__BFS, &arg_list, NULL);
542         if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) {
543                 ACPI_REPORT_ERROR (("Method _BFS failed, %s\n", acpi_format_exception (status)));
544         }
545
546         status = acpi_evaluate_object (NULL, METHOD_NAME__WAK, &arg_list, NULL);
547         if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) {
548                 ACPI_REPORT_ERROR (("Method _WAK failed, %s\n", acpi_format_exception (status)));
549         }
550         /* TBD: _WAK "sometimes" returns stuff - do we want to look at it? */
551
552         /*
553          * Restore the GPEs:
554          * 1) Disable/Clear all GPEs
555          * 2) Enable all runtime GPEs
556          */
557         status = acpi_hw_disable_all_gpes (ACPI_NOT_ISR);
558         if (ACPI_FAILURE (status)) {
559                 return_ACPI_STATUS (status);
560         }
561         acpi_gbl_system_awake_and_running = TRUE;
562
563         status = acpi_hw_enable_all_runtime_gpes (ACPI_NOT_ISR);
564         if (ACPI_FAILURE (status)) {
565                 return_ACPI_STATUS (status);
566         }
567
568         /* Enable power button */
569
570         (void) acpi_set_register(acpi_gbl_fixed_event_info[ACPI_EVENT_POWER_BUTTON].enable_register_id,
571                         1, ACPI_MTX_DO_NOT_LOCK);
572         (void) acpi_set_register(acpi_gbl_fixed_event_info[ACPI_EVENT_POWER_BUTTON].status_register_id,
573                         1, ACPI_MTX_DO_NOT_LOCK);
574
575         arg.integer.value = ACPI_SST_WORKING;
576         status = acpi_evaluate_object (NULL, METHOD_NAME__SST, &arg_list, NULL);
577         if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) {
578                 ACPI_REPORT_ERROR (("Method _SST failed, %s\n", acpi_format_exception (status)));
579         }
580
581         return_ACPI_STATUS (status);
582 }