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