Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. /******************************************************************************
  2.  *
  3.  * Name: hwesleep.c - ACPI Hardware Sleep/Wake Support functions for the
  4.  *                    extended FADT-V5 sleep registers.
  5.  *
  6.  *****************************************************************************/
  7.  
  8. /*
  9.  * Copyright (C) 2000 - 2015, 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 <linux/acpi.h>
  47. #include "accommon.h"
  48.  
  49. #define _COMPONENT          ACPI_HARDWARE
  50. ACPI_MODULE_NAME("hwesleep")
  51.  
  52. /*******************************************************************************
  53.  *
  54.  * FUNCTION:    acpi_hw_execute_sleep_method
  55.  *
  56.  * PARAMETERS:  method_pathname     - Pathname of method to execute
  57.  *              integer_argument    - Argument to pass to the method
  58.  *
  59.  * RETURN:      None
  60.  *
  61.  * DESCRIPTION: Execute a sleep/wake related method with one integer argument
  62.  *              and no return value.
  63.  *
  64.  ******************************************************************************/
  65. void acpi_hw_execute_sleep_method(char *method_pathname, u32 integer_argument)
  66. {
  67.         struct acpi_object_list arg_list;
  68.         union acpi_object arg;
  69.         acpi_status status;
  70.  
  71.         ACPI_FUNCTION_TRACE(hw_execute_sleep_method);
  72.  
  73.         /* One argument, integer_argument; No return value expected */
  74.  
  75.         arg_list.count = 1;
  76.         arg_list.pointer = &arg;
  77.         arg.type = ACPI_TYPE_INTEGER;
  78.         arg.integer.value = (u64)integer_argument;
  79.  
  80.         status = acpi_evaluate_object(NULL, method_pathname, &arg_list, NULL);
  81.         if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
  82.                 ACPI_EXCEPTION((AE_INFO, status, "While executing method %s",
  83.                                 method_pathname));
  84.         }
  85.  
  86.         return_VOID;
  87. }
  88.  
  89. /*******************************************************************************
  90.  *
  91.  * FUNCTION:    acpi_hw_extended_sleep
  92.  *
  93.  * PARAMETERS:  sleep_state         - Which sleep state to enter
  94.  *
  95.  * RETURN:      Status
  96.  *
  97.  * DESCRIPTION: Enter a system sleep state via the extended FADT sleep
  98.  *              registers (V5 FADT).
  99.  *              THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED
  100.  *
  101.  ******************************************************************************/
  102.  
  103. acpi_status acpi_hw_extended_sleep(u8 sleep_state)
  104. {
  105.         acpi_status status;
  106.         u8 sleep_type_value;
  107.         u64 sleep_status;
  108.  
  109.         ACPI_FUNCTION_TRACE(hw_extended_sleep);
  110.  
  111.         /* Extended sleep registers must be valid */
  112.  
  113.         if (!acpi_gbl_FADT.sleep_control.address ||
  114.             !acpi_gbl_FADT.sleep_status.address) {
  115.                 return_ACPI_STATUS(AE_NOT_EXIST);
  116.         }
  117.  
  118.         /* Clear wake status (WAK_STS) */
  119.  
  120.         status =
  121.             acpi_write((u64)ACPI_X_WAKE_STATUS, &acpi_gbl_FADT.sleep_status);
  122.         if (ACPI_FAILURE(status)) {
  123.                 return_ACPI_STATUS(status);
  124.         }
  125.  
  126.         acpi_gbl_system_awake_and_running = FALSE;
  127.  
  128.         /* Flush caches, as per ACPI specification */
  129.  
  130.         ACPI_FLUSH_CPU_CACHE();
  131.  
  132.         status = acpi_os_prepare_extended_sleep(sleep_state,
  133.                                                 acpi_gbl_sleep_type_a,
  134.                                                 acpi_gbl_sleep_type_b);
  135.         if (ACPI_SKIP(status))
  136.                 return_ACPI_STATUS(AE_OK);
  137.         if (ACPI_FAILURE(status))
  138.                 return_ACPI_STATUS(status);
  139.  
  140.         /*
  141.          * Set the SLP_TYP and SLP_EN bits.
  142.          *
  143.          * Note: We only use the first value returned by the \_Sx method
  144.          * (acpi_gbl_sleep_type_a) - As per ACPI specification.
  145.          */
  146.         ACPI_DEBUG_PRINT((ACPI_DB_INIT,
  147.                           "Entering sleep state [S%u]\n", sleep_state));
  148.  
  149.         sleep_type_value =
  150.             ((acpi_gbl_sleep_type_a << ACPI_X_SLEEP_TYPE_POSITION) &
  151.              ACPI_X_SLEEP_TYPE_MASK);
  152.  
  153.         status = acpi_write((u64)(sleep_type_value | ACPI_X_SLEEP_ENABLE),
  154.                             &acpi_gbl_FADT.sleep_control);
  155.         if (ACPI_FAILURE(status)) {
  156.                 return_ACPI_STATUS(status);
  157.         }
  158.  
  159.         /* Wait for transition back to Working State */
  160.  
  161.         do {
  162.                 status = acpi_read(&sleep_status, &acpi_gbl_FADT.sleep_status);
  163.                 if (ACPI_FAILURE(status)) {
  164.                         return_ACPI_STATUS(status);
  165.                 }
  166.  
  167.         } while (!(((u8)sleep_status) & ACPI_X_WAKE_STATUS));
  168.  
  169.         return_ACPI_STATUS(AE_OK);
  170. }
  171.  
  172. /*******************************************************************************
  173.  *
  174.  * FUNCTION:    acpi_hw_extended_wake_prep
  175.  *
  176.  * PARAMETERS:  sleep_state         - Which sleep state we just exited
  177.  *
  178.  * RETURN:      Status
  179.  *
  180.  * DESCRIPTION: Perform first part of OS-independent ACPI cleanup after
  181.  *              a sleep. Called with interrupts ENABLED.
  182.  *
  183.  ******************************************************************************/
  184.  
  185. acpi_status acpi_hw_extended_wake_prep(u8 sleep_state)
  186. {
  187.         acpi_status status;
  188.         u8 sleep_type_value;
  189.  
  190.         ACPI_FUNCTION_TRACE(hw_extended_wake_prep);
  191.  
  192.         status = acpi_get_sleep_type_data(ACPI_STATE_S0,
  193.                                           &acpi_gbl_sleep_type_a,
  194.                                           &acpi_gbl_sleep_type_b);
  195.         if (ACPI_SUCCESS(status)) {
  196.                 sleep_type_value =
  197.                     ((acpi_gbl_sleep_type_a << ACPI_X_SLEEP_TYPE_POSITION) &
  198.                      ACPI_X_SLEEP_TYPE_MASK);
  199.  
  200.                 (void)acpi_write((u64)(sleep_type_value | ACPI_X_SLEEP_ENABLE),
  201.                                  &acpi_gbl_FADT.sleep_control);
  202.         }
  203.  
  204.         return_ACPI_STATUS(AE_OK);
  205. }
  206.  
  207. /*******************************************************************************
  208.  *
  209.  * FUNCTION:    acpi_hw_extended_wake
  210.  *
  211.  * PARAMETERS:  sleep_state         - Which sleep state we just exited
  212.  *
  213.  * RETURN:      Status
  214.  *
  215.  * DESCRIPTION: Perform OS-independent ACPI cleanup after a sleep
  216.  *              Called with interrupts ENABLED.
  217.  *
  218.  ******************************************************************************/
  219.  
  220. acpi_status acpi_hw_extended_wake(u8 sleep_state)
  221. {
  222.         ACPI_FUNCTION_TRACE(hw_extended_wake);
  223.  
  224.         /* Ensure enter_sleep_state_prep -> enter_sleep_state ordering */
  225.  
  226.         acpi_gbl_sleep_type_a = ACPI_SLEEP_TYPE_INVALID;
  227.  
  228.         /* Execute the wake methods */
  229.  
  230.         acpi_hw_execute_sleep_method(METHOD_PATHNAME__SST, ACPI_SST_WAKING);
  231.         acpi_hw_execute_sleep_method(METHOD_PATHNAME__WAK, sleep_state);
  232.  
  233.         /*
  234.          * Some BIOS code assumes that WAK_STS will be cleared on resume
  235.          * and use it to determine whether the system is rebooting or
  236.          * resuming. Clear WAK_STS for compatibility.
  237.          */
  238.         (void)acpi_write((u64)ACPI_X_WAKE_STATUS, &acpi_gbl_FADT.sleep_status);
  239.         acpi_gbl_system_awake_and_running = TRUE;
  240.  
  241.         acpi_hw_execute_sleep_method(METHOD_PATHNAME__SST, ACPI_SST_WORKING);
  242.         return_ACPI_STATUS(AE_OK);
  243. }
  244.