Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:02

0001 /******************************************************************************
0002  *
0003  * Module Name: evxfgpe - External Interfaces for General Purpose Events (GPEs)
0004  *
0005  *****************************************************************************/
0006 
0007 /******************************************************************************
0008  *
0009  * 1. Copyright Notice
0010  *
0011  * Some or all of this work - Copyright (c) 1999 - 2024, Intel Corp.
0012  * All rights reserved.
0013  *
0014  * 2. License
0015  *
0016  * 2.1. This is your license from Intel Corp. under its intellectual property
0017  * rights. You may have additional license terms from the party that provided
0018  * you this software, covering your right to use that party's intellectual
0019  * property rights.
0020  *
0021  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
0022  * copy of the source code appearing in this file ("Covered Code") an
0023  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
0024  * base code distributed originally by Intel ("Original Intel Code") to copy,
0025  * make derivatives, distribute, use and display any portion of the Covered
0026  * Code in any form, with the right to sublicense such rights; and
0027  *
0028  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
0029  * license (with the right to sublicense), under only those claims of Intel
0030  * patents that are infringed by the Original Intel Code, to make, use, sell,
0031  * offer to sell, and import the Covered Code and derivative works thereof
0032  * solely to the minimum extent necessary to exercise the above copyright
0033  * license, and in no event shall the patent license extend to any additions
0034  * to or modifications of the Original Intel Code. No other license or right
0035  * is granted directly or by implication, estoppel or otherwise;
0036  *
0037  * The above copyright and patent license is granted only if the following
0038  * conditions are met:
0039  *
0040  * 3. Conditions
0041  *
0042  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
0043  * Redistribution of source code of any substantial portion of the Covered
0044  * Code or modification with rights to further distribute source must include
0045  * the above Copyright Notice, the above License, this list of Conditions,
0046  * and the following Disclaimer and Export Compliance provision. In addition,
0047  * Licensee must cause all Covered Code to which Licensee contributes to
0048  * contain a file documenting the changes Licensee made to create that Covered
0049  * Code and the date of any change. Licensee must include in that file the
0050  * documentation of any changes made by any predecessor Licensee. Licensee
0051  * must include a prominent statement that the modification is derived,
0052  * directly or indirectly, from Original Intel Code.
0053  *
0054  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
0055  * Redistribution of source code of any substantial portion of the Covered
0056  * Code or modification without rights to further distribute source must
0057  * include the following Disclaimer and Export Compliance provision in the
0058  * documentation and/or other materials provided with distribution. In
0059  * addition, Licensee may not authorize further sublicense of source of any
0060  * portion of the Covered Code, and must include terms to the effect that the
0061  * license from Licensee to its licensee is limited to the intellectual
0062  * property embodied in the software Licensee provides to its licensee, and
0063  * not to intellectual property embodied in modifications its licensee may
0064  * make.
0065  *
0066  * 3.3. Redistribution of Executable. Redistribution in executable form of any
0067  * substantial portion of the Covered Code or modification must reproduce the
0068  * above Copyright Notice, and the following Disclaimer and Export Compliance
0069  * provision in the documentation and/or other materials provided with the
0070  * distribution.
0071  *
0072  * 3.4. Intel retains all right, title, and interest in and to the Original
0073  * Intel Code.
0074  *
0075  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
0076  * Intel shall be used in advertising or otherwise to promote the sale, use or
0077  * other dealings in products derived from or relating to the Covered Code
0078  * without prior written authorization from Intel.
0079  *
0080  * 4. Disclaimer and Export Compliance
0081  *
0082  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
0083  * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
0084  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
0085  * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
0086  * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
0087  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
0088  * PARTICULAR PURPOSE.
0089  *
0090  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
0091  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
0092  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
0093  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
0094  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
0095  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
0096  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
0097  * LIMITED REMEDY.
0098  *
0099  * 4.3. Licensee shall not export, either directly or indirectly, any of this
0100  * software or system incorporating such software without first obtaining any
0101  * required license or other approval from the U. S. Department of Commerce or
0102  * any other agency or department of the United States Government. In the
0103  * event Licensee exports any such software from the United States or
0104  * re-exports any such software from a foreign destination, Licensee shall
0105  * ensure that the distribution and export/re-export of the software is in
0106  * compliance with all laws, regulations, orders, or other restrictions of the
0107  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
0108  * any of its subsidiaries will export/re-export any technical data, process,
0109  * software, or service, directly or indirectly, to any country for which the
0110  * United States government or any agency thereof requires an export license,
0111  * other governmental approval, or letter of assurance, without first obtaining
0112  * such license, approval or letter.
0113  *
0114  *****************************************************************************
0115  *
0116  * Alternatively, you may choose to be licensed under the terms of the
0117  * following license:
0118  *
0119  * Redistribution and use in source and binary forms, with or without
0120  * modification, are permitted provided that the following conditions
0121  * are met:
0122  * 1. Redistributions of source code must retain the above copyright
0123  *    notice, this list of conditions, and the following disclaimer,
0124  *    without modification.
0125  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
0126  *    substantially similar to the "NO WARRANTY" disclaimer below
0127  *    ("Disclaimer") and any redistribution must be conditioned upon
0128  *    including a substantially similar Disclaimer requirement for further
0129  *    binary redistribution.
0130  * 3. Neither the names of the above-listed copyright holders nor the names
0131  *    of any contributors may be used to endorse or promote products derived
0132  *    from this software without specific prior written permission.
0133  *
0134  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
0135  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
0136  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
0137  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
0138  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
0139  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
0140  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
0141  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
0142  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0143  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
0144  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0145  *
0146  * Alternatively, you may choose to be licensed under the terms of the
0147  * GNU General Public License ("GPL") version 2 as published by the Free
0148  * Software Foundation.
0149  *
0150  *****************************************************************************/
0151 
0152 #define EXPORT_ACPI_INTERFACES
0153 
0154 #include "acpi.h"
0155 #include "accommon.h"
0156 #include "acevents.h"
0157 #include "acnamesp.h"
0158 
0159 #define _COMPONENT          ACPI_EVENTS
0160         ACPI_MODULE_NAME    ("evxfgpe")
0161 
0162 
0163 #if (!ACPI_REDUCED_HARDWARE) /* Entire module */
0164 /*******************************************************************************
0165  *
0166  * FUNCTION:    AcpiUpdateAllGpes
0167  *
0168  * PARAMETERS:  None
0169  *
0170  * RETURN:      Status
0171  *
0172  * DESCRIPTION: Complete GPE initialization and enable all GPEs that have
0173  *              associated _Lxx or _Exx methods and are not pointed to by any
0174  *              device _PRW methods (this indicates that these GPEs are
0175  *              generally intended for system or device wakeup. Such GPEs
0176  *              have to be enabled directly when the devices whose _PRW
0177  *              methods point to them are set up for wakeup signaling.)
0178  *
0179  * NOTE: Should be called after any GPEs are added to the system. Primarily,
0180  * after the system _PRW methods have been run, but also after a GPE Block
0181  * Device has been added or if any new GPE methods have been added via a
0182  * dynamic table load.
0183  *
0184  ******************************************************************************/
0185 
0186 ACPI_STATUS
0187 AcpiUpdateAllGpes (
0188     void)
0189 {
0190     ACPI_STATUS             Status;
0191     BOOLEAN                 IsPollingNeeded = FALSE;
0192 
0193 
0194     ACPI_FUNCTION_TRACE (AcpiUpdateAllGpes);
0195 
0196 
0197     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
0198     if (ACPI_FAILURE (Status))
0199     {
0200         return_ACPI_STATUS (Status);
0201     }
0202 
0203     if (AcpiGbl_AllGpesInitialized)
0204     {
0205         goto UnlockAndExit;
0206     }
0207 
0208     Status = AcpiEvWalkGpeList (AcpiEvInitializeGpeBlock,
0209         &IsPollingNeeded);
0210     if (ACPI_SUCCESS (Status))
0211     {
0212         AcpiGbl_AllGpesInitialized = TRUE;
0213     }
0214 
0215 UnlockAndExit:
0216     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
0217 
0218     if (IsPollingNeeded && AcpiGbl_AllGpesInitialized)
0219     {
0220         /* Poll GPEs to handle already triggered events */
0221 
0222         AcpiEvGpeDetect (AcpiGbl_GpeXruptListHead);
0223     }
0224     return_ACPI_STATUS (Status);
0225 }
0226 
0227 ACPI_EXPORT_SYMBOL (AcpiUpdateAllGpes)
0228 
0229 
0230 /*******************************************************************************
0231  *
0232  * FUNCTION:    AcpiEnableGpe
0233  *
0234  * PARAMETERS:  GpeDevice           - Parent GPE Device. NULL for GPE0/GPE1
0235  *              GpeNumber           - GPE level within the GPE block
0236  *
0237  * RETURN:      Status
0238  *
0239  * DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is
0240  *              hardware-enabled.
0241  *
0242  ******************************************************************************/
0243 
0244 ACPI_STATUS
0245 AcpiEnableGpe (
0246     ACPI_HANDLE             GpeDevice,
0247     UINT32                  GpeNumber)
0248 {
0249     ACPI_STATUS             Status = AE_BAD_PARAMETER;
0250     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
0251     ACPI_CPU_FLAGS          Flags;
0252 
0253 
0254     ACPI_FUNCTION_TRACE (AcpiEnableGpe);
0255 
0256 
0257     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
0258 
0259     /*
0260      * Ensure that we have a valid GPE number and that there is some way
0261      * of handling the GPE (handler or a GPE method). In other words, we
0262      * won't allow a valid GPE to be enabled if there is no way to handle it.
0263      */
0264     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
0265     if (GpeEventInfo)
0266     {
0267         if (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) !=
0268             ACPI_GPE_DISPATCH_NONE)
0269         {
0270             Status = AcpiEvAddGpeReference (GpeEventInfo, TRUE);
0271             if (ACPI_SUCCESS (Status) &&
0272                 ACPI_GPE_IS_POLLING_NEEDED (GpeEventInfo))
0273             {
0274                 /* Poll edge-triggered GPEs to handle existing events */
0275 
0276                 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
0277                 (void) AcpiEvDetectGpe (
0278                     GpeDevice, GpeEventInfo, GpeNumber);
0279                 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
0280             }
0281         }
0282         else
0283         {
0284             Status = AE_NO_HANDLER;
0285         }
0286     }
0287 
0288     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
0289     return_ACPI_STATUS (Status);
0290 }
0291 
0292 ACPI_EXPORT_SYMBOL (AcpiEnableGpe)
0293 
0294 
0295 /*******************************************************************************
0296  *
0297  * FUNCTION:    AcpiDisableGpe
0298  *
0299  * PARAMETERS:  GpeDevice           - Parent GPE Device. NULL for GPE0/GPE1
0300  *              GpeNumber           - GPE level within the GPE block
0301  *
0302  * RETURN:      Status
0303  *
0304  * DESCRIPTION: Remove a reference to a GPE. When the last reference is
0305  *              removed, only then is the GPE disabled (for runtime GPEs), or
0306  *              the GPE mask bit disabled (for wake GPEs)
0307  *
0308  ******************************************************************************/
0309 
0310 ACPI_STATUS
0311 AcpiDisableGpe (
0312     ACPI_HANDLE             GpeDevice,
0313     UINT32                  GpeNumber)
0314 {
0315     ACPI_STATUS             Status = AE_BAD_PARAMETER;
0316     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
0317     ACPI_CPU_FLAGS          Flags;
0318 
0319 
0320     ACPI_FUNCTION_TRACE (AcpiDisableGpe);
0321 
0322 
0323     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
0324 
0325     /* Ensure that we have a valid GPE number */
0326 
0327     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
0328     if (GpeEventInfo)
0329     {
0330         Status = AcpiEvRemoveGpeReference (GpeEventInfo);
0331     }
0332 
0333     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
0334     return_ACPI_STATUS (Status);
0335 }
0336 
0337 ACPI_EXPORT_SYMBOL (AcpiDisableGpe)
0338 
0339 
0340 /*******************************************************************************
0341  *
0342  * FUNCTION:    AcpiSetGpe
0343  *
0344  * PARAMETERS:  GpeDevice           - Parent GPE Device. NULL for GPE0/GPE1
0345  *              GpeNumber           - GPE level within the GPE block
0346  *              Action              - ACPI_GPE_ENABLE or ACPI_GPE_DISABLE
0347  *
0348  * RETURN:      Status
0349  *
0350  * DESCRIPTION: Enable or disable an individual GPE. This function bypasses
0351  *              the reference count mechanism used in the AcpiEnableGpe(),
0352  *              AcpiDisableGpe() interfaces.
0353  *              This API is typically used by the GPE raw handler mode driver
0354  *              to switch between the polling mode and the interrupt mode after
0355  *              the driver has enabled the GPE.
0356  *              The APIs should be invoked in this order:
0357  *               AcpiEnableGpe()              <- Ensure the reference count > 0
0358  *               AcpiSetGpe(ACPI_GPE_DISABLE) <- Enter polling mode
0359  *               AcpiSetGpe(ACPI_GPE_ENABLE)  <- Leave polling mode
0360  *               AcpiDisableGpe()             <- Decrease the reference count
0361  *
0362  * Note: If a GPE is shared by 2 silicon components, then both the drivers
0363  *       should support GPE polling mode or disabling the GPE for long period
0364  *       for one driver may break the other. So use it with care since all
0365  *       firmware _Lxx/_Exx handlers currently rely on the GPE interrupt mode.
0366  *
0367  ******************************************************************************/
0368 
0369 ACPI_STATUS
0370 AcpiSetGpe (
0371     ACPI_HANDLE             GpeDevice,
0372     UINT32                  GpeNumber,
0373     UINT8                   Action)
0374 {
0375     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
0376     ACPI_STATUS             Status;
0377     ACPI_CPU_FLAGS          Flags;
0378 
0379 
0380     ACPI_FUNCTION_TRACE (AcpiSetGpe);
0381 
0382 
0383     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
0384 
0385     /* Ensure that we have a valid GPE number */
0386 
0387     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
0388     if (!GpeEventInfo)
0389     {
0390         Status = AE_BAD_PARAMETER;
0391         goto UnlockAndExit;
0392     }
0393 
0394     /* Perform the action */
0395 
0396     switch (Action)
0397     {
0398     case ACPI_GPE_ENABLE:
0399 
0400         Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_ENABLE);
0401         GpeEventInfo->DisableForDispatch = FALSE;
0402         break;
0403 
0404     case ACPI_GPE_DISABLE:
0405 
0406         Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_DISABLE);
0407         GpeEventInfo->DisableForDispatch = TRUE;
0408         break;
0409 
0410     default:
0411 
0412         Status = AE_BAD_PARAMETER;
0413         break;
0414     }
0415 
0416 UnlockAndExit:
0417     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
0418     return_ACPI_STATUS (Status);
0419 }
0420 
0421 ACPI_EXPORT_SYMBOL (AcpiSetGpe)
0422 
0423 
0424 /*******************************************************************************
0425  *
0426  * FUNCTION:    AcpiMaskGpe
0427  *
0428  * PARAMETERS:  GpeDevice           - Parent GPE Device. NULL for GPE0/GPE1
0429  *              GpeNumber           - GPE level within the GPE block
0430  *              IsMasked            - Whether the GPE is masked or not
0431  *
0432  * RETURN:      Status
0433  *
0434  * DESCRIPTION: Unconditionally mask/unmask the an individual GPE, ex., to
0435  *              prevent a GPE flooding.
0436  *
0437  ******************************************************************************/
0438 
0439 ACPI_STATUS
0440 AcpiMaskGpe (
0441     ACPI_HANDLE             GpeDevice,
0442     UINT32                  GpeNumber,
0443     BOOLEAN                 IsMasked)
0444 {
0445     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
0446     ACPI_STATUS             Status;
0447     ACPI_CPU_FLAGS          Flags;
0448 
0449 
0450     ACPI_FUNCTION_TRACE (AcpiMaskGpe);
0451 
0452 
0453     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
0454 
0455     /* Ensure that we have a valid GPE number */
0456 
0457     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
0458     if (!GpeEventInfo)
0459     {
0460         Status = AE_BAD_PARAMETER;
0461         goto UnlockAndExit;
0462     }
0463 
0464     Status = AcpiEvMaskGpe (GpeEventInfo, IsMasked);
0465 
0466 UnlockAndExit:
0467     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
0468     return_ACPI_STATUS (Status);
0469 }
0470 
0471 ACPI_EXPORT_SYMBOL (AcpiMaskGpe)
0472 
0473 
0474 /*******************************************************************************
0475  *
0476  * FUNCTION:    AcpiMarkGpeForWake
0477  *
0478  * PARAMETERS:  GpeDevice           - Parent GPE Device. NULL for GPE0/GPE1
0479  *              GpeNumber           - GPE level within the GPE block
0480  *
0481  * RETURN:      Status
0482  *
0483  * DESCRIPTION: Mark a GPE as having the ability to wake the system. Simply
0484  *              sets the ACPI_GPE_CAN_WAKE flag.
0485  *
0486  * Some potential callers of AcpiSetupGpeForWake may know in advance that
0487  * there won't be any notify handlers installed for device wake notifications
0488  * from the given GPE (one example is a button GPE in Linux). For these cases,
0489  * AcpiMarkGpeForWake should be used instead of AcpiSetupGpeForWake.
0490  * This will set the ACPI_GPE_CAN_WAKE flag for the GPE without trying to
0491  * setup implicit wake notification for it (since there's no handler method).
0492  *
0493  ******************************************************************************/
0494 
0495 ACPI_STATUS
0496 AcpiMarkGpeForWake (
0497     ACPI_HANDLE             GpeDevice,
0498     UINT32                  GpeNumber)
0499 {
0500     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
0501     ACPI_STATUS             Status = AE_BAD_PARAMETER;
0502     ACPI_CPU_FLAGS          Flags;
0503 
0504 
0505     ACPI_FUNCTION_TRACE (AcpiMarkGpeForWake);
0506 
0507 
0508     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
0509 
0510     /* Ensure that we have a valid GPE number */
0511 
0512     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
0513     if (GpeEventInfo)
0514     {
0515         /* Mark the GPE as a possible wake event */
0516 
0517         GpeEventInfo->Flags |= ACPI_GPE_CAN_WAKE;
0518         Status = AE_OK;
0519     }
0520 
0521     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
0522     return_ACPI_STATUS (Status);
0523 }
0524 
0525 ACPI_EXPORT_SYMBOL (AcpiMarkGpeForWake)
0526 
0527 
0528 /*******************************************************************************
0529  *
0530  * FUNCTION:    AcpiSetupGpeForWake
0531  *
0532  * PARAMETERS:  WakeDevice          - Device associated with the GPE (via _PRW)
0533  *              GpeDevice           - Parent GPE Device. NULL for GPE0/GPE1
0534  *              GpeNumber           - GPE level within the GPE block
0535  *
0536  * RETURN:      Status
0537  *
0538  * DESCRIPTION: Mark a GPE as having the ability to wake the system. This
0539  *              interface is intended to be used as the host executes the
0540  *              _PRW methods (Power Resources for Wake) in the system tables.
0541  *              Each _PRW appears under a Device Object (The WakeDevice), and
0542  *              contains the info for the wake GPE associated with the
0543  *              WakeDevice.
0544  *
0545  ******************************************************************************/
0546 
0547 ACPI_STATUS
0548 AcpiSetupGpeForWake (
0549     ACPI_HANDLE             WakeDevice,
0550     ACPI_HANDLE             GpeDevice,
0551     UINT32                  GpeNumber)
0552 {
0553     ACPI_STATUS             Status;
0554     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
0555     ACPI_NAMESPACE_NODE     *DeviceNode;
0556     ACPI_GPE_NOTIFY_INFO    *Notify;
0557     ACPI_GPE_NOTIFY_INFO    *NewNotify;
0558     ACPI_CPU_FLAGS          Flags;
0559 
0560 
0561     ACPI_FUNCTION_TRACE (AcpiSetupGpeForWake);
0562 
0563 
0564     /* Parameter Validation */
0565 
0566     if (!WakeDevice)
0567     {
0568         /*
0569          * By forcing WakeDevice to be valid, we automatically enable the
0570          * implicit notify feature on all hosts.
0571          */
0572         return_ACPI_STATUS (AE_BAD_PARAMETER);
0573     }
0574 
0575     /* Handle root object case */
0576 
0577     if (WakeDevice == ACPI_ROOT_OBJECT)
0578     {
0579         DeviceNode = AcpiGbl_RootNode;
0580     }
0581     else
0582     {
0583         DeviceNode = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, WakeDevice);
0584     }
0585 
0586     /* Validate WakeDevice is of type Device */
0587 
0588     if (DeviceNode->Type != ACPI_TYPE_DEVICE)
0589     {
0590         return_ACPI_STATUS (AE_BAD_PARAMETER);
0591     }
0592 
0593     /*
0594      * Allocate a new notify object up front, in case it is needed.
0595      * Memory allocation while holding a spinlock is a big no-no
0596      * on some hosts.
0597      */
0598     NewNotify = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_GPE_NOTIFY_INFO));
0599     if (!NewNotify)
0600     {
0601         return_ACPI_STATUS (AE_NO_MEMORY);
0602     }
0603 
0604     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
0605 
0606     /* Ensure that we have a valid GPE number */
0607 
0608     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
0609     if (!GpeEventInfo)
0610     {
0611         Status = AE_BAD_PARAMETER;
0612         goto UnlockAndExit;
0613     }
0614 
0615     /*
0616      * If there is no method or handler for this GPE, then the
0617      * WakeDevice will be notified whenever this GPE fires. This is
0618      * known as an "implicit notify". Note: The GPE is assumed to be
0619      * level-triggered (for windows compatibility).
0620      */
0621     if (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) ==
0622         ACPI_GPE_DISPATCH_NONE)
0623     {
0624         /*
0625          * This is the first device for implicit notify on this GPE.
0626          * Just set the flags here, and enter the NOTIFY block below.
0627          */
0628         GpeEventInfo->Flags =
0629             (ACPI_GPE_DISPATCH_NOTIFY | ACPI_GPE_LEVEL_TRIGGERED);
0630     }
0631     else if (GpeEventInfo->Flags & ACPI_GPE_AUTO_ENABLED)
0632     {
0633         /*
0634          * A reference to this GPE has been added during the GPE block
0635          * initialization, so drop it now to prevent the GPE from being
0636          * permanently enabled and clear its ACPI_GPE_AUTO_ENABLED flag.
0637          */
0638         (void) AcpiEvRemoveGpeReference (GpeEventInfo);
0639         GpeEventInfo->Flags &= ~ACPI_GPE_AUTO_ENABLED;
0640     }
0641 
0642     /*
0643      * If we already have an implicit notify on this GPE, add
0644      * this device to the notify list.
0645      */
0646     if (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) ==
0647         ACPI_GPE_DISPATCH_NOTIFY)
0648     {
0649         /* Ensure that the device is not already in the list */
0650 
0651         Notify = GpeEventInfo->Dispatch.NotifyList;
0652         while (Notify)
0653         {
0654             if (Notify->DeviceNode == DeviceNode)
0655             {
0656                 Status = AE_ALREADY_EXISTS;
0657                 goto UnlockAndExit;
0658             }
0659             Notify = Notify->Next;
0660         }
0661 
0662         /* Add this device to the notify list for this GPE */
0663 
0664         NewNotify->DeviceNode = DeviceNode;
0665         NewNotify->Next = GpeEventInfo->Dispatch.NotifyList;
0666         GpeEventInfo->Dispatch.NotifyList = NewNotify;
0667         NewNotify = NULL;
0668     }
0669 
0670     /* Mark the GPE as a possible wake event */
0671 
0672     GpeEventInfo->Flags |= ACPI_GPE_CAN_WAKE;
0673     Status = AE_OK;
0674 
0675 
0676 UnlockAndExit:
0677     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
0678 
0679     /* Delete the notify object if it was not used above */
0680 
0681     if (NewNotify)
0682     {
0683         ACPI_FREE (NewNotify);
0684     }
0685     return_ACPI_STATUS (Status);
0686 }
0687 
0688 ACPI_EXPORT_SYMBOL (AcpiSetupGpeForWake)
0689 
0690 
0691 /*******************************************************************************
0692  *
0693  * FUNCTION:    AcpiSetGpeWakeMask
0694  *
0695  * PARAMETERS:  GpeDevice           - Parent GPE Device. NULL for GPE0/GPE1
0696  *              GpeNumber           - GPE level within the GPE block
0697  *              Action              - Enable or Disable
0698  *
0699  * RETURN:      Status
0700  *
0701  * DESCRIPTION: Set or clear the GPE's wakeup enable mask bit. The GPE must
0702  *              already be marked as a WAKE GPE.
0703  *
0704  ******************************************************************************/
0705 
0706 ACPI_STATUS
0707 AcpiSetGpeWakeMask (
0708     ACPI_HANDLE             GpeDevice,
0709     UINT32                  GpeNumber,
0710     UINT8                   Action)
0711 {
0712     ACPI_STATUS             Status = AE_OK;
0713     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
0714     ACPI_GPE_REGISTER_INFO  *GpeRegisterInfo;
0715     ACPI_CPU_FLAGS          Flags;
0716     UINT32                  RegisterBit;
0717 
0718 
0719     ACPI_FUNCTION_TRACE (AcpiSetGpeWakeMask);
0720 
0721 
0722     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
0723 
0724     /*
0725      * Ensure that we have a valid GPE number and that this GPE is in
0726      * fact a wake GPE
0727      */
0728     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
0729     if (!GpeEventInfo)
0730     {
0731         Status = AE_BAD_PARAMETER;
0732         goto UnlockAndExit;
0733     }
0734 
0735     if (!(GpeEventInfo->Flags & ACPI_GPE_CAN_WAKE))
0736     {
0737         Status = AE_TYPE;
0738         goto UnlockAndExit;
0739     }
0740 
0741     GpeRegisterInfo = GpeEventInfo->RegisterInfo;
0742     if (!GpeRegisterInfo)
0743     {
0744         Status = AE_NOT_EXIST;
0745         goto UnlockAndExit;
0746     }
0747 
0748     RegisterBit = AcpiHwGetGpeRegisterBit (GpeEventInfo);
0749 
0750     /* Perform the action */
0751 
0752     switch (Action)
0753     {
0754     case ACPI_GPE_ENABLE:
0755 
0756         ACPI_SET_BIT (GpeRegisterInfo->EnableForWake, (UINT8) RegisterBit);
0757         break;
0758 
0759     case ACPI_GPE_DISABLE:
0760 
0761         ACPI_CLEAR_BIT (GpeRegisterInfo->EnableForWake, (UINT8) RegisterBit);
0762         break;
0763 
0764     default:
0765 
0766         ACPI_ERROR ((AE_INFO, "%u, Invalid action", Action));
0767         Status = AE_BAD_PARAMETER;
0768         break;
0769     }
0770 
0771 UnlockAndExit:
0772     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
0773     return_ACPI_STATUS (Status);
0774 }
0775 
0776 ACPI_EXPORT_SYMBOL (AcpiSetGpeWakeMask)
0777 
0778 
0779 /*******************************************************************************
0780  *
0781  * FUNCTION:    AcpiClearGpe
0782  *
0783  * PARAMETERS:  GpeDevice           - Parent GPE Device. NULL for GPE0/GPE1
0784  *              GpeNumber           - GPE level within the GPE block
0785  *
0786  * RETURN:      Status
0787  *
0788  * DESCRIPTION: Clear an ACPI event (general purpose)
0789  *
0790  ******************************************************************************/
0791 
0792 ACPI_STATUS
0793 AcpiClearGpe (
0794     ACPI_HANDLE             GpeDevice,
0795     UINT32                  GpeNumber)
0796 {
0797     ACPI_STATUS             Status = AE_OK;
0798     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
0799     ACPI_CPU_FLAGS          Flags;
0800 
0801 
0802     ACPI_FUNCTION_TRACE (AcpiClearGpe);
0803 
0804 
0805     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
0806 
0807     /* Ensure that we have a valid GPE number */
0808 
0809     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
0810     if (!GpeEventInfo)
0811     {
0812         Status = AE_BAD_PARAMETER;
0813         goto UnlockAndExit;
0814     }
0815 
0816     Status = AcpiHwClearGpe (GpeEventInfo);
0817 
0818 UnlockAndExit:
0819     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
0820     return_ACPI_STATUS (Status);
0821 }
0822 
0823 ACPI_EXPORT_SYMBOL (AcpiClearGpe)
0824 
0825 
0826 /*******************************************************************************
0827  *
0828  * FUNCTION:    AcpiGetGpeStatus
0829  *
0830  * PARAMETERS:  GpeDevice           - Parent GPE Device. NULL for GPE0/GPE1
0831  *              GpeNumber           - GPE level within the GPE block
0832  *              EventStatus         - Where the current status of the event
0833  *                                    will be returned
0834  *
0835  * RETURN:      Status
0836  *
0837  * DESCRIPTION: Get the current status of a GPE (signalled/not_signalled)
0838  *
0839  ******************************************************************************/
0840 
0841 ACPI_STATUS
0842 AcpiGetGpeStatus (
0843     ACPI_HANDLE             GpeDevice,
0844     UINT32                  GpeNumber,
0845     ACPI_EVENT_STATUS       *EventStatus)
0846 {
0847     ACPI_STATUS             Status = AE_OK;
0848     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
0849     ACPI_CPU_FLAGS          Flags;
0850 
0851 
0852     ACPI_FUNCTION_TRACE (AcpiGetGpeStatus);
0853 
0854 
0855     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
0856 
0857     /* Ensure that we have a valid GPE number */
0858 
0859     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
0860     if (!GpeEventInfo)
0861     {
0862         Status = AE_BAD_PARAMETER;
0863         goto UnlockAndExit;
0864     }
0865 
0866     /* Obtain status on the requested GPE number */
0867 
0868     Status = AcpiHwGetGpeStatus (GpeEventInfo, EventStatus);
0869 
0870 UnlockAndExit:
0871     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
0872     return_ACPI_STATUS (Status);
0873 }
0874 
0875 ACPI_EXPORT_SYMBOL (AcpiGetGpeStatus)
0876 
0877 
0878 /*******************************************************************************
0879  *
0880  * FUNCTION:    AcpiDispatchGpe
0881  *
0882  * PARAMETERS:  GpeDevice           - Parent GPE Device. NULL for GPE0/GPE1
0883  *              GpeNumber           - GPE level within the GPE block
0884  *
0885  * RETURN:      INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED
0886  *
0887  * DESCRIPTION: Detect and dispatch a General Purpose Event to either a function
0888  *              (e.g. EC) or method (e.g. _Lxx/_Exx) handler.
0889  *
0890  ******************************************************************************/
0891 
0892 UINT32
0893 AcpiDispatchGpe(
0894     ACPI_HANDLE             GpeDevice,
0895     UINT32                  GpeNumber)
0896 {
0897     ACPI_FUNCTION_TRACE(acpi_dispatch_gpe);
0898 
0899     return (AcpiEvDetectGpe (GpeDevice, NULL, GpeNumber));
0900 }
0901 
0902 ACPI_EXPORT_SYMBOL (AcpiDispatchGpe)
0903 
0904 
0905 /*******************************************************************************
0906  *
0907  * FUNCTION:    AcpiFinishGpe
0908  *
0909  * PARAMETERS:  GpeDevice           - Namespace node for the GPE Block
0910  *                                    (NULL for FADT defined GPEs)
0911  *              GpeNumber           - GPE level within the GPE block
0912  *
0913  * RETURN:      Status
0914  *
0915  * DESCRIPTION: Clear and conditionally re-enable a GPE. This completes the GPE
0916  *              processing. Intended for use by asynchronous host-installed
0917  *              GPE handlers. The GPE is only re-enabled if the EnableForRun bit
0918  *              is set in the GPE info.
0919  *
0920  ******************************************************************************/
0921 
0922 ACPI_STATUS
0923 AcpiFinishGpe (
0924     ACPI_HANDLE             GpeDevice,
0925     UINT32                  GpeNumber)
0926 {
0927     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
0928     ACPI_STATUS             Status;
0929     ACPI_CPU_FLAGS          Flags;
0930 
0931 
0932     ACPI_FUNCTION_TRACE (AcpiFinishGpe);
0933 
0934 
0935     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
0936 
0937     /* Ensure that we have a valid GPE number */
0938 
0939     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
0940     if (!GpeEventInfo)
0941     {
0942         Status = AE_BAD_PARAMETER;
0943         goto UnlockAndExit;
0944     }
0945 
0946     Status = AcpiEvFinishGpe (GpeEventInfo);
0947 
0948 UnlockAndExit:
0949     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
0950     return_ACPI_STATUS (Status);
0951 }
0952 
0953 ACPI_EXPORT_SYMBOL (AcpiFinishGpe)
0954 
0955 
0956 /******************************************************************************
0957  *
0958  * FUNCTION:    AcpiDisableAllGpes
0959  *
0960  * PARAMETERS:  None
0961  *
0962  * RETURN:      Status
0963  *
0964  * DESCRIPTION: Disable and clear all GPEs in all GPE blocks
0965  *
0966  ******************************************************************************/
0967 
0968 ACPI_STATUS
0969 AcpiDisableAllGpes (
0970     void)
0971 {
0972     ACPI_STATUS             Status;
0973 
0974 
0975     ACPI_FUNCTION_TRACE (AcpiDisableAllGpes);
0976 
0977 
0978     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
0979     if (ACPI_FAILURE (Status))
0980     {
0981         return_ACPI_STATUS (Status);
0982     }
0983 
0984     Status = AcpiHwDisableAllGpes ();
0985     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
0986 
0987     return_ACPI_STATUS (Status);
0988 }
0989 
0990 ACPI_EXPORT_SYMBOL (AcpiDisableAllGpes)
0991 
0992 
0993 /******************************************************************************
0994  *
0995  * FUNCTION:    AcpiEnableAllRuntimeGpes
0996  *
0997  * PARAMETERS:  None
0998  *
0999  * RETURN:      Status
1000  *
1001  * DESCRIPTION: Enable all "runtime" GPEs, in all GPE blocks
1002  *
1003  ******************************************************************************/
1004 
1005 ACPI_STATUS
1006 AcpiEnableAllRuntimeGpes (
1007     void)
1008 {
1009     ACPI_STATUS             Status;
1010 
1011 
1012     ACPI_FUNCTION_TRACE (AcpiEnableAllRuntimeGpes);
1013 
1014 
1015     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
1016     if (ACPI_FAILURE (Status))
1017     {
1018         return_ACPI_STATUS (Status);
1019     }
1020 
1021     Status = AcpiHwEnableAllRuntimeGpes ();
1022     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
1023 
1024     return_ACPI_STATUS (Status);
1025 }
1026 
1027 ACPI_EXPORT_SYMBOL (AcpiEnableAllRuntimeGpes)
1028 
1029 
1030 /******************************************************************************
1031  *
1032  * FUNCTION:    AcpiEnableAllWakeupGpes
1033  *
1034  * PARAMETERS:  None
1035  *
1036  * RETURN:      Status
1037  *
1038  * DESCRIPTION: Enable all "wakeup" GPEs and disable all of the other GPEs, in
1039  *              all GPE blocks.
1040  *
1041  ******************************************************************************/
1042 
1043 ACPI_STATUS
1044 AcpiEnableAllWakeupGpes (
1045     void)
1046 {
1047     ACPI_STATUS             Status;
1048 
1049 
1050     ACPI_FUNCTION_TRACE (AcpiEnableAllWakeupGpes);
1051 
1052 
1053     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
1054     if (ACPI_FAILURE (Status))
1055     {
1056         return_ACPI_STATUS (Status);
1057     }
1058 
1059     Status = AcpiHwEnableAllWakeupGpes ();
1060     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
1061 
1062     return_ACPI_STATUS (Status);
1063 }
1064 
1065 ACPI_EXPORT_SYMBOL (AcpiEnableAllWakeupGpes)
1066 
1067 
1068 /******************************************************************************
1069  *
1070  * FUNCTION:    AcpiAnyGpeStatusSet
1071  *
1072  * PARAMETERS:  None
1073  *
1074  * RETURN:      Whether or not the status bit is set for any GPE
1075  *
1076  * DESCRIPTION: Check the status bits of all enabled GPEs and return TRUE if any
1077  *              of them is set or FALSE otherwise.
1078  *
1079  ******************************************************************************/
1080 
1081 UINT32
1082 AcpiAnyGpeStatusSet (
1083     void)
1084 {
1085     ACPI_STATUS                Status;
1086     UINT8                      Ret;
1087 
1088 
1089     ACPI_FUNCTION_TRACE (AcpiAnyGpeStatusSet);
1090 
1091     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
1092     if (ACPI_FAILURE (Status))
1093     {
1094         return (FALSE);
1095     }
1096 
1097     Ret = AcpiHwCheckAllGpes ();
1098     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
1099 
1100     return (Ret);
1101 }
1102 
1103 ACPI_EXPORT_SYMBOL(AcpiAnyGpeStatusSet)
1104 
1105 
1106 /*******************************************************************************
1107  *
1108  * FUNCTION:    AcpiInstallGpeBlock
1109  *
1110  * PARAMETERS:  GpeDevice           - Handle to the parent GPE Block Device
1111  *              GpeBlockAddress     - Address and SpaceID
1112  *              RegisterCount       - Number of GPE register pairs in the block
1113  *              InterruptNumber     - H/W interrupt for the block
1114  *
1115  * RETURN:      Status
1116  *
1117  * DESCRIPTION: Create and Install a block of GPE registers. The GPEs are not
1118  *              enabled here.
1119  *
1120  ******************************************************************************/
1121 
1122 ACPI_STATUS
1123 AcpiInstallGpeBlock (
1124     ACPI_HANDLE             GpeDevice,
1125     ACPI_GENERIC_ADDRESS    *GpeBlockAddress,
1126     UINT32                  RegisterCount,
1127     UINT32                  InterruptNumber)
1128 {
1129     ACPI_STATUS             Status;
1130     ACPI_OPERAND_OBJECT     *ObjDesc;
1131     ACPI_NAMESPACE_NODE     *Node;
1132     ACPI_GPE_BLOCK_INFO     *GpeBlock;
1133 
1134 
1135     ACPI_FUNCTION_TRACE (AcpiInstallGpeBlock);
1136 
1137 
1138     if ((!GpeDevice)       ||
1139         (!GpeBlockAddress) ||
1140         (!RegisterCount))
1141     {
1142         return_ACPI_STATUS (AE_BAD_PARAMETER);
1143     }
1144 
1145     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
1146     if (ACPI_FAILURE (Status))
1147     {
1148         return_ACPI_STATUS (Status);
1149     }
1150 
1151     Node = AcpiNsValidateHandle (GpeDevice);
1152     if (!Node)
1153     {
1154         Status = AE_BAD_PARAMETER;
1155         goto UnlockAndExit;
1156     }
1157 
1158     /* Validate the parent device */
1159 
1160     if (Node->Type != ACPI_TYPE_DEVICE)
1161     {
1162         Status = AE_TYPE;
1163         goto UnlockAndExit;
1164     }
1165 
1166     if (Node->Object)
1167     {
1168         Status = AE_ALREADY_EXISTS;
1169         goto UnlockAndExit;
1170     }
1171 
1172     /*
1173      * For user-installed GPE Block Devices, the GpeBlockBaseNumber
1174      * is always zero
1175      */
1176     Status = AcpiEvCreateGpeBlock (Node, GpeBlockAddress->Address,
1177         GpeBlockAddress->SpaceId, RegisterCount,
1178         0, InterruptNumber, &GpeBlock);
1179     if (ACPI_FAILURE (Status))
1180     {
1181         goto UnlockAndExit;
1182     }
1183 
1184     /* Install block in the DeviceObject attached to the node */
1185 
1186     ObjDesc = AcpiNsGetAttachedObject (Node);
1187     if (!ObjDesc)
1188     {
1189         /*
1190          * No object, create a new one (Device nodes do not always have
1191          * an attached object)
1192          */
1193         ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_DEVICE);
1194         if (!ObjDesc)
1195         {
1196             Status = AE_NO_MEMORY;
1197             goto UnlockAndExit;
1198         }
1199 
1200         Status = AcpiNsAttachObject (Node, ObjDesc, ACPI_TYPE_DEVICE);
1201 
1202         /* Remove local reference to the object */
1203 
1204         AcpiUtRemoveReference (ObjDesc);
1205         if (ACPI_FAILURE (Status))
1206         {
1207             goto UnlockAndExit;
1208         }
1209     }
1210 
1211     /* Now install the GPE block in the DeviceObject */
1212 
1213     ObjDesc->Device.GpeBlock = GpeBlock;
1214 
1215 
1216 UnlockAndExit:
1217     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
1218     return_ACPI_STATUS (Status);
1219 }
1220 
1221 ACPI_EXPORT_SYMBOL (AcpiInstallGpeBlock)
1222 
1223 
1224 /*******************************************************************************
1225  *
1226  * FUNCTION:    AcpiRemoveGpeBlock
1227  *
1228  * PARAMETERS:  GpeDevice           - Handle to the parent GPE Block Device
1229  *
1230  * RETURN:      Status
1231  *
1232  * DESCRIPTION: Remove a previously installed block of GPE registers
1233  *
1234  ******************************************************************************/
1235 
1236 ACPI_STATUS
1237 AcpiRemoveGpeBlock (
1238     ACPI_HANDLE             GpeDevice)
1239 {
1240     ACPI_OPERAND_OBJECT     *ObjDesc;
1241     ACPI_STATUS             Status;
1242     ACPI_NAMESPACE_NODE     *Node;
1243 
1244 
1245     ACPI_FUNCTION_TRACE (AcpiRemoveGpeBlock);
1246 
1247 
1248     if (!GpeDevice)
1249     {
1250         return_ACPI_STATUS (AE_BAD_PARAMETER);
1251     }
1252 
1253     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
1254     if (ACPI_FAILURE (Status))
1255     {
1256         return_ACPI_STATUS (Status);
1257     }
1258 
1259     Node = AcpiNsValidateHandle (GpeDevice);
1260     if (!Node)
1261     {
1262         Status = AE_BAD_PARAMETER;
1263         goto UnlockAndExit;
1264     }
1265 
1266     /* Validate the parent device */
1267 
1268     if (Node->Type != ACPI_TYPE_DEVICE)
1269     {
1270         Status = AE_TYPE;
1271         goto UnlockAndExit;
1272     }
1273 
1274     /* Get the DeviceObject attached to the node */
1275 
1276     ObjDesc = AcpiNsGetAttachedObject (Node);
1277     if (!ObjDesc ||
1278         !ObjDesc->Device.GpeBlock)
1279     {
1280         return_ACPI_STATUS (AE_NULL_OBJECT);
1281     }
1282 
1283     /* Delete the GPE block (but not the DeviceObject) */
1284 
1285     Status = AcpiEvDeleteGpeBlock (ObjDesc->Device.GpeBlock);
1286     if (ACPI_SUCCESS (Status))
1287     {
1288         ObjDesc->Device.GpeBlock = NULL;
1289     }
1290 
1291 UnlockAndExit:
1292     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
1293     return_ACPI_STATUS (Status);
1294 }
1295 
1296 ACPI_EXPORT_SYMBOL (AcpiRemoveGpeBlock)
1297 
1298 
1299 /*******************************************************************************
1300  *
1301  * FUNCTION:    AcpiGetGpeDevice
1302  *
1303  * PARAMETERS:  Index               - System GPE index (0-CurrentGpeCount)
1304  *              GpeDevice           - Where the parent GPE Device is returned
1305  *
1306  * RETURN:      Status
1307  *
1308  * DESCRIPTION: Obtain the GPE device associated with the input index. A NULL
1309  *              gpe device indicates that the gpe number is contained in one of
1310  *              the FADT-defined gpe blocks. Otherwise, the GPE block device.
1311  *
1312  ******************************************************************************/
1313 
1314 ACPI_STATUS
1315 AcpiGetGpeDevice (
1316     UINT32                  Index,
1317     ACPI_HANDLE             *GpeDevice)
1318 {
1319     ACPI_GPE_DEVICE_INFO    Info;
1320     ACPI_STATUS             Status;
1321 
1322 
1323     ACPI_FUNCTION_TRACE (AcpiGetGpeDevice);
1324 
1325 
1326     if (!GpeDevice)
1327     {
1328         return_ACPI_STATUS (AE_BAD_PARAMETER);
1329     }
1330 
1331     if (Index >= AcpiCurrentGpeCount)
1332     {
1333         return_ACPI_STATUS (AE_NOT_EXIST);
1334     }
1335 
1336     /* Setup and walk the GPE list */
1337 
1338     Info.Index = Index;
1339     Info.Status = AE_NOT_EXIST;
1340     Info.GpeDevice = NULL;
1341     Info.NextBlockBaseIndex = 0;
1342 
1343     Status = AcpiEvWalkGpeList (AcpiEvGetGpeDevice, &Info);
1344     if (ACPI_FAILURE (Status))
1345     {
1346         return_ACPI_STATUS (Status);
1347     }
1348 
1349     *GpeDevice = ACPI_CAST_PTR (ACPI_HANDLE, Info.GpeDevice);
1350     return_ACPI_STATUS (Info.Status);
1351 }
1352 
1353 ACPI_EXPORT_SYMBOL (AcpiGetGpeDevice)
1354 
1355 #endif /* !ACPI_REDUCED_HARDWARE */