linux/drivers/acpi/acpica/exsystem.c
<<
>>
Prefs
   1/******************************************************************************
   2 *
   3 * Module Name: exsystem - Interface to OS services
   4 *
   5 *****************************************************************************/
   6
   7/*
   8 * Copyright (C) 2000 - 2016, 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#include <acpi/acpi.h>
  45#include "accommon.h"
  46#include "acinterp.h"
  47
  48#define _COMPONENT          ACPI_EXECUTER
  49ACPI_MODULE_NAME("exsystem")
  50
  51/*******************************************************************************
  52 *
  53 * FUNCTION:    acpi_ex_system_wait_semaphore
  54 *
  55 * PARAMETERS:  semaphore       - Semaphore to wait on
  56 *              timeout         - Max time to wait
  57 *
  58 * RETURN:      Status
  59 *
  60 * DESCRIPTION: Implements a semaphore wait with a check to see if the
  61 *              semaphore is available immediately. If it is not, the
  62 *              interpreter is released before waiting.
  63 *
  64 ******************************************************************************/
  65acpi_status acpi_ex_system_wait_semaphore(acpi_semaphore semaphore, u16 timeout)
  66{
  67        acpi_status status;
  68
  69        ACPI_FUNCTION_TRACE(ex_system_wait_semaphore);
  70
  71        status = acpi_os_wait_semaphore(semaphore, 1, ACPI_DO_NOT_WAIT);
  72        if (ACPI_SUCCESS(status)) {
  73                return_ACPI_STATUS(status);
  74        }
  75
  76        if (status == AE_TIME) {
  77
  78                /* We must wait, so unlock the interpreter */
  79
  80                acpi_ex_exit_interpreter();
  81                status = acpi_os_wait_semaphore(semaphore, 1, timeout);
  82
  83                ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
  84                                  "*** Thread awake after blocking, %s\n",
  85                                  acpi_format_exception(status)));
  86
  87                /* Reacquire the interpreter */
  88
  89                acpi_ex_enter_interpreter();
  90        }
  91
  92        return_ACPI_STATUS(status);
  93}
  94
  95/*******************************************************************************
  96 *
  97 * FUNCTION:    acpi_ex_system_wait_mutex
  98 *
  99 * PARAMETERS:  mutex           - Mutex to wait on
 100 *              timeout         - Max time to wait
 101 *
 102 * RETURN:      Status
 103 *
 104 * DESCRIPTION: Implements a mutex wait with a check to see if the
 105 *              mutex is available immediately. If it is not, the
 106 *              interpreter is released before waiting.
 107 *
 108 ******************************************************************************/
 109
 110acpi_status acpi_ex_system_wait_mutex(acpi_mutex mutex, u16 timeout)
 111{
 112        acpi_status status;
 113
 114        ACPI_FUNCTION_TRACE(ex_system_wait_mutex);
 115
 116        status = acpi_os_acquire_mutex(mutex, ACPI_DO_NOT_WAIT);
 117        if (ACPI_SUCCESS(status)) {
 118                return_ACPI_STATUS(status);
 119        }
 120
 121        if (status == AE_TIME) {
 122
 123                /* We must wait, so unlock the interpreter */
 124
 125                acpi_ex_exit_interpreter();
 126                status = acpi_os_acquire_mutex(mutex, timeout);
 127
 128                ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
 129                                  "*** Thread awake after blocking, %s\n",
 130                                  acpi_format_exception(status)));
 131
 132                /* Reacquire the interpreter */
 133
 134                acpi_ex_enter_interpreter();
 135        }
 136
 137        return_ACPI_STATUS(status);
 138}
 139
 140/*******************************************************************************
 141 *
 142 * FUNCTION:    acpi_ex_system_do_stall
 143 *
 144 * PARAMETERS:  how_long        - The amount of time to stall,
 145 *                                in microseconds
 146 *
 147 * RETURN:      Status
 148 *
 149 * DESCRIPTION: Suspend running thread for specified amount of time.
 150 *              Note: ACPI specification requires that Stall() does not
 151 *              relinquish the processor, and delays longer than 100 usec
 152 *              should use Sleep() instead. We allow stalls up to 255 usec
 153 *              for compatibility with other interpreters and existing BIOSs.
 154 *
 155 ******************************************************************************/
 156
 157acpi_status acpi_ex_system_do_stall(u32 how_long)
 158{
 159        acpi_status status = AE_OK;
 160
 161        ACPI_FUNCTION_ENTRY();
 162
 163        if (how_long > 255) {   /* 255 microseconds */
 164                /*
 165                 * Longer than 255 usec, this is an error
 166                 *
 167                 * (ACPI specifies 100 usec as max, but this gives some slack in
 168                 * order to support existing BIOSs)
 169                 */
 170                ACPI_ERROR((AE_INFO,
 171                            "Time parameter is too large (%u)", how_long));
 172                status = AE_AML_OPERAND_VALUE;
 173        } else {
 174                acpi_os_stall(how_long);
 175        }
 176
 177        return (status);
 178}
 179
 180/*******************************************************************************
 181 *
 182 * FUNCTION:    acpi_ex_system_do_sleep
 183 *
 184 * PARAMETERS:  how_long        - The amount of time to sleep,
 185 *                                in milliseconds
 186 *
 187 * RETURN:      None
 188 *
 189 * DESCRIPTION: Sleep the running thread for specified amount of time.
 190 *
 191 ******************************************************************************/
 192
 193acpi_status acpi_ex_system_do_sleep(u64 how_long)
 194{
 195        ACPI_FUNCTION_ENTRY();
 196
 197        /* Since this thread will sleep, we must release the interpreter */
 198
 199        acpi_ex_exit_interpreter();
 200
 201        /*
 202         * For compatibility with other ACPI implementations and to prevent
 203         * accidental deep sleeps, limit the sleep time to something reasonable.
 204         */
 205        if (how_long > ACPI_MAX_SLEEP) {
 206                how_long = ACPI_MAX_SLEEP;
 207        }
 208
 209        acpi_os_sleep(how_long);
 210
 211        /* And now we must get the interpreter again */
 212
 213        acpi_ex_enter_interpreter();
 214        return (AE_OK);
 215}
 216
 217/*******************************************************************************
 218 *
 219 * FUNCTION:    acpi_ex_system_signal_event
 220 *
 221 * PARAMETERS:  obj_desc        - The object descriptor for this op
 222 *
 223 * RETURN:      Status
 224 *
 225 * DESCRIPTION: Provides an access point to perform synchronization operations
 226 *              within the AML.
 227 *
 228 ******************************************************************************/
 229
 230acpi_status acpi_ex_system_signal_event(union acpi_operand_object * obj_desc)
 231{
 232        acpi_status status = AE_OK;
 233
 234        ACPI_FUNCTION_TRACE(ex_system_signal_event);
 235
 236        if (obj_desc) {
 237                status =
 238                    acpi_os_signal_semaphore(obj_desc->event.os_semaphore, 1);
 239        }
 240
 241        return_ACPI_STATUS(status);
 242}
 243
 244/*******************************************************************************
 245 *
 246 * FUNCTION:    acpi_ex_system_wait_event
 247 *
 248 * PARAMETERS:  time_desc       - The 'time to delay' object descriptor
 249 *              obj_desc        - The object descriptor for this op
 250 *
 251 * RETURN:      Status
 252 *
 253 * DESCRIPTION: Provides an access point to perform synchronization operations
 254 *              within the AML. This operation is a request to wait for an
 255 *              event.
 256 *
 257 ******************************************************************************/
 258
 259acpi_status
 260acpi_ex_system_wait_event(union acpi_operand_object *time_desc,
 261                          union acpi_operand_object *obj_desc)
 262{
 263        acpi_status status = AE_OK;
 264
 265        ACPI_FUNCTION_TRACE(ex_system_wait_event);
 266
 267        if (obj_desc) {
 268                status =
 269                    acpi_ex_system_wait_semaphore(obj_desc->event.os_semaphore,
 270                                                  (u16) time_desc->integer.
 271                                                  value);
 272        }
 273
 274        return_ACPI_STATUS(status);
 275}
 276
 277/*******************************************************************************
 278 *
 279 * FUNCTION:    acpi_ex_system_reset_event
 280 *
 281 * PARAMETERS:  obj_desc        - The object descriptor for this op
 282 *
 283 * RETURN:      Status
 284 *
 285 * DESCRIPTION: Reset an event to a known state.
 286 *
 287 ******************************************************************************/
 288
 289acpi_status acpi_ex_system_reset_event(union acpi_operand_object *obj_desc)
 290{
 291        acpi_status status = AE_OK;
 292        acpi_semaphore temp_semaphore;
 293
 294        ACPI_FUNCTION_ENTRY();
 295
 296        /*
 297         * We are going to simply delete the existing semaphore and
 298         * create a new one!
 299         */
 300        status =
 301            acpi_os_create_semaphore(ACPI_NO_UNIT_LIMIT, 0, &temp_semaphore);
 302        if (ACPI_SUCCESS(status)) {
 303                (void)acpi_os_delete_semaphore(obj_desc->event.os_semaphore);
 304                obj_desc->event.os_semaphore = temp_semaphore;
 305        }
 306
 307        return (status);
 308}
 309