3467380d2c471ed267b9c8946504243b750517ce
[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 - 2004, 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         if (sleep_state != ACPI_STATE_S5) {
286                 /* Disable BM arbitration */
287
288                 status = acpi_set_register (ACPI_BITREG_ARB_DISABLE, 1, ACPI_MTX_DO_NOT_LOCK);
289                 if (ACPI_FAILURE (status)) {
290                         return_ACPI_STATUS (status);
291                 }
292         }
293
294         /*
295          * 1) Disable/Clear all GPEs
296          * 2) Enable all wakeup GPEs
297          */
298         status = acpi_hw_disable_all_gpes (ACPI_ISR);
299         if (ACPI_FAILURE (status)) {
300                 return_ACPI_STATUS (status);
301         }
302         acpi_gbl_system_awake_and_running = FALSE;
303
304         status = acpi_hw_enable_all_wakeup_gpes (ACPI_ISR);
305         if (ACPI_FAILURE (status)) {
306                 return_ACPI_STATUS (status);
307         }
308
309         /* Get current value of PM1A control */
310
311         status = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1_CONTROL, &PM1Acontrol);
312         if (ACPI_FAILURE (status)) {
313                 return_ACPI_STATUS (status);
314         }
315         ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "Entering sleep state [S%d]\n", sleep_state));
316
317         /* Clear SLP_EN and SLP_TYP fields */
318
319         PM1Acontrol &= ~(sleep_type_reg_info->access_bit_mask | sleep_enable_reg_info->access_bit_mask);
320         PM1Bcontrol = PM1Acontrol;
321
322         /* Insert SLP_TYP bits */
323
324         PM1Acontrol |= (acpi_gbl_sleep_type_a << sleep_type_reg_info->bit_position);
325         PM1Bcontrol |= (acpi_gbl_sleep_type_b << sleep_type_reg_info->bit_position);
326
327         /*
328          * We split the writes of SLP_TYP and SLP_EN to workaround
329          * poorly implemented hardware.
330          */
331
332         /* Write #1: fill in SLP_TYP data */
333
334         status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1A_CONTROL, PM1Acontrol);
335         if (ACPI_FAILURE (status)) {
336                 return_ACPI_STATUS (status);
337         }
338
339         status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1B_CONTROL, PM1Bcontrol);
340         if (ACPI_FAILURE (status)) {
341                 return_ACPI_STATUS (status);
342         }
343
344         /* Insert SLP_ENABLE bit */
345
346         PM1Acontrol |= sleep_enable_reg_info->access_bit_mask;
347         PM1Bcontrol |= sleep_enable_reg_info->access_bit_mask;
348
349         /* Write #2: SLP_TYP + SLP_EN */
350
351         ACPI_FLUSH_CPU_CACHE ();
352
353         status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1A_CONTROL, PM1Acontrol);
354         if (ACPI_FAILURE (status)) {
355                 return_ACPI_STATUS (status);
356         }
357
358         status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1B_CONTROL, PM1Bcontrol);
359         if (ACPI_FAILURE (status)) {
360                 return_ACPI_STATUS (status);
361         }
362
363         if (sleep_state > ACPI_STATE_S3) {
364                 /*
365                  * We wanted to sleep > S3, but it didn't happen (by virtue of the fact that
366                  * we are still executing!)
367                  *
368                  * Wait ten seconds, then try again. This is to get S4/S5 to work on all machines.
369                  *
370                  * We wait so long to allow chipsets that poll this reg very slowly to
371                  * still read the right value. Ideally, this block would go
372                  * away entirely.
373                  */
374                 acpi_os_stall (10000000);
375
376                 status = acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1_CONTROL,
377                                  sleep_enable_reg_info->access_bit_mask);
378                 if (ACPI_FAILURE (status)) {
379                         return_ACPI_STATUS (status);
380                 }
381         }
382
383         /* Wait until we enter sleep state */
384
385         do {
386                 status = acpi_get_register (ACPI_BITREG_WAKE_STATUS, &in_value, ACPI_MTX_DO_NOT_LOCK);
387                 if (ACPI_FAILURE (status)) {
388                         return_ACPI_STATUS (status);
389                 }
390
391                 /* Spin until we wake */
392
393         } while (!in_value);
394
395         return_ACPI_STATUS (AE_OK);
396 }
397 EXPORT_SYMBOL(acpi_enter_sleep_state);
398
399
400 /******************************************************************************
401  *
402  * FUNCTION:    acpi_enter_sleep_state_s4bios
403  *
404  * PARAMETERS:  None
405  *
406  * RETURN:      Status
407  *
408  * DESCRIPTION: Perform a S4 bios request.
409  *              THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED
410  *
411  ******************************************************************************/
412
413 acpi_status asmlinkage
414 acpi_enter_sleep_state_s4bios (
415         void)
416 {
417         u32                             in_value;
418         acpi_status                     status;
419
420
421         ACPI_FUNCTION_TRACE ("acpi_enter_sleep_state_s4bios");
422
423
424         status = acpi_set_register (ACPI_BITREG_WAKE_STATUS, 1, ACPI_MTX_DO_NOT_LOCK);
425         if (ACPI_FAILURE (status)) {
426                 return_ACPI_STATUS (status);
427         }
428
429         status = acpi_hw_clear_acpi_status (ACPI_MTX_DO_NOT_LOCK);
430         if (ACPI_FAILURE (status)) {
431                 return_ACPI_STATUS (status);
432         }
433
434         /*
435          * 1) Disable/Clear all GPEs
436          * 2) Enable all wakeup GPEs
437          */
438         status = acpi_hw_disable_all_gpes (ACPI_ISR);
439         if (ACPI_FAILURE (status)) {
440                 return_ACPI_STATUS (status);
441         }
442         acpi_gbl_system_awake_and_running = FALSE;
443
444         status = acpi_hw_enable_all_wakeup_gpes (ACPI_ISR);
445         if (ACPI_FAILURE (status)) {
446                 return_ACPI_STATUS (status);
447         }
448
449         ACPI_FLUSH_CPU_CACHE ();
450
451         status = acpi_os_write_port (acpi_gbl_FADT->smi_cmd, (u32) acpi_gbl_FADT->S4bios_req, 8);
452
453         do {
454                 acpi_os_stall(1000);
455                 status = acpi_get_register (ACPI_BITREG_WAKE_STATUS, &in_value, ACPI_MTX_DO_NOT_LOCK);
456                 if (ACPI_FAILURE (status)) {
457                         return_ACPI_STATUS (status);
458                 }
459         } while (!in_value);
460
461         return_ACPI_STATUS (AE_OK);
462 }
463 EXPORT_SYMBOL(acpi_enter_sleep_state_s4bios);
464
465
466 /******************************************************************************
467  *
468  * FUNCTION:    acpi_leave_sleep_state
469  *
470  * PARAMETERS:  sleep_state         - Which sleep state we just exited
471  *
472  * RETURN:      Status
473  *
474  * DESCRIPTION: Perform OS-independent ACPI cleanup after a sleep
475  *              Called with interrupts ENABLED.
476  *
477  ******************************************************************************/
478
479 acpi_status
480 acpi_leave_sleep_state (
481         u8                              sleep_state)
482 {
483         struct acpi_object_list         arg_list;
484         union acpi_object               arg;
485         acpi_status                     status;
486         struct acpi_bit_register_info   *sleep_type_reg_info;
487         struct acpi_bit_register_info   *sleep_enable_reg_info;
488         u32                             PM1Acontrol;
489         u32                             PM1Bcontrol;
490
491
492         ACPI_FUNCTION_TRACE ("acpi_leave_sleep_state");
493
494
495         /*
496          * Set SLP_TYPE and SLP_EN to state S0.
497          * This is unclear from the ACPI Spec, but it is required
498          * by some machines.
499          */
500         status = acpi_get_sleep_type_data (ACPI_STATE_S0,
501                           &acpi_gbl_sleep_type_a, &acpi_gbl_sleep_type_b);
502         if (ACPI_SUCCESS (status)) {
503                 sleep_type_reg_info = acpi_hw_get_bit_register_info (ACPI_BITREG_SLEEP_TYPE_A);
504                 sleep_enable_reg_info = acpi_hw_get_bit_register_info (ACPI_BITREG_SLEEP_ENABLE);
505
506                 /* Get current value of PM1A control */
507
508                 status = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK,
509                                  ACPI_REGISTER_PM1_CONTROL, &PM1Acontrol);
510                 if (ACPI_SUCCESS (status)) {
511                         /* Clear SLP_EN and SLP_TYP fields */
512
513                         PM1Acontrol &= ~(sleep_type_reg_info->access_bit_mask |
514                                            sleep_enable_reg_info->access_bit_mask);
515                         PM1Bcontrol = PM1Acontrol;
516
517                         /* Insert SLP_TYP bits */
518
519                         PM1Acontrol |= (acpi_gbl_sleep_type_a << sleep_type_reg_info->bit_position);
520                         PM1Bcontrol |= (acpi_gbl_sleep_type_b << sleep_type_reg_info->bit_position);
521
522                         /* Just ignore any errors */
523
524                         (void) acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK,
525                                           ACPI_REGISTER_PM1A_CONTROL, PM1Acontrol);
526                         (void) acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK,
527                                           ACPI_REGISTER_PM1B_CONTROL, PM1Bcontrol);
528                 }
529         }
530
531         /* Ensure enter_sleep_state_prep -> enter_sleep_state ordering */
532
533         acpi_gbl_sleep_type_a = ACPI_SLEEP_TYPE_INVALID;
534
535         /* Setup parameter object */
536
537         arg_list.count = 1;
538         arg_list.pointer = &arg;
539         arg.type = ACPI_TYPE_INTEGER;
540
541         /* Ignore any errors from these methods */
542
543         arg.integer.value = ACPI_SST_WAKING;
544         status = acpi_evaluate_object (NULL, METHOD_NAME__SST, &arg_list, NULL);
545         if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) {
546                 ACPI_REPORT_ERROR (("Method _SST failed, %s\n", acpi_format_exception (status)));
547         }
548
549         arg.integer.value = sleep_state;
550         status = acpi_evaluate_object (NULL, METHOD_NAME__BFS, &arg_list, NULL);
551         if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) {
552                 ACPI_REPORT_ERROR (("Method _BFS failed, %s\n", acpi_format_exception (status)));
553         }
554
555         status = acpi_evaluate_object (NULL, METHOD_NAME__WAK, &arg_list, NULL);
556         if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) {
557                 ACPI_REPORT_ERROR (("Method _WAK failed, %s\n", acpi_format_exception (status)));
558         }
559         /* TBD: _WAK "sometimes" returns stuff - do we want to look at it? */
560
561         /*
562          * Restore the GPEs:
563          * 1) Disable/Clear all GPEs
564          * 2) Enable all runtime GPEs
565          */
566         status = acpi_hw_disable_all_gpes (ACPI_NOT_ISR);
567         if (ACPI_FAILURE (status)) {
568                 return_ACPI_STATUS (status);
569         }
570         acpi_gbl_system_awake_and_running = TRUE;
571
572         status = acpi_hw_enable_all_runtime_gpes (ACPI_NOT_ISR);
573         if (ACPI_FAILURE (status)) {
574                 return_ACPI_STATUS (status);
575         }
576
577         /* Enable power button */
578
579         (void) acpi_set_register(acpi_gbl_fixed_event_info[ACPI_EVENT_POWER_BUTTON].enable_register_id,
580                         1, ACPI_MTX_DO_NOT_LOCK);
581         (void) acpi_set_register(acpi_gbl_fixed_event_info[ACPI_EVENT_POWER_BUTTON].status_register_id,
582                         1, ACPI_MTX_DO_NOT_LOCK);
583
584         /* Enable BM arbitration */
585
586         status = acpi_set_register (ACPI_BITREG_ARB_DISABLE, 0, ACPI_MTX_LOCK);
587         if (ACPI_FAILURE (status)) {
588                 return_ACPI_STATUS (status);
589         }
590
591         arg.integer.value = ACPI_SST_WORKING;
592         status = acpi_evaluate_object (NULL, METHOD_NAME__SST, &arg_list, NULL);
593         if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) {
594                 ACPI_REPORT_ERROR (("Method _SST failed, %s\n", acpi_format_exception (status)));
595         }
596
597         return_ACPI_STATUS (status);
598 }