The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/contrib/dev/acpica/components/events/evxfgpe.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /******************************************************************************
    2  *
    3  * Module Name: evxfgpe - External Interfaces for General Purpose Events (GPEs)
    4  *
    5  *****************************************************************************/
    6 
    7 /******************************************************************************
    8  *
    9  * 1. Copyright Notice
   10  *
   11  * Some or all of this work - Copyright (c) 1999 - 2022, Intel Corp.
   12  * All rights reserved.
   13  *
   14  * 2. License
   15  *
   16  * 2.1. This is your license from Intel Corp. under its intellectual property
   17  * rights. You may have additional license terms from the party that provided
   18  * you this software, covering your right to use that party's intellectual
   19  * property rights.
   20  *
   21  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
   22  * copy of the source code appearing in this file ("Covered Code") an
   23  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
   24  * base code distributed originally by Intel ("Original Intel Code") to copy,
   25  * make derivatives, distribute, use and display any portion of the Covered
   26  * Code in any form, with the right to sublicense such rights; and
   27  *
   28  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
   29  * license (with the right to sublicense), under only those claims of Intel
   30  * patents that are infringed by the Original Intel Code, to make, use, sell,
   31  * offer to sell, and import the Covered Code and derivative works thereof
   32  * solely to the minimum extent necessary to exercise the above copyright
   33  * license, and in no event shall the patent license extend to any additions
   34  * to or modifications of the Original Intel Code. No other license or right
   35  * is granted directly or by implication, estoppel or otherwise;
   36  *
   37  * The above copyright and patent license is granted only if the following
   38  * conditions are met:
   39  *
   40  * 3. Conditions
   41  *
   42  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
   43  * Redistribution of source code of any substantial portion of the Covered
   44  * Code or modification with rights to further distribute source must include
   45  * the above Copyright Notice, the above License, this list of Conditions,
   46  * and the following Disclaimer and Export Compliance provision. In addition,
   47  * Licensee must cause all Covered Code to which Licensee contributes to
   48  * contain a file documenting the changes Licensee made to create that Covered
   49  * Code and the date of any change. Licensee must include in that file the
   50  * documentation of any changes made by any predecessor Licensee. Licensee
   51  * must include a prominent statement that the modification is derived,
   52  * directly or indirectly, from Original Intel Code.
   53  *
   54  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
   55  * Redistribution of source code of any substantial portion of the Covered
   56  * Code or modification without rights to further distribute source must
   57  * include the following Disclaimer and Export Compliance provision in the
   58  * documentation and/or other materials provided with distribution. In
   59  * addition, Licensee may not authorize further sublicense of source of any
   60  * portion of the Covered Code, and must include terms to the effect that the
   61  * license from Licensee to its licensee is limited to the intellectual
   62  * property embodied in the software Licensee provides to its licensee, and
   63  * not to intellectual property embodied in modifications its licensee may
   64  * make.
   65  *
   66  * 3.3. Redistribution of Executable. Redistribution in executable form of any
   67  * substantial portion of the Covered Code or modification must reproduce the
   68  * above Copyright Notice, and the following Disclaimer and Export Compliance
   69  * provision in the documentation and/or other materials provided with the
   70  * distribution.
   71  *
   72  * 3.4. Intel retains all right, title, and interest in and to the Original
   73  * Intel Code.
   74  *
   75  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
   76  * Intel shall be used in advertising or otherwise to promote the sale, use or
   77  * other dealings in products derived from or relating to the Covered Code
   78  * without prior written authorization from Intel.
   79  *
   80  * 4. Disclaimer and Export Compliance
   81  *
   82  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
   83  * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
   84  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
   85  * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
   86  * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
   87  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
   88  * PARTICULAR PURPOSE.
   89  *
   90  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
   91  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
   92  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
   93  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
   94  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
   95  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
   96  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
   97  * LIMITED REMEDY.
   98  *
   99  * 4.3. Licensee shall not export, either directly or indirectly, any of this
  100  * software or system incorporating such software without first obtaining any
  101  * required license or other approval from the U. S. Department of Commerce or
  102  * any other agency or department of the United States Government. In the
  103  * event Licensee exports any such software from the United States or
  104  * re-exports any such software from a foreign destination, Licensee shall
  105  * ensure that the distribution and export/re-export of the software is in
  106  * compliance with all laws, regulations, orders, or other restrictions of the
  107  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
  108  * any of its subsidiaries will export/re-export any technical data, process,
  109  * software, or service, directly or indirectly, to any country for which the
  110  * United States government or any agency thereof requires an export license,
  111  * other governmental approval, or letter of assurance, without first obtaining
  112  * such license, approval or letter.
  113  *
  114  *****************************************************************************
  115  *
  116  * Alternatively, you may choose to be licensed under the terms of the
  117  * following license:
  118  *
  119  * Redistribution and use in source and binary forms, with or without
  120  * modification, are permitted provided that the following conditions
  121  * are met:
  122  * 1. Redistributions of source code must retain the above copyright
  123  *    notice, this list of conditions, and the following disclaimer,
  124  *    without modification.
  125  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
  126  *    substantially similar to the "NO WARRANTY" disclaimer below
  127  *    ("Disclaimer") and any redistribution must be conditioned upon
  128  *    including a substantially similar Disclaimer requirement for further
  129  *    binary redistribution.
  130  * 3. Neither the names of the above-listed copyright holders nor the names
  131  *    of any contributors may be used to endorse or promote products derived
  132  *    from this software without specific prior written permission.
  133  *
  134  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  135  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  136  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  137  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  138  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  139  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  140  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  141  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  142  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  143  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  144  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  145  *
  146  * Alternatively, you may choose to be licensed under the terms of the
  147  * GNU General Public License ("GPL") version 2 as published by the Free
  148  * Software Foundation.
  149  *
  150  *****************************************************************************/
  151 
  152 #define EXPORT_ACPI_INTERFACES
  153 
  154 #include <contrib/dev/acpica/include/acpi.h>
  155 #include <contrib/dev/acpica/include/accommon.h>
  156 #include <contrib/dev/acpica/include/acevents.h>
  157 #include <contrib/dev/acpica/include/acnamesp.h>
  158 
  159 #define _COMPONENT          ACPI_EVENTS
  160         ACPI_MODULE_NAME    ("evxfgpe")
  161 
  162 
  163 #if (!ACPI_REDUCED_HARDWARE) /* Entire module */
  164 /*******************************************************************************
  165  *
  166  * FUNCTION:    AcpiUpdateAllGpes
  167  *
  168  * PARAMETERS:  None
  169  *
  170  * RETURN:      Status
  171  *
  172  * DESCRIPTION: Complete GPE initialization and enable all GPEs that have
  173  *              associated _Lxx or _Exx methods and are not pointed to by any
  174  *              device _PRW methods (this indicates that these GPEs are
  175  *              generally intended for system or device wakeup. Such GPEs
  176  *              have to be enabled directly when the devices whose _PRW
  177  *              methods point to them are set up for wakeup signaling.)
  178  *
  179  * NOTE: Should be called after any GPEs are added to the system. Primarily,
  180  * after the system _PRW methods have been run, but also after a GPE Block
  181  * Device has been added or if any new GPE methods have been added via a
  182  * dynamic table load.
  183  *
  184  ******************************************************************************/
  185 
  186 ACPI_STATUS
  187 AcpiUpdateAllGpes (
  188     void)
  189 {
  190     ACPI_STATUS             Status;
  191     BOOLEAN                 IsPollingNeeded = FALSE;
  192 
  193 
  194     ACPI_FUNCTION_TRACE (AcpiUpdateAllGpes);
  195 
  196 
  197     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
  198     if (ACPI_FAILURE (Status))
  199     {
  200         return_ACPI_STATUS (Status);
  201     }
  202 
  203     if (AcpiGbl_AllGpesInitialized)
  204     {
  205         goto UnlockAndExit;
  206     }
  207 
  208     Status = AcpiEvWalkGpeList (AcpiEvInitializeGpeBlock,
  209         &IsPollingNeeded);
  210     if (ACPI_SUCCESS (Status))
  211     {
  212         AcpiGbl_AllGpesInitialized = TRUE;
  213     }
  214 
  215 UnlockAndExit:
  216     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
  217 
  218     if (IsPollingNeeded && AcpiGbl_AllGpesInitialized)
  219     {
  220         /* Poll GPEs to handle already triggered events */
  221 
  222         AcpiEvGpeDetect (AcpiGbl_GpeXruptListHead);
  223     }
  224     return_ACPI_STATUS (Status);
  225 }
  226 
  227 ACPI_EXPORT_SYMBOL (AcpiUpdateAllGpes)
  228 
  229 
  230 /*******************************************************************************
  231  *
  232  * FUNCTION:    AcpiEnableGpe
  233  *
  234  * PARAMETERS:  GpeDevice           - Parent GPE Device. NULL for GPE0/GPE1
  235  *              GpeNumber           - GPE level within the GPE block
  236  *
  237  * RETURN:      Status
  238  *
  239  * DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is
  240  *              hardware-enabled.
  241  *
  242  ******************************************************************************/
  243 
  244 ACPI_STATUS
  245 AcpiEnableGpe (
  246     ACPI_HANDLE             GpeDevice,
  247     UINT32                  GpeNumber)
  248 {
  249     ACPI_STATUS             Status = AE_BAD_PARAMETER;
  250     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
  251     ACPI_CPU_FLAGS          Flags;
  252 
  253 
  254     ACPI_FUNCTION_TRACE (AcpiEnableGpe);
  255 
  256 
  257     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
  258 
  259     /*
  260      * Ensure that we have a valid GPE number and that there is some way
  261      * of handling the GPE (handler or a GPE method). In other words, we
  262      * won't allow a valid GPE to be enabled if there is no way to handle it.
  263      */
  264     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
  265     if (GpeEventInfo)
  266     {
  267         if (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) !=
  268             ACPI_GPE_DISPATCH_NONE)
  269         {
  270             Status = AcpiEvAddGpeReference (GpeEventInfo, TRUE);
  271             if (ACPI_SUCCESS (Status) &&
  272                 ACPI_GPE_IS_POLLING_NEEDED (GpeEventInfo))
  273             {
  274                 /* Poll edge-triggered GPEs to handle existing events */
  275 
  276                 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
  277                 (void) AcpiEvDetectGpe (
  278                     GpeDevice, GpeEventInfo, GpeNumber);
  279                 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
  280             }
  281         }
  282         else
  283         {
  284             Status = AE_NO_HANDLER;
  285         }
  286     }
  287 
  288     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
  289     return_ACPI_STATUS (Status);
  290 }
  291 
  292 ACPI_EXPORT_SYMBOL (AcpiEnableGpe)
  293 
  294 
  295 /*******************************************************************************
  296  *
  297  * FUNCTION:    AcpiDisableGpe
  298  *
  299  * PARAMETERS:  GpeDevice           - Parent GPE Device. NULL for GPE0/GPE1
  300  *              GpeNumber           - GPE level within the GPE block
  301  *
  302  * RETURN:      Status
  303  *
  304  * DESCRIPTION: Remove a reference to a GPE. When the last reference is
  305  *              removed, only then is the GPE disabled (for runtime GPEs), or
  306  *              the GPE mask bit disabled (for wake GPEs)
  307  *
  308  ******************************************************************************/
  309 
  310 ACPI_STATUS
  311 AcpiDisableGpe (
  312     ACPI_HANDLE             GpeDevice,
  313     UINT32                  GpeNumber)
  314 {
  315     ACPI_STATUS             Status = AE_BAD_PARAMETER;
  316     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
  317     ACPI_CPU_FLAGS          Flags;
  318 
  319 
  320     ACPI_FUNCTION_TRACE (AcpiDisableGpe);
  321 
  322 
  323     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
  324 
  325     /* Ensure that we have a valid GPE number */
  326 
  327     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
  328     if (GpeEventInfo)
  329     {
  330         Status = AcpiEvRemoveGpeReference (GpeEventInfo);
  331     }
  332 
  333     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
  334     return_ACPI_STATUS (Status);
  335 }
  336 
  337 ACPI_EXPORT_SYMBOL (AcpiDisableGpe)
  338 
  339 
  340 /*******************************************************************************
  341  *
  342  * FUNCTION:    AcpiSetGpe
  343  *
  344  * PARAMETERS:  GpeDevice           - Parent GPE Device. NULL for GPE0/GPE1
  345  *              GpeNumber           - GPE level within the GPE block
  346  *              Action              - ACPI_GPE_ENABLE or ACPI_GPE_DISABLE
  347  *
  348  * RETURN:      Status
  349  *
  350  * DESCRIPTION: Enable or disable an individual GPE. This function bypasses
  351  *              the reference count mechanism used in the AcpiEnableGpe(),
  352  *              AcpiDisableGpe() interfaces.
  353  *              This API is typically used by the GPE raw handler mode driver
  354  *              to switch between the polling mode and the interrupt mode after
  355  *              the driver has enabled the GPE.
  356  *              The APIs should be invoked in this order:
  357  *               AcpiEnableGpe()              <- Ensure the reference count > 0
  358  *               AcpiSetGpe(ACPI_GPE_DISABLE) <- Enter polling mode
  359  *               AcpiSetGpe(ACPI_GPE_ENABLE)  <- Leave polling mode
  360  *               AcpiDisableGpe()             <- Decrease the reference count
  361  *
  362  * Note: If a GPE is shared by 2 silicon components, then both the drivers
  363  *       should support GPE polling mode or disabling the GPE for long period
  364  *       for one driver may break the other. So use it with care since all
  365  *       firmware _Lxx/_Exx handlers currently rely on the GPE interrupt mode.
  366  *
  367  ******************************************************************************/
  368 
  369 ACPI_STATUS
  370 AcpiSetGpe (
  371     ACPI_HANDLE             GpeDevice,
  372     UINT32                  GpeNumber,
  373     UINT8                   Action)
  374 {
  375     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
  376     ACPI_STATUS             Status;
  377     ACPI_CPU_FLAGS          Flags;
  378 
  379 
  380     ACPI_FUNCTION_TRACE (AcpiSetGpe);
  381 
  382 
  383     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
  384 
  385     /* Ensure that we have a valid GPE number */
  386 
  387     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
  388     if (!GpeEventInfo)
  389     {
  390         Status = AE_BAD_PARAMETER;
  391         goto UnlockAndExit;
  392     }
  393 
  394     /* Perform the action */
  395 
  396     switch (Action)
  397     {
  398     case ACPI_GPE_ENABLE:
  399 
  400         Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_ENABLE);
  401         GpeEventInfo->DisableForDispatch = FALSE;
  402         break;
  403 
  404     case ACPI_GPE_DISABLE:
  405 
  406         Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_DISABLE);
  407         GpeEventInfo->DisableForDispatch = TRUE;
  408         break;
  409 
  410     default:
  411 
  412         Status = AE_BAD_PARAMETER;
  413         break;
  414     }
  415 
  416 UnlockAndExit:
  417     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
  418     return_ACPI_STATUS (Status);
  419 }
  420 
  421 ACPI_EXPORT_SYMBOL (AcpiSetGpe)
  422 
  423 
  424 /*******************************************************************************
  425  *
  426  * FUNCTION:    AcpiMaskGpe
  427  *
  428  * PARAMETERS:  GpeDevice           - Parent GPE Device. NULL for GPE0/GPE1
  429  *              GpeNumber           - GPE level within the GPE block
  430  *              IsMasked            - Whether the GPE is masked or not
  431  *
  432  * RETURN:      Status
  433  *
  434  * DESCRIPTION: Unconditionally mask/unmask the an individual GPE, ex., to
  435  *              prevent a GPE flooding.
  436  *
  437  ******************************************************************************/
  438 
  439 ACPI_STATUS
  440 AcpiMaskGpe (
  441     ACPI_HANDLE             GpeDevice,
  442     UINT32                  GpeNumber,
  443     BOOLEAN                 IsMasked)
  444 {
  445     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
  446     ACPI_STATUS             Status;
  447     ACPI_CPU_FLAGS          Flags;
  448 
  449 
  450     ACPI_FUNCTION_TRACE (AcpiMaskGpe);
  451 
  452 
  453     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
  454 
  455     /* Ensure that we have a valid GPE number */
  456 
  457     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
  458     if (!GpeEventInfo)
  459     {
  460         Status = AE_BAD_PARAMETER;
  461         goto UnlockAndExit;
  462     }
  463 
  464     Status = AcpiEvMaskGpe (GpeEventInfo, IsMasked);
  465 
  466 UnlockAndExit:
  467     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
  468     return_ACPI_STATUS (Status);
  469 }
  470 
  471 ACPI_EXPORT_SYMBOL (AcpiMaskGpe)
  472 
  473 
  474 /*******************************************************************************
  475  *
  476  * FUNCTION:    AcpiMarkGpeForWake
  477  *
  478  * PARAMETERS:  GpeDevice           - Parent GPE Device. NULL for GPE0/GPE1
  479  *              GpeNumber           - GPE level within the GPE block
  480  *
  481  * RETURN:      Status
  482  *
  483  * DESCRIPTION: Mark a GPE as having the ability to wake the system. Simply
  484  *              sets the ACPI_GPE_CAN_WAKE flag.
  485  *
  486  * Some potential callers of AcpiSetupGpeForWake may know in advance that
  487  * there won't be any notify handlers installed for device wake notifications
  488  * from the given GPE (one example is a button GPE in Linux). For these cases,
  489  * AcpiMarkGpeForWake should be used instead of AcpiSetupGpeForWake.
  490  * This will set the ACPI_GPE_CAN_WAKE flag for the GPE without trying to
  491  * setup implicit wake notification for it (since there's no handler method).
  492  *
  493  ******************************************************************************/
  494 
  495 ACPI_STATUS
  496 AcpiMarkGpeForWake (
  497     ACPI_HANDLE             GpeDevice,
  498     UINT32                  GpeNumber)
  499 {
  500     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
  501     ACPI_STATUS             Status = AE_BAD_PARAMETER;
  502     ACPI_CPU_FLAGS          Flags;
  503 
  504 
  505     ACPI_FUNCTION_TRACE (AcpiMarkGpeForWake);
  506 
  507 
  508     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
  509 
  510     /* Ensure that we have a valid GPE number */
  511 
  512     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
  513     if (GpeEventInfo)
  514     {
  515         /* Mark the GPE as a possible wake event */
  516 
  517         GpeEventInfo->Flags |= ACPI_GPE_CAN_WAKE;
  518         Status = AE_OK;
  519     }
  520 
  521     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
  522     return_ACPI_STATUS (Status);
  523 }
  524 
  525 ACPI_EXPORT_SYMBOL (AcpiMarkGpeForWake)
  526 
  527 
  528 /*******************************************************************************
  529  *
  530  * FUNCTION:    AcpiSetupGpeForWake
  531  *
  532  * PARAMETERS:  WakeDevice          - Device associated with the GPE (via _PRW)
  533  *              GpeDevice           - Parent GPE Device. NULL for GPE0/GPE1
  534  *              GpeNumber           - GPE level within the GPE block
  535  *
  536  * RETURN:      Status
  537  *
  538  * DESCRIPTION: Mark a GPE as having the ability to wake the system. This
  539  *              interface is intended to be used as the host executes the
  540  *              _PRW methods (Power Resources for Wake) in the system tables.
  541  *              Each _PRW appears under a Device Object (The WakeDevice), and
  542  *              contains the info for the wake GPE associated with the
  543  *              WakeDevice.
  544  *
  545  ******************************************************************************/
  546 
  547 ACPI_STATUS
  548 AcpiSetupGpeForWake (
  549     ACPI_HANDLE             WakeDevice,
  550     ACPI_HANDLE             GpeDevice,
  551     UINT32                  GpeNumber)
  552 {
  553     ACPI_STATUS             Status;
  554     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
  555     ACPI_NAMESPACE_NODE     *DeviceNode;
  556     ACPI_GPE_NOTIFY_INFO    *Notify;
  557     ACPI_GPE_NOTIFY_INFO    *NewNotify;
  558     ACPI_CPU_FLAGS          Flags;
  559 
  560 
  561     ACPI_FUNCTION_TRACE (AcpiSetupGpeForWake);
  562 
  563 
  564     /* Parameter Validation */
  565 
  566     if (!WakeDevice)
  567     {
  568         /*
  569          * By forcing WakeDevice to be valid, we automatically enable the
  570          * implicit notify feature on all hosts.
  571          */
  572         return_ACPI_STATUS (AE_BAD_PARAMETER);
  573     }
  574 
  575     /* Handle root object case */
  576 
  577     if (WakeDevice == ACPI_ROOT_OBJECT)
  578     {
  579         DeviceNode = AcpiGbl_RootNode;
  580     }
  581     else
  582     {
  583         DeviceNode = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, WakeDevice);
  584     }
  585 
  586     /* Validate WakeDevice is of type Device */
  587 
  588     if (DeviceNode->Type != ACPI_TYPE_DEVICE)
  589     {
  590         return_ACPI_STATUS (AE_BAD_PARAMETER);
  591     }
  592 
  593     /*
  594      * Allocate a new notify object up front, in case it is needed.
  595      * Memory allocation while holding a spinlock is a big no-no
  596      * on some hosts.
  597      */
  598     NewNotify = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_GPE_NOTIFY_INFO));
  599     if (!NewNotify)
  600     {
  601         return_ACPI_STATUS (AE_NO_MEMORY);
  602     }
  603 
  604     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
  605 
  606     /* Ensure that we have a valid GPE number */
  607 
  608     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
  609     if (!GpeEventInfo)
  610     {
  611         Status = AE_BAD_PARAMETER;
  612         goto UnlockAndExit;
  613     }
  614 
  615     /*
  616      * If there is no method or handler for this GPE, then the
  617      * WakeDevice will be notified whenever this GPE fires. This is
  618      * known as an "implicit notify". Note: The GPE is assumed to be
  619      * level-triggered (for windows compatibility).
  620      */
  621     if (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) ==
  622         ACPI_GPE_DISPATCH_NONE)
  623     {
  624         /*
  625          * This is the first device for implicit notify on this GPE.
  626          * Just set the flags here, and enter the NOTIFY block below.
  627          */
  628         GpeEventInfo->Flags =
  629             (ACPI_GPE_DISPATCH_NOTIFY | ACPI_GPE_LEVEL_TRIGGERED);
  630     }
  631     else if (GpeEventInfo->Flags & ACPI_GPE_AUTO_ENABLED)
  632     {
  633         /*
  634          * A reference to this GPE has been added during the GPE block
  635          * initialization, so drop it now to prevent the GPE from being
  636          * permanently enabled and clear its ACPI_GPE_AUTO_ENABLED flag.
  637          */
  638         (void) AcpiEvRemoveGpeReference (GpeEventInfo);
  639         GpeEventInfo->Flags &= ~~ACPI_GPE_AUTO_ENABLED;
  640     }
  641 
  642     /*
  643      * If we already have an implicit notify on this GPE, add
  644      * this device to the notify list.
  645      */
  646     if (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) ==
  647         ACPI_GPE_DISPATCH_NOTIFY)
  648     {
  649         /* Ensure that the device is not already in the list */
  650 
  651         Notify = GpeEventInfo->Dispatch.NotifyList;
  652         while (Notify)
  653         {
  654             if (Notify->DeviceNode == DeviceNode)
  655             {
  656                 Status = AE_ALREADY_EXISTS;
  657                 goto UnlockAndExit;
  658             }
  659             Notify = Notify->Next;
  660         }
  661 
  662         /* Add this device to the notify list for this GPE */
  663 
  664         NewNotify->DeviceNode = DeviceNode;
  665         NewNotify->Next = GpeEventInfo->Dispatch.NotifyList;
  666         GpeEventInfo->Dispatch.NotifyList = NewNotify;
  667         NewNotify = NULL;
  668     }
  669 
  670     /* Mark the GPE as a possible wake event */
  671 
  672     GpeEventInfo->Flags |= ACPI_GPE_CAN_WAKE;
  673     Status = AE_OK;
  674 
  675 
  676 UnlockAndExit:
  677     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
  678 
  679     /* Delete the notify object if it was not used above */
  680 
  681     if (NewNotify)
  682     {
  683         ACPI_FREE (NewNotify);
  684     }
  685     return_ACPI_STATUS (Status);
  686 }
  687 
  688 ACPI_EXPORT_SYMBOL (AcpiSetupGpeForWake)
  689 
  690 
  691 /*******************************************************************************
  692  *
  693  * FUNCTION:    AcpiSetGpeWakeMask
  694  *
  695  * PARAMETERS:  GpeDevice           - Parent GPE Device. NULL for GPE0/GPE1
  696  *              GpeNumber           - GPE level within the GPE block
  697  *              Action              - Enable or Disable
  698  *
  699  * RETURN:      Status
  700  *
  701  * DESCRIPTION: Set or clear the GPE's wakeup enable mask bit. The GPE must
  702  *              already be marked as a WAKE GPE.
  703  *
  704  ******************************************************************************/
  705 
  706 ACPI_STATUS
  707 AcpiSetGpeWakeMask (
  708     ACPI_HANDLE             GpeDevice,
  709     UINT32                  GpeNumber,
  710     UINT8                   Action)
  711 {
  712     ACPI_STATUS             Status = AE_OK;
  713     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
  714     ACPI_GPE_REGISTER_INFO  *GpeRegisterInfo;
  715     ACPI_CPU_FLAGS          Flags;
  716     UINT32                  RegisterBit;
  717 
  718 
  719     ACPI_FUNCTION_TRACE (AcpiSetGpeWakeMask);
  720 
  721 
  722     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
  723 
  724     /*
  725      * Ensure that we have a valid GPE number and that this GPE is in
  726      * fact a wake GPE
  727      */
  728     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
  729     if (!GpeEventInfo)
  730     {
  731         Status = AE_BAD_PARAMETER;
  732         goto UnlockAndExit;
  733     }
  734 
  735     if (!(GpeEventInfo->Flags & ACPI_GPE_CAN_WAKE))
  736     {
  737         Status = AE_TYPE;
  738         goto UnlockAndExit;
  739     }
  740 
  741     GpeRegisterInfo = GpeEventInfo->RegisterInfo;
  742     if (!GpeRegisterInfo)
  743     {
  744         Status = AE_NOT_EXIST;
  745         goto UnlockAndExit;
  746     }
  747 
  748     RegisterBit = AcpiHwGetGpeRegisterBit (GpeEventInfo);
  749 
  750     /* Perform the action */
  751 
  752     switch (Action)
  753     {
  754     case ACPI_GPE_ENABLE:
  755 
  756         ACPI_SET_BIT (GpeRegisterInfo->EnableForWake, (UINT8) RegisterBit);
  757         break;
  758 
  759     case ACPI_GPE_DISABLE:
  760 
  761         ACPI_CLEAR_BIT (GpeRegisterInfo->EnableForWake, (UINT8) RegisterBit);
  762         break;
  763 
  764     default:
  765 
  766         ACPI_ERROR ((AE_INFO, "%u, Invalid action", Action));
  767         Status = AE_BAD_PARAMETER;
  768         break;
  769     }
  770 
  771 UnlockAndExit:
  772     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
  773     return_ACPI_STATUS (Status);
  774 }
  775 
  776 ACPI_EXPORT_SYMBOL (AcpiSetGpeWakeMask)
  777 
  778 
  779 /*******************************************************************************
  780  *
  781  * FUNCTION:    AcpiClearGpe
  782  *
  783  * PARAMETERS:  GpeDevice           - Parent GPE Device. NULL for GPE0/GPE1
  784  *              GpeNumber           - GPE level within the GPE block
  785  *
  786  * RETURN:      Status
  787  *
  788  * DESCRIPTION: Clear an ACPI event (general purpose)
  789  *
  790  ******************************************************************************/
  791 
  792 ACPI_STATUS
  793 AcpiClearGpe (
  794     ACPI_HANDLE             GpeDevice,
  795     UINT32                  GpeNumber)
  796 {
  797     ACPI_STATUS             Status = AE_OK;
  798     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
  799     ACPI_CPU_FLAGS          Flags;
  800 
  801 
  802     ACPI_FUNCTION_TRACE (AcpiClearGpe);
  803 
  804 
  805     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
  806 
  807     /* Ensure that we have a valid GPE number */
  808 
  809     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
  810     if (!GpeEventInfo)
  811     {
  812         Status = AE_BAD_PARAMETER;
  813         goto UnlockAndExit;
  814     }
  815 
  816     Status = AcpiHwClearGpe (GpeEventInfo);
  817 
  818 UnlockAndExit:
  819     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
  820     return_ACPI_STATUS (Status);
  821 }
  822 
  823 ACPI_EXPORT_SYMBOL (AcpiClearGpe)
  824 
  825 
  826 /*******************************************************************************
  827  *
  828  * FUNCTION:    AcpiGetGpeStatus
  829  *
  830  * PARAMETERS:  GpeDevice           - Parent GPE Device. NULL for GPE0/GPE1
  831  *              GpeNumber           - GPE level within the GPE block
  832  *              EventStatus         - Where the current status of the event
  833  *                                    will be returned
  834  *
  835  * RETURN:      Status
  836  *
  837  * DESCRIPTION: Get the current status of a GPE (signalled/not_signalled)
  838  *
  839  ******************************************************************************/
  840 
  841 ACPI_STATUS
  842 AcpiGetGpeStatus (
  843     ACPI_HANDLE             GpeDevice,
  844     UINT32                  GpeNumber,
  845     ACPI_EVENT_STATUS       *EventStatus)
  846 {
  847     ACPI_STATUS             Status = AE_OK;
  848     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
  849     ACPI_CPU_FLAGS          Flags;
  850 
  851 
  852     ACPI_FUNCTION_TRACE (AcpiGetGpeStatus);
  853 
  854 
  855     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
  856 
  857     /* Ensure that we have a valid GPE number */
  858 
  859     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
  860     if (!GpeEventInfo)
  861     {
  862         Status = AE_BAD_PARAMETER;
  863         goto UnlockAndExit;
  864     }
  865 
  866     /* Obtain status on the requested GPE number */
  867 
  868     Status = AcpiHwGetGpeStatus (GpeEventInfo, EventStatus);
  869 
  870 UnlockAndExit:
  871     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
  872     return_ACPI_STATUS (Status);
  873 }
  874 
  875 ACPI_EXPORT_SYMBOL (AcpiGetGpeStatus)
  876 
  877 
  878 /*******************************************************************************
  879  *
  880  * FUNCTION:    AcpiDispatchGpe
  881  *
  882  * PARAMETERS:  GpeDevice           - Parent GPE Device. NULL for GPE0/GPE1
  883  *              GpeNumber           - GPE level within the GPE block
  884  *
  885  * RETURN:      INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED
  886  *
  887  * DESCRIPTION: Detect and dispatch a General Purpose Event to either a function
  888  *              (e.g. EC) or method (e.g. _Lxx/_Exx) handler.
  889  *
  890  ******************************************************************************/
  891 
  892 UINT32
  893 AcpiDispatchGpe(
  894     ACPI_HANDLE             GpeDevice,
  895     UINT32                  GpeNumber)
  896 {
  897     ACPI_FUNCTION_TRACE(acpi_dispatch_gpe);
  898 
  899     return (AcpiEvDetectGpe (GpeDevice, NULL, GpeNumber));
  900 }
  901 
  902 ACPI_EXPORT_SYMBOL (AcpiDispatchGpe)
  903 
  904 
  905 /*******************************************************************************
  906  *
  907  * FUNCTION:    AcpiFinishGpe
  908  *
  909  * PARAMETERS:  GpeDevice           - Namespace node for the GPE Block
  910  *                                    (NULL for FADT defined GPEs)
  911  *              GpeNumber           - GPE level within the GPE block
  912  *
  913  * RETURN:      Status
  914  *
  915  * DESCRIPTION: Clear and conditionally re-enable a GPE. This completes the GPE
  916  *              processing. Intended for use by asynchronous host-installed
  917  *              GPE handlers. The GPE is only re-enabled if the EnableForRun bit
  918  *              is set in the GPE info.
  919  *
  920  ******************************************************************************/
  921 
  922 ACPI_STATUS
  923 AcpiFinishGpe (
  924     ACPI_HANDLE             GpeDevice,
  925     UINT32                  GpeNumber)
  926 {
  927     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
  928     ACPI_STATUS             Status;
  929     ACPI_CPU_FLAGS          Flags;
  930 
  931 
  932     ACPI_FUNCTION_TRACE (AcpiFinishGpe);
  933 
  934 
  935     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
  936 
  937     /* Ensure that we have a valid GPE number */
  938 
  939     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
  940     if (!GpeEventInfo)
  941     {
  942         Status = AE_BAD_PARAMETER;
  943         goto UnlockAndExit;
  944     }
  945 
  946     Status = AcpiEvFinishGpe (GpeEventInfo);
  947 
  948 UnlockAndExit:
  949     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
  950     return_ACPI_STATUS (Status);
  951 }
  952 
  953 ACPI_EXPORT_SYMBOL (AcpiFinishGpe)
  954 
  955 
  956 /******************************************************************************
  957  *
  958  * FUNCTION:    AcpiDisableAllGpes
  959  *
  960  * PARAMETERS:  None
  961  *
  962  * RETURN:      Status
  963  *
  964  * DESCRIPTION: Disable and clear all GPEs in all GPE blocks
  965  *
  966  ******************************************************************************/
  967 
  968 ACPI_STATUS
  969 AcpiDisableAllGpes (
  970     void)
  971 {
  972     ACPI_STATUS             Status;
  973 
  974 
  975     ACPI_FUNCTION_TRACE (AcpiDisableAllGpes);
  976 
  977 
  978     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
  979     if (ACPI_FAILURE (Status))
  980     {
  981         return_ACPI_STATUS (Status);
  982     }
  983 
  984     Status = AcpiHwDisableAllGpes ();
  985     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
  986 
  987     return_ACPI_STATUS (Status);
  988 }
  989 
  990 ACPI_EXPORT_SYMBOL (AcpiDisableAllGpes)
  991 
  992 
  993 /******************************************************************************
  994  *
  995  * FUNCTION:    AcpiEnableAllRuntimeGpes
  996  *
  997  * PARAMETERS:  None
  998  *
  999  * 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 */

Cache object: ad4b33332d35c748846ecf04ecb589df


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.