linux/drivers/acpi/acpica/evxfgpe.c
<<
>>
Prefs
   1/******************************************************************************
   2 *
   3 * Module Name: evxfgpe - External Interfaces for General Purpose Events (GPEs)
   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 "acevents.h"
  49#include "acnamesp.h"
  50
  51#define _COMPONENT          ACPI_EVENTS
  52ACPI_MODULE_NAME("evxfgpe")
  53
  54#if (!ACPI_REDUCED_HARDWARE)    /* Entire module */
  55/*******************************************************************************
  56 *
  57 * FUNCTION:    acpi_update_all_gpes
  58 *
  59 * PARAMETERS:  None
  60 *
  61 * RETURN:      Status
  62 *
  63 * DESCRIPTION: Complete GPE initialization and enable all GPEs that have
  64 *              associated _Lxx or _Exx methods and are not pointed to by any
  65 *              device _PRW methods (this indicates that these GPEs are
  66 *              generally intended for system or device wakeup. Such GPEs
  67 *              have to be enabled directly when the devices whose _PRW
  68 *              methods point to them are set up for wakeup signaling.)
  69 *
  70 * NOTE: Should be called after any GPEs are added to the system. Primarily,
  71 * after the system _PRW methods have been run, but also after a GPE Block
  72 * Device has been added or if any new GPE methods have been added via a
  73 * dynamic table load.
  74 *
  75 ******************************************************************************/
  76
  77acpi_status acpi_update_all_gpes(void)
  78{
  79        acpi_status status;
  80
  81        ACPI_FUNCTION_TRACE(acpi_update_all_gpes);
  82
  83        status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
  84        if (ACPI_FAILURE(status)) {
  85                return_ACPI_STATUS(status);
  86        }
  87
  88        if (acpi_gbl_all_gpes_initialized) {
  89                goto unlock_and_exit;
  90        }
  91
  92        status = acpi_ev_walk_gpe_list(acpi_ev_initialize_gpe_block, NULL);
  93        if (ACPI_SUCCESS(status)) {
  94                acpi_gbl_all_gpes_initialized = TRUE;
  95        }
  96
  97unlock_and_exit:
  98        (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
  99
 100        return_ACPI_STATUS(status);
 101}
 102
 103ACPI_EXPORT_SYMBOL(acpi_update_all_gpes)
 104
 105/*******************************************************************************
 106 *
 107 * FUNCTION:    acpi_enable_gpe
 108 *
 109 * PARAMETERS:  gpe_device          - Parent GPE Device. NULL for GPE0/GPE1
 110 *              gpe_number          - GPE level within the GPE block
 111 *
 112 * RETURN:      Status
 113 *
 114 * DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is
 115 *              hardware-enabled.
 116 *
 117 ******************************************************************************/
 118acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number)
 119{
 120        acpi_status status = AE_BAD_PARAMETER;
 121        struct acpi_gpe_event_info *gpe_event_info;
 122        acpi_cpu_flags flags;
 123
 124        ACPI_FUNCTION_TRACE(acpi_enable_gpe);
 125
 126        flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
 127
 128        /*
 129         * Ensure that we have a valid GPE number and that there is some way
 130         * of handling the GPE (handler or a GPE method). In other words, we
 131         * won't allow a valid GPE to be enabled if there is no way to handle it.
 132         */
 133        gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
 134        if (gpe_event_info) {
 135                if (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) !=
 136                    ACPI_GPE_DISPATCH_NONE) {
 137                        status = acpi_ev_add_gpe_reference(gpe_event_info);
 138                } else {
 139                        status = AE_NO_HANDLER;
 140                }
 141        }
 142
 143        acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
 144        return_ACPI_STATUS(status);
 145}
 146ACPI_EXPORT_SYMBOL(acpi_enable_gpe)
 147
 148/*******************************************************************************
 149 *
 150 * FUNCTION:    acpi_disable_gpe
 151 *
 152 * PARAMETERS:  gpe_device      - Parent GPE Device. NULL for GPE0/GPE1
 153 *              gpe_number      - GPE level within the GPE block
 154 *
 155 * RETURN:      Status
 156 *
 157 * DESCRIPTION: Remove a reference to a GPE. When the last reference is
 158 *              removed, only then is the GPE disabled (for runtime GPEs), or
 159 *              the GPE mask bit disabled (for wake GPEs)
 160 *
 161 ******************************************************************************/
 162
 163acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number)
 164{
 165        acpi_status status = AE_BAD_PARAMETER;
 166        struct acpi_gpe_event_info *gpe_event_info;
 167        acpi_cpu_flags flags;
 168
 169        ACPI_FUNCTION_TRACE(acpi_disable_gpe);
 170
 171        flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
 172
 173        /* Ensure that we have a valid GPE number */
 174
 175        gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
 176        if (gpe_event_info) {
 177                status = acpi_ev_remove_gpe_reference(gpe_event_info) ;
 178        }
 179
 180        acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
 181        return_ACPI_STATUS(status);
 182}
 183
 184ACPI_EXPORT_SYMBOL(acpi_disable_gpe)
 185
 186/*******************************************************************************
 187 *
 188 * FUNCTION:    acpi_set_gpe
 189 *
 190 * PARAMETERS:  gpe_device          - Parent GPE Device. NULL for GPE0/GPE1
 191 *              gpe_number          - GPE level within the GPE block
 192 *              action              - ACPI_GPE_ENABLE or ACPI_GPE_DISABLE
 193 *
 194 * RETURN:      Status
 195 *
 196 * DESCRIPTION: Enable or disable an individual GPE. This function bypasses
 197 *              the reference count mechanism used in the acpi_enable_gpe(),
 198 *              acpi_disable_gpe() interfaces.
 199 *              This API is typically used by the GPE raw handler mode driver
 200 *              to switch between the polling mode and the interrupt mode after
 201 *              the driver has enabled the GPE.
 202 *              The APIs should be invoked in this order:
 203 *               acpi_enable_gpe()            <- Ensure the reference count > 0
 204 *               acpi_set_gpe(ACPI_GPE_DISABLE) <- Enter polling mode
 205 *               acpi_set_gpe(ACPI_GPE_ENABLE) <- Leave polling mode
 206 *               acpi_disable_gpe()           <- Decrease the reference count
 207 *
 208 * Note: If a GPE is shared by 2 silicon components, then both the drivers
 209 *       should support GPE polling mode or disabling the GPE for long period
 210 *       for one driver may break the other. So use it with care since all
 211 *       firmware _Lxx/_Exx handlers currently rely on the GPE interrupt mode.
 212 *
 213 ******************************************************************************/
 214acpi_status acpi_set_gpe(acpi_handle gpe_device, u32 gpe_number, u8 action)
 215{
 216        struct acpi_gpe_event_info *gpe_event_info;
 217        acpi_status status;
 218        acpi_cpu_flags flags;
 219
 220        ACPI_FUNCTION_TRACE(acpi_set_gpe);
 221
 222        flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
 223
 224        /* Ensure that we have a valid GPE number */
 225
 226        gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
 227        if (!gpe_event_info) {
 228                status = AE_BAD_PARAMETER;
 229                goto unlock_and_exit;
 230        }
 231
 232        /* Perform the action */
 233
 234        switch (action) {
 235        case ACPI_GPE_ENABLE:
 236
 237                status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_ENABLE);
 238                gpe_event_info->disable_for_dispatch = FALSE;
 239                break;
 240
 241        case ACPI_GPE_DISABLE:
 242
 243                status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_DISABLE);
 244                gpe_event_info->disable_for_dispatch = TRUE;
 245                break;
 246
 247        default:
 248
 249                status = AE_BAD_PARAMETER;
 250                break;
 251        }
 252
 253unlock_and_exit:
 254        acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
 255        return_ACPI_STATUS(status);
 256}
 257
 258ACPI_EXPORT_SYMBOL(acpi_set_gpe)
 259
 260/*******************************************************************************
 261 *
 262 * FUNCTION:    acpi_mask_gpe
 263 *
 264 * PARAMETERS:  gpe_device          - Parent GPE Device. NULL for GPE0/GPE1
 265 *              gpe_number          - GPE level within the GPE block
 266 *              is_masked           - Whether the GPE is masked or not
 267 *
 268 * RETURN:      Status
 269 *
 270 * DESCRIPTION: Unconditionally mask/unmask the an individual GPE, ex., to
 271 *              prevent a GPE flooding.
 272 *
 273 ******************************************************************************/
 274acpi_status acpi_mask_gpe(acpi_handle gpe_device, u32 gpe_number, u8 is_masked)
 275{
 276        struct acpi_gpe_event_info *gpe_event_info;
 277        acpi_status status;
 278        acpi_cpu_flags flags;
 279
 280        ACPI_FUNCTION_TRACE(acpi_mask_gpe);
 281
 282        flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
 283
 284        /* Ensure that we have a valid GPE number */
 285
 286        gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
 287        if (!gpe_event_info) {
 288                status = AE_BAD_PARAMETER;
 289                goto unlock_and_exit;
 290        }
 291
 292        status = acpi_ev_mask_gpe(gpe_event_info, is_masked);
 293
 294unlock_and_exit:
 295        acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
 296        return_ACPI_STATUS(status);
 297}
 298
 299ACPI_EXPORT_SYMBOL(acpi_mask_gpe)
 300
 301/*******************************************************************************
 302 *
 303 * FUNCTION:    acpi_mark_gpe_for_wake
 304 *
 305 * PARAMETERS:  gpe_device          - Parent GPE Device. NULL for GPE0/GPE1
 306 *              gpe_number          - GPE level within the GPE block
 307 *
 308 * RETURN:      Status
 309 *
 310 * DESCRIPTION: Mark a GPE as having the ability to wake the system. Simply
 311 *              sets the ACPI_GPE_CAN_WAKE flag.
 312 *
 313 * Some potential callers of acpi_setup_gpe_for_wake may know in advance that
 314 * there won't be any notify handlers installed for device wake notifications
 315 * from the given GPE (one example is a button GPE in Linux). For these cases,
 316 * acpi_mark_gpe_for_wake should be used instead of acpi_setup_gpe_for_wake.
 317 * This will set the ACPI_GPE_CAN_WAKE flag for the GPE without trying to
 318 * setup implicit wake notification for it (since there's no handler method).
 319 *
 320 ******************************************************************************/
 321acpi_status acpi_mark_gpe_for_wake(acpi_handle gpe_device, u32 gpe_number)
 322{
 323        struct acpi_gpe_event_info *gpe_event_info;
 324        acpi_status status = AE_BAD_PARAMETER;
 325        acpi_cpu_flags flags;
 326
 327        ACPI_FUNCTION_TRACE(acpi_mark_gpe_for_wake);
 328
 329        flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
 330
 331        /* Ensure that we have a valid GPE number */
 332
 333        gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
 334        if (gpe_event_info) {
 335
 336                /* Mark the GPE as a possible wake event */
 337
 338                gpe_event_info->flags |= ACPI_GPE_CAN_WAKE;
 339                status = AE_OK;
 340        }
 341
 342        acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
 343        return_ACPI_STATUS(status);
 344}
 345
 346ACPI_EXPORT_SYMBOL(acpi_mark_gpe_for_wake)
 347
 348/*******************************************************************************
 349 *
 350 * FUNCTION:    acpi_setup_gpe_for_wake
 351 *
 352 * PARAMETERS:  wake_device         - Device associated with the GPE (via _PRW)
 353 *              gpe_device          - Parent GPE Device. NULL for GPE0/GPE1
 354 *              gpe_number          - GPE level within the GPE block
 355 *
 356 * RETURN:      Status
 357 *
 358 * DESCRIPTION: Mark a GPE as having the ability to wake the system. This
 359 *              interface is intended to be used as the host executes the
 360 *              _PRW methods (Power Resources for Wake) in the system tables.
 361 *              Each _PRW appears under a Device Object (The wake_device), and
 362 *              contains the info for the wake GPE associated with the
 363 *              wake_device.
 364 *
 365 ******************************************************************************/
 366acpi_status
 367acpi_setup_gpe_for_wake(acpi_handle wake_device,
 368                        acpi_handle gpe_device, u32 gpe_number)
 369{
 370        acpi_status status;
 371        struct acpi_gpe_event_info *gpe_event_info;
 372        struct acpi_namespace_node *device_node;
 373        struct acpi_gpe_notify_info *notify;
 374        struct acpi_gpe_notify_info *new_notify;
 375        acpi_cpu_flags flags;
 376
 377        ACPI_FUNCTION_TRACE(acpi_setup_gpe_for_wake);
 378
 379        /* Parameter Validation */
 380
 381        if (!wake_device) {
 382                /*
 383                 * By forcing wake_device to be valid, we automatically enable the
 384                 * implicit notify feature on all hosts.
 385                 */
 386                return_ACPI_STATUS(AE_BAD_PARAMETER);
 387        }
 388
 389        /* Handle root object case */
 390
 391        if (wake_device == ACPI_ROOT_OBJECT) {
 392                device_node = acpi_gbl_root_node;
 393        } else {
 394                device_node =
 395                    ACPI_CAST_PTR(struct acpi_namespace_node, wake_device);
 396        }
 397
 398        /* Validate wake_device is of type Device */
 399
 400        if (device_node->type != ACPI_TYPE_DEVICE) {
 401                return_ACPI_STATUS (AE_BAD_PARAMETER);
 402        }
 403
 404        /*
 405         * Allocate a new notify object up front, in case it is needed.
 406         * Memory allocation while holding a spinlock is a big no-no
 407         * on some hosts.
 408         */
 409        new_notify = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_gpe_notify_info));
 410        if (!new_notify) {
 411                return_ACPI_STATUS(AE_NO_MEMORY);
 412        }
 413
 414        flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
 415
 416        /* Ensure that we have a valid GPE number */
 417
 418        gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
 419        if (!gpe_event_info) {
 420                status = AE_BAD_PARAMETER;
 421                goto unlock_and_exit;
 422        }
 423
 424        /*
 425         * If there is no method or handler for this GPE, then the
 426         * wake_device will be notified whenever this GPE fires. This is
 427         * known as an "implicit notify". Note: The GPE is assumed to be
 428         * level-triggered (for windows compatibility).
 429         */
 430        if (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) ==
 431            ACPI_GPE_DISPATCH_NONE) {
 432                /*
 433                 * This is the first device for implicit notify on this GPE.
 434                 * Just set the flags here, and enter the NOTIFY block below.
 435                 */
 436                gpe_event_info->flags =
 437                    (ACPI_GPE_DISPATCH_NOTIFY | ACPI_GPE_LEVEL_TRIGGERED);
 438        } else if (gpe_event_info->flags & ACPI_GPE_AUTO_ENABLED) {
 439                /*
 440                 * A reference to this GPE has been added during the GPE block
 441                 * initialization, so drop it now to prevent the GPE from being
 442                 * permanently enabled and clear its ACPI_GPE_AUTO_ENABLED flag.
 443                 */
 444                (void)acpi_ev_remove_gpe_reference(gpe_event_info);
 445                gpe_event_info->flags &= ~ACPI_GPE_AUTO_ENABLED;
 446        }
 447
 448        /*
 449         * If we already have an implicit notify on this GPE, add
 450         * this device to the notify list.
 451         */
 452        if (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) ==
 453            ACPI_GPE_DISPATCH_NOTIFY) {
 454
 455                /* Ensure that the device is not already in the list */
 456
 457                notify = gpe_event_info->dispatch.notify_list;
 458                while (notify) {
 459                        if (notify->device_node == device_node) {
 460                                status = AE_ALREADY_EXISTS;
 461                                goto unlock_and_exit;
 462                        }
 463                        notify = notify->next;
 464                }
 465
 466                /* Add this device to the notify list for this GPE */
 467
 468                new_notify->device_node = device_node;
 469                new_notify->next = gpe_event_info->dispatch.notify_list;
 470                gpe_event_info->dispatch.notify_list = new_notify;
 471                new_notify = NULL;
 472        }
 473
 474        /* Mark the GPE as a possible wake event */
 475
 476        gpe_event_info->flags |= ACPI_GPE_CAN_WAKE;
 477        status = AE_OK;
 478
 479unlock_and_exit:
 480        acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
 481
 482        /* Delete the notify object if it was not used above */
 483
 484        if (new_notify) {
 485                ACPI_FREE(new_notify);
 486        }
 487        return_ACPI_STATUS(status);
 488}
 489ACPI_EXPORT_SYMBOL(acpi_setup_gpe_for_wake)
 490
 491/*******************************************************************************
 492 *
 493 * FUNCTION:    acpi_set_gpe_wake_mask
 494 *
 495 * PARAMETERS:  gpe_device      - Parent GPE Device. NULL for GPE0/GPE1
 496 *              gpe_number      - GPE level within the GPE block
 497 *              action              - Enable or Disable
 498 *
 499 * RETURN:      Status
 500 *
 501 * DESCRIPTION: Set or clear the GPE's wakeup enable mask bit. The GPE must
 502 *              already be marked as a WAKE GPE.
 503 *
 504 ******************************************************************************/
 505
 506acpi_status
 507acpi_set_gpe_wake_mask(acpi_handle gpe_device, u32 gpe_number, u8 action)
 508{
 509        acpi_status status = AE_OK;
 510        struct acpi_gpe_event_info *gpe_event_info;
 511        struct acpi_gpe_register_info *gpe_register_info;
 512        acpi_cpu_flags flags;
 513        u32 register_bit;
 514
 515        ACPI_FUNCTION_TRACE(acpi_set_gpe_wake_mask);
 516
 517        flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
 518
 519        /*
 520         * Ensure that we have a valid GPE number and that this GPE is in
 521         * fact a wake GPE
 522         */
 523        gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
 524        if (!gpe_event_info) {
 525                status = AE_BAD_PARAMETER;
 526                goto unlock_and_exit;
 527        }
 528
 529        if (!(gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) {
 530                status = AE_TYPE;
 531                goto unlock_and_exit;
 532        }
 533
 534        gpe_register_info = gpe_event_info->register_info;
 535        if (!gpe_register_info) {
 536                status = AE_NOT_EXIST;
 537                goto unlock_and_exit;
 538        }
 539
 540        register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info);
 541
 542        /* Perform the action */
 543
 544        switch (action) {
 545        case ACPI_GPE_ENABLE:
 546
 547                ACPI_SET_BIT(gpe_register_info->enable_for_wake,
 548                             (u8)register_bit);
 549                break;
 550
 551        case ACPI_GPE_DISABLE:
 552
 553                ACPI_CLEAR_BIT(gpe_register_info->enable_for_wake,
 554                               (u8)register_bit);
 555                break;
 556
 557        default:
 558
 559                ACPI_ERROR((AE_INFO, "%u, Invalid action", action));
 560                status = AE_BAD_PARAMETER;
 561                break;
 562        }
 563
 564unlock_and_exit:
 565        acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
 566        return_ACPI_STATUS(status);
 567}
 568
 569ACPI_EXPORT_SYMBOL(acpi_set_gpe_wake_mask)
 570
 571/*******************************************************************************
 572 *
 573 * FUNCTION:    acpi_clear_gpe
 574 *
 575 * PARAMETERS:  gpe_device      - Parent GPE Device. NULL for GPE0/GPE1
 576 *              gpe_number      - GPE level within the GPE block
 577 *
 578 * RETURN:      Status
 579 *
 580 * DESCRIPTION: Clear an ACPI event (general purpose)
 581 *
 582 ******************************************************************************/
 583acpi_status acpi_clear_gpe(acpi_handle gpe_device, u32 gpe_number)
 584{
 585        acpi_status status = AE_OK;
 586        struct acpi_gpe_event_info *gpe_event_info;
 587        acpi_cpu_flags flags;
 588
 589        ACPI_FUNCTION_TRACE(acpi_clear_gpe);
 590
 591        flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
 592
 593        /* Ensure that we have a valid GPE number */
 594
 595        gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
 596        if (!gpe_event_info) {
 597                status = AE_BAD_PARAMETER;
 598                goto unlock_and_exit;
 599        }
 600
 601        status = acpi_hw_clear_gpe(gpe_event_info);
 602
 603      unlock_and_exit:
 604        acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
 605        return_ACPI_STATUS(status);
 606}
 607
 608ACPI_EXPORT_SYMBOL(acpi_clear_gpe)
 609
 610/*******************************************************************************
 611 *
 612 * FUNCTION:    acpi_get_gpe_status
 613 *
 614 * PARAMETERS:  gpe_device          - Parent GPE Device. NULL for GPE0/GPE1
 615 *              gpe_number          - GPE level within the GPE block
 616 *              event_status        - Where the current status of the event
 617 *                                    will be returned
 618 *
 619 * RETURN:      Status
 620 *
 621 * DESCRIPTION: Get the current status of a GPE (signalled/not_signalled)
 622 *
 623 ******************************************************************************/
 624acpi_status
 625acpi_get_gpe_status(acpi_handle gpe_device,
 626                    u32 gpe_number, acpi_event_status *event_status)
 627{
 628        acpi_status status = AE_OK;
 629        struct acpi_gpe_event_info *gpe_event_info;
 630        acpi_cpu_flags flags;
 631
 632        ACPI_FUNCTION_TRACE(acpi_get_gpe_status);
 633
 634        flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
 635
 636        /* Ensure that we have a valid GPE number */
 637
 638        gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
 639        if (!gpe_event_info) {
 640                status = AE_BAD_PARAMETER;
 641                goto unlock_and_exit;
 642        }
 643
 644        /* Obtain status on the requested GPE number */
 645
 646        status = acpi_hw_get_gpe_status(gpe_event_info, event_status);
 647
 648unlock_and_exit:
 649        acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
 650        return_ACPI_STATUS(status);
 651}
 652
 653ACPI_EXPORT_SYMBOL(acpi_get_gpe_status)
 654
 655/*******************************************************************************
 656 *
 657 * FUNCTION:    acpi_finish_gpe
 658 *
 659 * PARAMETERS:  gpe_device          - Namespace node for the GPE Block
 660 *                                    (NULL for FADT defined GPEs)
 661 *              gpe_number          - GPE level within the GPE block
 662 *
 663 * RETURN:      Status
 664 *
 665 * DESCRIPTION: Clear and conditionally reenable a GPE. This completes the GPE
 666 *              processing. Intended for use by asynchronous host-installed
 667 *              GPE handlers. The GPE is only reenabled if the enable_for_run bit
 668 *              is set in the GPE info.
 669 *
 670 ******************************************************************************/
 671acpi_status acpi_finish_gpe(acpi_handle gpe_device, u32 gpe_number)
 672{
 673        struct acpi_gpe_event_info *gpe_event_info;
 674        acpi_status status;
 675        acpi_cpu_flags flags;
 676
 677        ACPI_FUNCTION_TRACE(acpi_finish_gpe);
 678
 679        flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
 680
 681        /* Ensure that we have a valid GPE number */
 682
 683        gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
 684        if (!gpe_event_info) {
 685                status = AE_BAD_PARAMETER;
 686                goto unlock_and_exit;
 687        }
 688
 689        status = acpi_ev_finish_gpe(gpe_event_info);
 690
 691unlock_and_exit:
 692        acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
 693        return_ACPI_STATUS(status);
 694}
 695
 696ACPI_EXPORT_SYMBOL(acpi_finish_gpe)
 697
 698/******************************************************************************
 699 *
 700 * FUNCTION:    acpi_disable_all_gpes
 701 *
 702 * PARAMETERS:  None
 703 *
 704 * RETURN:      Status
 705 *
 706 * DESCRIPTION: Disable and clear all GPEs in all GPE blocks
 707 *
 708 ******************************************************************************/
 709
 710acpi_status acpi_disable_all_gpes(void)
 711{
 712        acpi_status status;
 713
 714        ACPI_FUNCTION_TRACE(acpi_disable_all_gpes);
 715
 716        status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
 717        if (ACPI_FAILURE(status)) {
 718                return_ACPI_STATUS(status);
 719        }
 720
 721        status = acpi_hw_disable_all_gpes();
 722        (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
 723
 724        return_ACPI_STATUS(status);
 725}
 726
 727ACPI_EXPORT_SYMBOL(acpi_disable_all_gpes)
 728
 729/******************************************************************************
 730 *
 731 * FUNCTION:    acpi_enable_all_runtime_gpes
 732 *
 733 * PARAMETERS:  None
 734 *
 735 * RETURN:      Status
 736 *
 737 * DESCRIPTION: Enable all "runtime" GPEs, in all GPE blocks
 738 *
 739 ******************************************************************************/
 740
 741acpi_status acpi_enable_all_runtime_gpes(void)
 742{
 743        acpi_status status;
 744
 745        ACPI_FUNCTION_TRACE(acpi_enable_all_runtime_gpes);
 746
 747        status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
 748        if (ACPI_FAILURE(status)) {
 749                return_ACPI_STATUS(status);
 750        }
 751
 752        status = acpi_hw_enable_all_runtime_gpes();
 753        (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
 754
 755        return_ACPI_STATUS(status);
 756}
 757
 758ACPI_EXPORT_SYMBOL(acpi_enable_all_runtime_gpes)
 759
 760/******************************************************************************
 761 *
 762 * FUNCTION:    acpi_enable_all_wakeup_gpes
 763 *
 764 * PARAMETERS:  None
 765 *
 766 * RETURN:      Status
 767 *
 768 * DESCRIPTION: Enable all "wakeup" GPEs and disable all of the other GPEs, in
 769 *              all GPE blocks.
 770 *
 771 ******************************************************************************/
 772acpi_status acpi_enable_all_wakeup_gpes(void)
 773{
 774        acpi_status status;
 775
 776        ACPI_FUNCTION_TRACE(acpi_enable_all_wakeup_gpes);
 777
 778        status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
 779        if (ACPI_FAILURE(status)) {
 780                return_ACPI_STATUS(status);
 781        }
 782
 783        status = acpi_hw_enable_all_wakeup_gpes();
 784        (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS);
 785
 786        return_ACPI_STATUS(status);
 787}
 788
 789ACPI_EXPORT_SYMBOL(acpi_enable_all_wakeup_gpes)
 790
 791/*******************************************************************************
 792 *
 793 * FUNCTION:    acpi_install_gpe_block
 794 *
 795 * PARAMETERS:  gpe_device          - Handle to the parent GPE Block Device
 796 *              gpe_block_address   - Address and space_ID
 797 *              register_count      - Number of GPE register pairs in the block
 798 *              interrupt_number    - H/W interrupt for the block
 799 *
 800 * RETURN:      Status
 801 *
 802 * DESCRIPTION: Create and Install a block of GPE registers. The GPEs are not
 803 *              enabled here.
 804 *
 805 ******************************************************************************/
 806acpi_status
 807acpi_install_gpe_block(acpi_handle gpe_device,
 808                       struct acpi_generic_address *gpe_block_address,
 809                       u32 register_count, u32 interrupt_number)
 810{
 811        acpi_status status;
 812        union acpi_operand_object *obj_desc;
 813        struct acpi_namespace_node *node;
 814        struct acpi_gpe_block_info *gpe_block;
 815
 816        ACPI_FUNCTION_TRACE(acpi_install_gpe_block);
 817
 818        if ((!gpe_device) || (!gpe_block_address) || (!register_count)) {
 819                return_ACPI_STATUS(AE_BAD_PARAMETER);
 820        }
 821
 822        status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
 823        if (ACPI_FAILURE(status)) {
 824                return_ACPI_STATUS(status);
 825        }
 826
 827        node = acpi_ns_validate_handle(gpe_device);
 828        if (!node) {
 829                status = AE_BAD_PARAMETER;
 830                goto unlock_and_exit;
 831        }
 832
 833        /* Validate the parent device */
 834
 835        if (node->type != ACPI_TYPE_DEVICE) {
 836                status = AE_TYPE;
 837                goto unlock_and_exit;
 838        }
 839
 840        if (node->object) {
 841                status = AE_ALREADY_EXISTS;
 842                goto unlock_and_exit;
 843        }
 844
 845        /*
 846         * For user-installed GPE Block Devices, the gpe_block_base_number
 847         * is always zero
 848         */
 849        status = acpi_ev_create_gpe_block(node, gpe_block_address->address,
 850                                          gpe_block_address->space_id,
 851                                          register_count, 0, interrupt_number,
 852                                          &gpe_block);
 853        if (ACPI_FAILURE(status)) {
 854                goto unlock_and_exit;
 855        }
 856
 857        /* Install block in the device_object attached to the node */
 858
 859        obj_desc = acpi_ns_get_attached_object(node);
 860        if (!obj_desc) {
 861
 862                /*
 863                 * No object, create a new one (Device nodes do not always have
 864                 * an attached object)
 865                 */
 866                obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_DEVICE);
 867                if (!obj_desc) {
 868                        status = AE_NO_MEMORY;
 869                        goto unlock_and_exit;
 870                }
 871
 872                status =
 873                    acpi_ns_attach_object(node, obj_desc, ACPI_TYPE_DEVICE);
 874
 875                /* Remove local reference to the object */
 876
 877                acpi_ut_remove_reference(obj_desc);
 878
 879                if (ACPI_FAILURE(status)) {
 880                        goto unlock_and_exit;
 881                }
 882        }
 883
 884        /* Now install the GPE block in the device_object */
 885
 886        obj_desc->device.gpe_block = gpe_block;
 887
 888unlock_and_exit:
 889        (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
 890        return_ACPI_STATUS(status);
 891}
 892
 893ACPI_EXPORT_SYMBOL(acpi_install_gpe_block)
 894
 895/*******************************************************************************
 896 *
 897 * FUNCTION:    acpi_remove_gpe_block
 898 *
 899 * PARAMETERS:  gpe_device          - Handle to the parent GPE Block Device
 900 *
 901 * RETURN:      Status
 902 *
 903 * DESCRIPTION: Remove a previously installed block of GPE registers
 904 *
 905 ******************************************************************************/
 906acpi_status acpi_remove_gpe_block(acpi_handle gpe_device)
 907{
 908        union acpi_operand_object *obj_desc;
 909        acpi_status status;
 910        struct acpi_namespace_node *node;
 911
 912        ACPI_FUNCTION_TRACE(acpi_remove_gpe_block);
 913
 914        if (!gpe_device) {
 915                return_ACPI_STATUS(AE_BAD_PARAMETER);
 916        }
 917
 918        status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
 919        if (ACPI_FAILURE(status)) {
 920                return_ACPI_STATUS(status);
 921        }
 922
 923        node = acpi_ns_validate_handle(gpe_device);
 924        if (!node) {
 925                status = AE_BAD_PARAMETER;
 926                goto unlock_and_exit;
 927        }
 928
 929        /* Validate the parent device */
 930
 931        if (node->type != ACPI_TYPE_DEVICE) {
 932                status = AE_TYPE;
 933                goto unlock_and_exit;
 934        }
 935
 936        /* Get the device_object attached to the node */
 937
 938        obj_desc = acpi_ns_get_attached_object(node);
 939        if (!obj_desc || !obj_desc->device.gpe_block) {
 940                return_ACPI_STATUS(AE_NULL_OBJECT);
 941        }
 942
 943        /* Delete the GPE block (but not the device_object) */
 944
 945        status = acpi_ev_delete_gpe_block(obj_desc->device.gpe_block);
 946        if (ACPI_SUCCESS(status)) {
 947                obj_desc->device.gpe_block = NULL;
 948        }
 949
 950unlock_and_exit:
 951        (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
 952        return_ACPI_STATUS(status);
 953}
 954
 955ACPI_EXPORT_SYMBOL(acpi_remove_gpe_block)
 956
 957/*******************************************************************************
 958 *
 959 * FUNCTION:    acpi_get_gpe_device
 960 *
 961 * PARAMETERS:  index               - System GPE index (0-current_gpe_count)
 962 *              gpe_device          - Where the parent GPE Device is returned
 963 *
 964 * RETURN:      Status
 965 *
 966 * DESCRIPTION: Obtain the GPE device associated with the input index. A NULL
 967 *              gpe device indicates that the gpe number is contained in one of
 968 *              the FADT-defined gpe blocks. Otherwise, the GPE block device.
 969 *
 970 ******************************************************************************/
 971acpi_status acpi_get_gpe_device(u32 index, acpi_handle *gpe_device)
 972{
 973        struct acpi_gpe_device_info info;
 974        acpi_status status;
 975
 976        ACPI_FUNCTION_TRACE(acpi_get_gpe_device);
 977
 978        if (!gpe_device) {
 979                return_ACPI_STATUS(AE_BAD_PARAMETER);
 980        }
 981
 982        if (index >= acpi_current_gpe_count) {
 983                return_ACPI_STATUS(AE_NOT_EXIST);
 984        }
 985
 986        /* Setup and walk the GPE list */
 987
 988        info.index = index;
 989        info.status = AE_NOT_EXIST;
 990        info.gpe_device = NULL;
 991        info.next_block_base_index = 0;
 992
 993        status = acpi_ev_walk_gpe_list(acpi_ev_get_gpe_device, &info);
 994        if (ACPI_FAILURE(status)) {
 995                return_ACPI_STATUS(status);
 996        }
 997
 998        *gpe_device = ACPI_CAST_PTR(acpi_handle, info.gpe_device);
 999        return_ACPI_STATUS(info.status);
1000}
1001
1002ACPI_EXPORT_SYMBOL(acpi_get_gpe_device)
1003#endif                          /* !ACPI_REDUCED_HARDWARE */
1004