linux/drivers/acpi/acpica/evxfevnt.c
<<
>>
Prefs
   1/******************************************************************************
   2 *
   3 * Module Name: evxfevnt - External Interfaces, ACPI event disable/enable
   4 *
   5 *****************************************************************************/
   6
   7/*
   8 * Copyright (C) 2000 - 2017, 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#define EXPORT_ACPI_INTERFACES
  45
  46#include <acpi/acpi.h>
  47#include "accommon.h"
  48#include "actables.h"
  49
  50#define _COMPONENT          ACPI_EVENTS
  51ACPI_MODULE_NAME("evxfevnt")
  52
  53#if (!ACPI_REDUCED_HARDWARE)    /* Entire module */
  54/*******************************************************************************
  55 *
  56 * FUNCTION:    acpi_enable
  57 *
  58 * PARAMETERS:  None
  59 *
  60 * RETURN:      Status
  61 *
  62 * DESCRIPTION: Transfers the system into ACPI mode.
  63 *
  64 ******************************************************************************/
  65acpi_status acpi_enable(void)
  66{
  67        acpi_status status;
  68        int retry;
  69
  70        ACPI_FUNCTION_TRACE(acpi_enable);
  71
  72        /* ACPI tables must be present */
  73
  74        if (acpi_gbl_fadt_index == ACPI_INVALID_TABLE_INDEX) {
  75                return_ACPI_STATUS(AE_NO_ACPI_TABLES);
  76        }
  77
  78        /* If the Hardware Reduced flag is set, machine is always in acpi mode */
  79
  80        if (acpi_gbl_reduced_hardware) {
  81                return_ACPI_STATUS(AE_OK);
  82        }
  83
  84        /* Check current mode */
  85
  86        if (acpi_hw_get_mode() == ACPI_SYS_MODE_ACPI) {
  87                ACPI_DEBUG_PRINT((ACPI_DB_INIT,
  88                                  "System is already in ACPI mode\n"));
  89                return_ACPI_STATUS(AE_OK);
  90        }
  91
  92        /* Transition to ACPI mode */
  93
  94        status = acpi_hw_set_mode(ACPI_SYS_MODE_ACPI);
  95        if (ACPI_FAILURE(status)) {
  96                ACPI_ERROR((AE_INFO,
  97                            "Could not transition to ACPI mode"));
  98                return_ACPI_STATUS(status);
  99        }
 100
 101        /* Sanity check that transition succeeded */
 102
 103        for (retry = 0; retry < 30000; ++retry) {
 104                if (acpi_hw_get_mode() == ACPI_SYS_MODE_ACPI) {
 105                        if (retry != 0)
 106                                ACPI_WARNING((AE_INFO,
 107                                "Platform took > %d00 usec to enter ACPI mode", retry));
 108                        return_ACPI_STATUS(AE_OK);
 109                }
 110                acpi_os_stall(100);     /* 100 usec */
 111        }
 112
 113        ACPI_ERROR((AE_INFO, "Hardware did not enter ACPI mode"));
 114        return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE);
 115}
 116
 117ACPI_EXPORT_SYMBOL(acpi_enable)
 118
 119/*******************************************************************************
 120 *
 121 * FUNCTION:    acpi_disable
 122 *
 123 * PARAMETERS:  None
 124 *
 125 * RETURN:      Status
 126 *
 127 * DESCRIPTION: Transfers the system into LEGACY (non-ACPI) mode.
 128 *
 129 ******************************************************************************/
 130acpi_status acpi_disable(void)
 131{
 132        acpi_status status = AE_OK;
 133
 134        ACPI_FUNCTION_TRACE(acpi_disable);
 135
 136        /* If the Hardware Reduced flag is set, machine is always in acpi mode */
 137
 138        if (acpi_gbl_reduced_hardware) {
 139                return_ACPI_STATUS(AE_OK);
 140        }
 141
 142        if (acpi_hw_get_mode() == ACPI_SYS_MODE_LEGACY) {
 143                ACPI_DEBUG_PRINT((ACPI_DB_INIT,
 144                                  "System is already in legacy (non-ACPI) mode\n"));
 145        } else {
 146                /* Transition to LEGACY mode */
 147
 148                status = acpi_hw_set_mode(ACPI_SYS_MODE_LEGACY);
 149
 150                if (ACPI_FAILURE(status)) {
 151                        ACPI_ERROR((AE_INFO,
 152                                    "Could not exit ACPI mode to legacy mode"));
 153                        return_ACPI_STATUS(status);
 154                }
 155
 156                ACPI_DEBUG_PRINT((ACPI_DB_INIT, "ACPI mode disabled\n"));
 157        }
 158
 159        return_ACPI_STATUS(status);
 160}
 161
 162ACPI_EXPORT_SYMBOL(acpi_disable)
 163
 164/*******************************************************************************
 165 *
 166 * FUNCTION:    acpi_enable_event
 167 *
 168 * PARAMETERS:  event           - The fixed eventto be enabled
 169 *              flags           - Reserved
 170 *
 171 * RETURN:      Status
 172 *
 173 * DESCRIPTION: Enable an ACPI event (fixed)
 174 *
 175 ******************************************************************************/
 176acpi_status acpi_enable_event(u32 event, u32 flags)
 177{
 178        acpi_status status = AE_OK;
 179        u32 value;
 180
 181        ACPI_FUNCTION_TRACE(acpi_enable_event);
 182
 183        /* If Hardware Reduced flag is set, there are no fixed events */
 184
 185        if (acpi_gbl_reduced_hardware) {
 186                return_ACPI_STATUS(AE_OK);
 187        }
 188
 189        /* Decode the Fixed Event */
 190
 191        if (event > ACPI_EVENT_MAX) {
 192                return_ACPI_STATUS(AE_BAD_PARAMETER);
 193        }
 194
 195        /*
 196         * Enable the requested fixed event (by writing a one to the enable
 197         * register bit)
 198         */
 199        status =
 200            acpi_write_bit_register(acpi_gbl_fixed_event_info[event].
 201                                    enable_register_id, ACPI_ENABLE_EVENT);
 202        if (ACPI_FAILURE(status)) {
 203                return_ACPI_STATUS(status);
 204        }
 205
 206        /* Make sure that the hardware responded */
 207
 208        status =
 209            acpi_read_bit_register(acpi_gbl_fixed_event_info[event].
 210                                   enable_register_id, &value);
 211        if (ACPI_FAILURE(status)) {
 212                return_ACPI_STATUS(status);
 213        }
 214
 215        if (value != 1) {
 216                ACPI_ERROR((AE_INFO,
 217                            "Could not enable %s event",
 218                            acpi_ut_get_event_name(event)));
 219                return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE);
 220        }
 221
 222        return_ACPI_STATUS(status);
 223}
 224
 225ACPI_EXPORT_SYMBOL(acpi_enable_event)
 226
 227/*******************************************************************************
 228 *
 229 * FUNCTION:    acpi_disable_event
 230 *
 231 * PARAMETERS:  event           - The fixed event to be disabled
 232 *              flags           - Reserved
 233 *
 234 * RETURN:      Status
 235 *
 236 * DESCRIPTION: Disable an ACPI event (fixed)
 237 *
 238 ******************************************************************************/
 239acpi_status acpi_disable_event(u32 event, u32 flags)
 240{
 241        acpi_status status = AE_OK;
 242        u32 value;
 243
 244        ACPI_FUNCTION_TRACE(acpi_disable_event);
 245
 246        /* If Hardware Reduced flag is set, there are no fixed events */
 247
 248        if (acpi_gbl_reduced_hardware) {
 249                return_ACPI_STATUS(AE_OK);
 250        }
 251
 252        /* Decode the Fixed Event */
 253
 254        if (event > ACPI_EVENT_MAX) {
 255                return_ACPI_STATUS(AE_BAD_PARAMETER);
 256        }
 257
 258        /*
 259         * Disable the requested fixed event (by writing a zero to the enable
 260         * register bit)
 261         */
 262        status =
 263            acpi_write_bit_register(acpi_gbl_fixed_event_info[event].
 264                                    enable_register_id, ACPI_DISABLE_EVENT);
 265        if (ACPI_FAILURE(status)) {
 266                return_ACPI_STATUS(status);
 267        }
 268
 269        status =
 270            acpi_read_bit_register(acpi_gbl_fixed_event_info[event].
 271                                   enable_register_id, &value);
 272        if (ACPI_FAILURE(status)) {
 273                return_ACPI_STATUS(status);
 274        }
 275
 276        if (value != 0) {
 277                ACPI_ERROR((AE_INFO,
 278                            "Could not disable %s events",
 279                            acpi_ut_get_event_name(event)));
 280                return_ACPI_STATUS(AE_NO_HARDWARE_RESPONSE);
 281        }
 282
 283        return_ACPI_STATUS(status);
 284}
 285
 286ACPI_EXPORT_SYMBOL(acpi_disable_event)
 287
 288/*******************************************************************************
 289 *
 290 * FUNCTION:    acpi_clear_event
 291 *
 292 * PARAMETERS:  event           - The fixed event to be cleared
 293 *
 294 * RETURN:      Status
 295 *
 296 * DESCRIPTION: Clear an ACPI event (fixed)
 297 *
 298 ******************************************************************************/
 299acpi_status acpi_clear_event(u32 event)
 300{
 301        acpi_status status = AE_OK;
 302
 303        ACPI_FUNCTION_TRACE(acpi_clear_event);
 304
 305        /* If Hardware Reduced flag is set, there are no fixed events */
 306
 307        if (acpi_gbl_reduced_hardware) {
 308                return_ACPI_STATUS(AE_OK);
 309        }
 310
 311        /* Decode the Fixed Event */
 312
 313        if (event > ACPI_EVENT_MAX) {
 314                return_ACPI_STATUS(AE_BAD_PARAMETER);
 315        }
 316
 317        /*
 318         * Clear the requested fixed event (By writing a one to the status
 319         * register bit)
 320         */
 321        status =
 322            acpi_write_bit_register(acpi_gbl_fixed_event_info[event].
 323                                    status_register_id, ACPI_CLEAR_STATUS);
 324
 325        return_ACPI_STATUS(status);
 326}
 327
 328ACPI_EXPORT_SYMBOL(acpi_clear_event)
 329
 330/*******************************************************************************
 331 *
 332 * FUNCTION:    acpi_get_event_status
 333 *
 334 * PARAMETERS:  event           - The fixed event
 335 *              event_status    - Where the current status of the event will
 336 *                                be returned
 337 *
 338 * RETURN:      Status
 339 *
 340 * DESCRIPTION: Obtains and returns the current status of the event
 341 *
 342 ******************************************************************************/
 343acpi_status acpi_get_event_status(u32 event, acpi_event_status * event_status)
 344{
 345        acpi_status status;
 346        acpi_event_status local_event_status = 0;
 347        u32 in_byte;
 348
 349        ACPI_FUNCTION_TRACE(acpi_get_event_status);
 350
 351        if (!event_status) {
 352                return_ACPI_STATUS(AE_BAD_PARAMETER);
 353        }
 354
 355        /* Decode the Fixed Event */
 356
 357        if (event > ACPI_EVENT_MAX) {
 358                return_ACPI_STATUS(AE_BAD_PARAMETER);
 359        }
 360
 361        /* Fixed event currently can be dispatched? */
 362
 363        if (acpi_gbl_fixed_event_handlers[event].handler) {
 364                local_event_status |= ACPI_EVENT_FLAG_HAS_HANDLER;
 365        }
 366
 367        /* Fixed event currently enabled? */
 368
 369        status =
 370            acpi_read_bit_register(acpi_gbl_fixed_event_info[event].
 371                                   enable_register_id, &in_byte);
 372        if (ACPI_FAILURE(status)) {
 373                return_ACPI_STATUS(status);
 374        }
 375
 376        if (in_byte) {
 377                local_event_status |=
 378                    (ACPI_EVENT_FLAG_ENABLED | ACPI_EVENT_FLAG_ENABLE_SET);
 379        }
 380
 381        /* Fixed event currently active? */
 382
 383        status =
 384            acpi_read_bit_register(acpi_gbl_fixed_event_info[event].
 385                                   status_register_id, &in_byte);
 386        if (ACPI_FAILURE(status)) {
 387                return_ACPI_STATUS(status);
 388        }
 389
 390        if (in_byte) {
 391                local_event_status |= ACPI_EVENT_FLAG_STATUS_SET;
 392        }
 393
 394        (*event_status) = local_event_status;
 395        return_ACPI_STATUS(AE_OK);
 396}
 397
 398ACPI_EXPORT_SYMBOL(acpi_get_event_status)
 399#endif                          /* !ACPI_REDUCED_HARDWARE */
 400