xref: /titanic_44/usr/src/uts/intel/io/acpica/events/evxfgpe.c (revision cb56572868bfc488bbd3ab847b09db2a25554d44)
126f3cdf0SGordon Ross /******************************************************************************
226f3cdf0SGordon Ross  *
326f3cdf0SGordon Ross  * Module Name: evxfgpe - External Interfaces for General Purpose Events (GPEs)
426f3cdf0SGordon Ross  *
526f3cdf0SGordon Ross  *****************************************************************************/
626f3cdf0SGordon Ross 
726f3cdf0SGordon Ross /*
8*cb565728SJerry Jelinek  * Copyright (C) 2000 - 2016, Intel Corp.
926f3cdf0SGordon Ross  * All rights reserved.
1026f3cdf0SGordon Ross  *
1126f3cdf0SGordon Ross  * Redistribution and use in source and binary forms, with or without
1226f3cdf0SGordon Ross  * modification, are permitted provided that the following conditions
1326f3cdf0SGordon Ross  * are met:
1426f3cdf0SGordon Ross  * 1. Redistributions of source code must retain the above copyright
1526f3cdf0SGordon Ross  *    notice, this list of conditions, and the following disclaimer,
1626f3cdf0SGordon Ross  *    without modification.
1726f3cdf0SGordon Ross  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
1826f3cdf0SGordon Ross  *    substantially similar to the "NO WARRANTY" disclaimer below
1926f3cdf0SGordon Ross  *    ("Disclaimer") and any redistribution must be conditioned upon
2026f3cdf0SGordon Ross  *    including a substantially similar Disclaimer requirement for further
2126f3cdf0SGordon Ross  *    binary redistribution.
2226f3cdf0SGordon Ross  * 3. Neither the names of the above-listed copyright holders nor the names
2326f3cdf0SGordon Ross  *    of any contributors may be used to endorse or promote products derived
2426f3cdf0SGordon Ross  *    from this software without specific prior written permission.
2526f3cdf0SGordon Ross  *
2626f3cdf0SGordon Ross  * Alternatively, this software may be distributed under the terms of the
2726f3cdf0SGordon Ross  * GNU General Public License ("GPL") version 2 as published by the Free
2826f3cdf0SGordon Ross  * Software Foundation.
2926f3cdf0SGordon Ross  *
3026f3cdf0SGordon Ross  * NO WARRANTY
3126f3cdf0SGordon Ross  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
3226f3cdf0SGordon Ross  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3326f3cdf0SGordon Ross  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
3426f3cdf0SGordon Ross  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
3526f3cdf0SGordon Ross  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
3626f3cdf0SGordon Ross  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
3726f3cdf0SGordon Ross  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
3826f3cdf0SGordon Ross  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
3926f3cdf0SGordon Ross  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
4026f3cdf0SGordon Ross  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
4126f3cdf0SGordon Ross  * POSSIBILITY OF SUCH DAMAGES.
4226f3cdf0SGordon Ross  */
4326f3cdf0SGordon Ross 
44*cb565728SJerry Jelinek #define EXPORT_ACPI_INTERFACES
4526f3cdf0SGordon Ross 
4626f3cdf0SGordon Ross #include "acpi.h"
4726f3cdf0SGordon Ross #include "accommon.h"
4826f3cdf0SGordon Ross #include "acevents.h"
4926f3cdf0SGordon Ross #include "acnamesp.h"
5026f3cdf0SGordon Ross 
5126f3cdf0SGordon Ross #define _COMPONENT          ACPI_EVENTS
5226f3cdf0SGordon Ross         ACPI_MODULE_NAME    ("evxfgpe")
5326f3cdf0SGordon Ross 
5426f3cdf0SGordon Ross 
55*cb565728SJerry Jelinek #if (!ACPI_REDUCED_HARDWARE) /* Entire module */
5626f3cdf0SGordon Ross /*******************************************************************************
5726f3cdf0SGordon Ross  *
5826f3cdf0SGordon Ross  * FUNCTION:    AcpiUpdateAllGpes
5926f3cdf0SGordon Ross  *
6026f3cdf0SGordon Ross  * PARAMETERS:  None
6126f3cdf0SGordon Ross  *
6226f3cdf0SGordon Ross  * RETURN:      Status
6326f3cdf0SGordon Ross  *
6426f3cdf0SGordon Ross  * DESCRIPTION: Complete GPE initialization and enable all GPEs that have
6526f3cdf0SGordon Ross  *              associated _Lxx or _Exx methods and are not pointed to by any
6626f3cdf0SGordon Ross  *              device _PRW methods (this indicates that these GPEs are
6726f3cdf0SGordon Ross  *              generally intended for system or device wakeup. Such GPEs
6826f3cdf0SGordon Ross  *              have to be enabled directly when the devices whose _PRW
6926f3cdf0SGordon Ross  *              methods point to them are set up for wakeup signaling.)
7026f3cdf0SGordon Ross  *
7126f3cdf0SGordon Ross  * NOTE: Should be called after any GPEs are added to the system. Primarily,
7226f3cdf0SGordon Ross  * after the system _PRW methods have been run, but also after a GPE Block
7326f3cdf0SGordon Ross  * Device has been added or if any new GPE methods have been added via a
7426f3cdf0SGordon Ross  * dynamic table load.
7526f3cdf0SGordon Ross  *
7626f3cdf0SGordon Ross  ******************************************************************************/
7726f3cdf0SGordon Ross 
7826f3cdf0SGordon Ross ACPI_STATUS
AcpiUpdateAllGpes(void)7926f3cdf0SGordon Ross AcpiUpdateAllGpes (
8026f3cdf0SGordon Ross     void)
8126f3cdf0SGordon Ross {
8226f3cdf0SGordon Ross     ACPI_STATUS             Status;
8326f3cdf0SGordon Ross 
8426f3cdf0SGordon Ross 
85*cb565728SJerry Jelinek     ACPI_FUNCTION_TRACE (AcpiUpdateAllGpes);
8626f3cdf0SGordon Ross 
8726f3cdf0SGordon Ross 
8826f3cdf0SGordon Ross     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
8926f3cdf0SGordon Ross     if (ACPI_FAILURE (Status))
9026f3cdf0SGordon Ross     {
9126f3cdf0SGordon Ross         return_ACPI_STATUS (Status);
9226f3cdf0SGordon Ross     }
9326f3cdf0SGordon Ross 
9426f3cdf0SGordon Ross     if (AcpiGbl_AllGpesInitialized)
9526f3cdf0SGordon Ross     {
9626f3cdf0SGordon Ross         goto UnlockAndExit;
9726f3cdf0SGordon Ross     }
9826f3cdf0SGordon Ross 
9926f3cdf0SGordon Ross     Status = AcpiEvWalkGpeList (AcpiEvInitializeGpeBlock, NULL);
10026f3cdf0SGordon Ross     if (ACPI_SUCCESS (Status))
10126f3cdf0SGordon Ross     {
10226f3cdf0SGordon Ross         AcpiGbl_AllGpesInitialized = TRUE;
10326f3cdf0SGordon Ross     }
10426f3cdf0SGordon Ross 
10526f3cdf0SGordon Ross UnlockAndExit:
10626f3cdf0SGordon Ross     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
10726f3cdf0SGordon Ross     return_ACPI_STATUS (Status);
10826f3cdf0SGordon Ross }
10926f3cdf0SGordon Ross 
ACPI_EXPORT_SYMBOL(AcpiUpdateAllGpes)11026f3cdf0SGordon Ross ACPI_EXPORT_SYMBOL (AcpiUpdateAllGpes)
11126f3cdf0SGordon Ross 
11226f3cdf0SGordon Ross 
11326f3cdf0SGordon Ross /*******************************************************************************
11426f3cdf0SGordon Ross  *
11526f3cdf0SGordon Ross  * FUNCTION:    AcpiEnableGpe
11626f3cdf0SGordon Ross  *
11726f3cdf0SGordon Ross  * PARAMETERS:  GpeDevice           - Parent GPE Device. NULL for GPE0/GPE1
11826f3cdf0SGordon Ross  *              GpeNumber           - GPE level within the GPE block
11926f3cdf0SGordon Ross  *
12026f3cdf0SGordon Ross  * RETURN:      Status
12126f3cdf0SGordon Ross  *
12226f3cdf0SGordon Ross  * DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is
12326f3cdf0SGordon Ross  *              hardware-enabled.
12426f3cdf0SGordon Ross  *
12526f3cdf0SGordon Ross  ******************************************************************************/
12626f3cdf0SGordon Ross 
12726f3cdf0SGordon Ross ACPI_STATUS
12826f3cdf0SGordon Ross AcpiEnableGpe (
12926f3cdf0SGordon Ross     ACPI_HANDLE             GpeDevice,
13026f3cdf0SGordon Ross     UINT32                  GpeNumber)
13126f3cdf0SGordon Ross {
13226f3cdf0SGordon Ross     ACPI_STATUS             Status = AE_BAD_PARAMETER;
13326f3cdf0SGordon Ross     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
13426f3cdf0SGordon Ross     ACPI_CPU_FLAGS          Flags;
13526f3cdf0SGordon Ross 
13626f3cdf0SGordon Ross 
13726f3cdf0SGordon Ross     ACPI_FUNCTION_TRACE (AcpiEnableGpe);
13826f3cdf0SGordon Ross 
13926f3cdf0SGordon Ross 
14026f3cdf0SGordon Ross     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
14126f3cdf0SGordon Ross 
142*cb565728SJerry Jelinek     /*
143*cb565728SJerry Jelinek      * Ensure that we have a valid GPE number and that there is some way
144*cb565728SJerry Jelinek      * of handling the GPE (handler or a GPE method). In other words, we
145*cb565728SJerry Jelinek      * won't allow a valid GPE to be enabled if there is no way to handle it.
146*cb565728SJerry Jelinek      */
14726f3cdf0SGordon Ross     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
14826f3cdf0SGordon Ross     if (GpeEventInfo)
14926f3cdf0SGordon Ross     {
150*cb565728SJerry Jelinek         if (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) !=
151*cb565728SJerry Jelinek             ACPI_GPE_DISPATCH_NONE)
152*cb565728SJerry Jelinek         {
15326f3cdf0SGordon Ross             Status = AcpiEvAddGpeReference (GpeEventInfo);
15426f3cdf0SGordon Ross         }
155*cb565728SJerry Jelinek         else
156*cb565728SJerry Jelinek         {
157*cb565728SJerry Jelinek             Status = AE_NO_HANDLER;
158*cb565728SJerry Jelinek         }
159*cb565728SJerry Jelinek     }
16026f3cdf0SGordon Ross 
16126f3cdf0SGordon Ross     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
16226f3cdf0SGordon Ross     return_ACPI_STATUS (Status);
16326f3cdf0SGordon Ross }
16426f3cdf0SGordon Ross 
ACPI_EXPORT_SYMBOL(AcpiEnableGpe)16526f3cdf0SGordon Ross ACPI_EXPORT_SYMBOL (AcpiEnableGpe)
16626f3cdf0SGordon Ross 
16726f3cdf0SGordon Ross 
16826f3cdf0SGordon Ross /*******************************************************************************
16926f3cdf0SGordon Ross  *
17026f3cdf0SGordon Ross  * FUNCTION:    AcpiDisableGpe
17126f3cdf0SGordon Ross  *
17226f3cdf0SGordon Ross  * PARAMETERS:  GpeDevice           - Parent GPE Device. NULL for GPE0/GPE1
17326f3cdf0SGordon Ross  *              GpeNumber           - GPE level within the GPE block
17426f3cdf0SGordon Ross  *
17526f3cdf0SGordon Ross  * RETURN:      Status
17626f3cdf0SGordon Ross  *
17726f3cdf0SGordon Ross  * DESCRIPTION: Remove a reference to a GPE. When the last reference is
17826f3cdf0SGordon Ross  *              removed, only then is the GPE disabled (for runtime GPEs), or
17926f3cdf0SGordon Ross  *              the GPE mask bit disabled (for wake GPEs)
18026f3cdf0SGordon Ross  *
18126f3cdf0SGordon Ross  ******************************************************************************/
18226f3cdf0SGordon Ross 
18326f3cdf0SGordon Ross ACPI_STATUS
18426f3cdf0SGordon Ross AcpiDisableGpe (
18526f3cdf0SGordon Ross     ACPI_HANDLE             GpeDevice,
18626f3cdf0SGordon Ross     UINT32                  GpeNumber)
18726f3cdf0SGordon Ross {
18826f3cdf0SGordon Ross     ACPI_STATUS             Status = AE_BAD_PARAMETER;
18926f3cdf0SGordon Ross     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
19026f3cdf0SGordon Ross     ACPI_CPU_FLAGS          Flags;
19126f3cdf0SGordon Ross 
19226f3cdf0SGordon Ross 
19326f3cdf0SGordon Ross     ACPI_FUNCTION_TRACE (AcpiDisableGpe);
19426f3cdf0SGordon Ross 
19526f3cdf0SGordon Ross 
19626f3cdf0SGordon Ross     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
19726f3cdf0SGordon Ross 
19826f3cdf0SGordon Ross     /* Ensure that we have a valid GPE number */
19926f3cdf0SGordon Ross 
20026f3cdf0SGordon Ross     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
20126f3cdf0SGordon Ross     if (GpeEventInfo)
20226f3cdf0SGordon Ross     {
20326f3cdf0SGordon Ross         Status = AcpiEvRemoveGpeReference (GpeEventInfo);
20426f3cdf0SGordon Ross     }
20526f3cdf0SGordon Ross 
20626f3cdf0SGordon Ross     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
20726f3cdf0SGordon Ross     return_ACPI_STATUS (Status);
20826f3cdf0SGordon Ross }
20926f3cdf0SGordon Ross 
ACPI_EXPORT_SYMBOL(AcpiDisableGpe)21026f3cdf0SGordon Ross ACPI_EXPORT_SYMBOL (AcpiDisableGpe)
21126f3cdf0SGordon Ross 
21226f3cdf0SGordon Ross 
21326f3cdf0SGordon Ross /*******************************************************************************
21426f3cdf0SGordon Ross  *
21526f3cdf0SGordon Ross  * FUNCTION:    AcpiSetGpe
21626f3cdf0SGordon Ross  *
21726f3cdf0SGordon Ross  * PARAMETERS:  GpeDevice           - Parent GPE Device. NULL for GPE0/GPE1
21826f3cdf0SGordon Ross  *              GpeNumber           - GPE level within the GPE block
21926f3cdf0SGordon Ross  *              Action              - ACPI_GPE_ENABLE or ACPI_GPE_DISABLE
22026f3cdf0SGordon Ross  *
22126f3cdf0SGordon Ross  * RETURN:      Status
22226f3cdf0SGordon Ross  *
22326f3cdf0SGordon Ross  * DESCRIPTION: Enable or disable an individual GPE. This function bypasses
224*cb565728SJerry Jelinek  *              the reference count mechanism used in the AcpiEnableGpe(),
225*cb565728SJerry Jelinek  *              AcpiDisableGpe() interfaces.
226*cb565728SJerry Jelinek  *              This API is typically used by the GPE raw handler mode driver
227*cb565728SJerry Jelinek  *              to switch between the polling mode and the interrupt mode after
228*cb565728SJerry Jelinek  *              the driver has enabled the GPE.
229*cb565728SJerry Jelinek  *              The APIs should be invoked in this order:
230*cb565728SJerry Jelinek  *               AcpiEnableGpe()              <- Ensure the reference count > 0
231*cb565728SJerry Jelinek  *               AcpiSetGpe(ACPI_GPE_DISABLE) <- Enter polling mode
232*cb565728SJerry Jelinek  *               AcpiSetGpe(ACPI_GPE_ENABLE)  <- Leave polling mode
233*cb565728SJerry Jelinek  *               AcpiDisableGpe()             <- Decrease the reference count
23426f3cdf0SGordon Ross  *
235*cb565728SJerry Jelinek  * Note: If a GPE is shared by 2 silicon components, then both the drivers
236*cb565728SJerry Jelinek  *       should support GPE polling mode or disabling the GPE for long period
237*cb565728SJerry Jelinek  *       for one driver may break the other. So use it with care since all
238*cb565728SJerry Jelinek  *       firmware _Lxx/_Exx handlers currently rely on the GPE interrupt mode.
23926f3cdf0SGordon Ross  *
24026f3cdf0SGordon Ross  ******************************************************************************/
24126f3cdf0SGordon Ross 
24226f3cdf0SGordon Ross ACPI_STATUS
24326f3cdf0SGordon Ross AcpiSetGpe (
24426f3cdf0SGordon Ross     ACPI_HANDLE             GpeDevice,
24526f3cdf0SGordon Ross     UINT32                  GpeNumber,
24626f3cdf0SGordon Ross     UINT8                   Action)
24726f3cdf0SGordon Ross {
24826f3cdf0SGordon Ross     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
24926f3cdf0SGordon Ross     ACPI_STATUS             Status;
25026f3cdf0SGordon Ross     ACPI_CPU_FLAGS          Flags;
25126f3cdf0SGordon Ross 
25226f3cdf0SGordon Ross 
25326f3cdf0SGordon Ross     ACPI_FUNCTION_TRACE (AcpiSetGpe);
25426f3cdf0SGordon Ross 
25526f3cdf0SGordon Ross 
25626f3cdf0SGordon Ross     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
25726f3cdf0SGordon Ross 
25826f3cdf0SGordon Ross     /* Ensure that we have a valid GPE number */
25926f3cdf0SGordon Ross 
26026f3cdf0SGordon Ross     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
26126f3cdf0SGordon Ross     if (!GpeEventInfo)
26226f3cdf0SGordon Ross     {
26326f3cdf0SGordon Ross         Status = AE_BAD_PARAMETER;
26426f3cdf0SGordon Ross         goto UnlockAndExit;
26526f3cdf0SGordon Ross     }
26626f3cdf0SGordon Ross 
26726f3cdf0SGordon Ross     /* Perform the action */
26826f3cdf0SGordon Ross 
26926f3cdf0SGordon Ross     switch (Action)
27026f3cdf0SGordon Ross     {
27126f3cdf0SGordon Ross     case ACPI_GPE_ENABLE:
272*cb565728SJerry Jelinek 
273*cb565728SJerry Jelinek         Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_ENABLE);
27426f3cdf0SGordon Ross         break;
27526f3cdf0SGordon Ross 
27626f3cdf0SGordon Ross     case ACPI_GPE_DISABLE:
277*cb565728SJerry Jelinek 
27826f3cdf0SGordon Ross         Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_DISABLE);
27926f3cdf0SGordon Ross         break;
28026f3cdf0SGordon Ross 
28126f3cdf0SGordon Ross     default:
282*cb565728SJerry Jelinek 
28326f3cdf0SGordon Ross         Status = AE_BAD_PARAMETER;
28426f3cdf0SGordon Ross         break;
28526f3cdf0SGordon Ross     }
28626f3cdf0SGordon Ross 
28726f3cdf0SGordon Ross UnlockAndExit:
28826f3cdf0SGordon Ross     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
28926f3cdf0SGordon Ross     return_ACPI_STATUS (Status);
29026f3cdf0SGordon Ross }
29126f3cdf0SGordon Ross 
ACPI_EXPORT_SYMBOL(AcpiSetGpe)29226f3cdf0SGordon Ross ACPI_EXPORT_SYMBOL (AcpiSetGpe)
29326f3cdf0SGordon Ross 
29426f3cdf0SGordon Ross 
29526f3cdf0SGordon Ross /*******************************************************************************
29626f3cdf0SGordon Ross  *
297*cb565728SJerry Jelinek  * FUNCTION:    AcpiMarkGpeForWake
298*cb565728SJerry Jelinek  *
299*cb565728SJerry Jelinek  * PARAMETERS:  GpeDevice           - Parent GPE Device. NULL for GPE0/GPE1
300*cb565728SJerry Jelinek  *              GpeNumber           - GPE level within the GPE block
301*cb565728SJerry Jelinek  *
302*cb565728SJerry Jelinek  * RETURN:      Status
303*cb565728SJerry Jelinek  *
304*cb565728SJerry Jelinek  * DESCRIPTION: Mark a GPE as having the ability to wake the system. Simply
305*cb565728SJerry Jelinek  *              sets the ACPI_GPE_CAN_WAKE flag.
306*cb565728SJerry Jelinek  *
307*cb565728SJerry Jelinek  * Some potential callers of AcpiSetupGpeForWake may know in advance that
308*cb565728SJerry Jelinek  * there won't be any notify handlers installed for device wake notifications
309*cb565728SJerry Jelinek  * from the given GPE (one example is a button GPE in Linux). For these cases,
310*cb565728SJerry Jelinek  * AcpiMarkGpeForWake should be used instead of AcpiSetupGpeForWake.
311*cb565728SJerry Jelinek  * This will set the ACPI_GPE_CAN_WAKE flag for the GPE without trying to
312*cb565728SJerry Jelinek  * setup implicit wake notification for it (since there's no handler method).
313*cb565728SJerry Jelinek  *
314*cb565728SJerry Jelinek  ******************************************************************************/
315*cb565728SJerry Jelinek 
316*cb565728SJerry Jelinek ACPI_STATUS
317*cb565728SJerry Jelinek AcpiMarkGpeForWake (
318*cb565728SJerry Jelinek     ACPI_HANDLE             GpeDevice,
319*cb565728SJerry Jelinek     UINT32                  GpeNumber)
320*cb565728SJerry Jelinek {
321*cb565728SJerry Jelinek     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
322*cb565728SJerry Jelinek     ACPI_STATUS             Status = AE_BAD_PARAMETER;
323*cb565728SJerry Jelinek     ACPI_CPU_FLAGS          Flags;
324*cb565728SJerry Jelinek 
325*cb565728SJerry Jelinek 
326*cb565728SJerry Jelinek     ACPI_FUNCTION_TRACE (AcpiMarkGpeForWake);
327*cb565728SJerry Jelinek 
328*cb565728SJerry Jelinek 
329*cb565728SJerry Jelinek     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
330*cb565728SJerry Jelinek 
331*cb565728SJerry Jelinek     /* Ensure that we have a valid GPE number */
332*cb565728SJerry Jelinek 
333*cb565728SJerry Jelinek     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
334*cb565728SJerry Jelinek     if (GpeEventInfo)
335*cb565728SJerry Jelinek     {
336*cb565728SJerry Jelinek         /* Mark the GPE as a possible wake event */
337*cb565728SJerry Jelinek 
338*cb565728SJerry Jelinek         GpeEventInfo->Flags |= ACPI_GPE_CAN_WAKE;
339*cb565728SJerry Jelinek         Status = AE_OK;
340*cb565728SJerry Jelinek     }
341*cb565728SJerry Jelinek 
342*cb565728SJerry Jelinek     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
343*cb565728SJerry Jelinek     return_ACPI_STATUS (Status);
344*cb565728SJerry Jelinek }
345*cb565728SJerry Jelinek 
ACPI_EXPORT_SYMBOL(AcpiMarkGpeForWake)346*cb565728SJerry Jelinek ACPI_EXPORT_SYMBOL (AcpiMarkGpeForWake)
347*cb565728SJerry Jelinek 
348*cb565728SJerry Jelinek 
349*cb565728SJerry Jelinek /*******************************************************************************
350*cb565728SJerry Jelinek  *
35126f3cdf0SGordon Ross  * FUNCTION:    AcpiSetupGpeForWake
35226f3cdf0SGordon Ross  *
35326f3cdf0SGordon Ross  * PARAMETERS:  WakeDevice          - Device associated with the GPE (via _PRW)
35426f3cdf0SGordon Ross  *              GpeDevice           - Parent GPE Device. NULL for GPE0/GPE1
35526f3cdf0SGordon Ross  *              GpeNumber           - GPE level within the GPE block
35626f3cdf0SGordon Ross  *
35726f3cdf0SGordon Ross  * RETURN:      Status
35826f3cdf0SGordon Ross  *
35926f3cdf0SGordon Ross  * DESCRIPTION: Mark a GPE as having the ability to wake the system. This
36026f3cdf0SGordon Ross  *              interface is intended to be used as the host executes the
36126f3cdf0SGordon Ross  *              _PRW methods (Power Resources for Wake) in the system tables.
36226f3cdf0SGordon Ross  *              Each _PRW appears under a Device Object (The WakeDevice), and
36326f3cdf0SGordon Ross  *              contains the info for the wake GPE associated with the
36426f3cdf0SGordon Ross  *              WakeDevice.
36526f3cdf0SGordon Ross  *
36626f3cdf0SGordon Ross  ******************************************************************************/
36726f3cdf0SGordon Ross 
36826f3cdf0SGordon Ross ACPI_STATUS
36926f3cdf0SGordon Ross AcpiSetupGpeForWake (
37026f3cdf0SGordon Ross     ACPI_HANDLE             WakeDevice,
37126f3cdf0SGordon Ross     ACPI_HANDLE             GpeDevice,
37226f3cdf0SGordon Ross     UINT32                  GpeNumber)
37326f3cdf0SGordon Ross {
374*cb565728SJerry Jelinek     ACPI_STATUS             Status;
37526f3cdf0SGordon Ross     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
37626f3cdf0SGordon Ross     ACPI_NAMESPACE_NODE     *DeviceNode;
377*cb565728SJerry Jelinek     ACPI_GPE_NOTIFY_INFO    *Notify;
378*cb565728SJerry Jelinek     ACPI_GPE_NOTIFY_INFO    *NewNotify;
37926f3cdf0SGordon Ross     ACPI_CPU_FLAGS          Flags;
38026f3cdf0SGordon Ross 
38126f3cdf0SGordon Ross 
38226f3cdf0SGordon Ross     ACPI_FUNCTION_TRACE (AcpiSetupGpeForWake);
38326f3cdf0SGordon Ross 
38426f3cdf0SGordon Ross 
38526f3cdf0SGordon Ross     /* Parameter Validation */
38626f3cdf0SGordon Ross 
38726f3cdf0SGordon Ross     if (!WakeDevice)
38826f3cdf0SGordon Ross     {
38926f3cdf0SGordon Ross         /*
39026f3cdf0SGordon Ross          * By forcing WakeDevice to be valid, we automatically enable the
39126f3cdf0SGordon Ross          * implicit notify feature on all hosts.
39226f3cdf0SGordon Ross          */
39326f3cdf0SGordon Ross         return_ACPI_STATUS (AE_BAD_PARAMETER);
39426f3cdf0SGordon Ross     }
39526f3cdf0SGordon Ross 
39626f3cdf0SGordon Ross     /* Handle root object case */
39726f3cdf0SGordon Ross 
39826f3cdf0SGordon Ross     if (WakeDevice == ACPI_ROOT_OBJECT)
39926f3cdf0SGordon Ross     {
40026f3cdf0SGordon Ross         DeviceNode = AcpiGbl_RootNode;
40126f3cdf0SGordon Ross     }
40226f3cdf0SGordon Ross     else
40326f3cdf0SGordon Ross     {
40426f3cdf0SGordon Ross         DeviceNode = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, WakeDevice);
40526f3cdf0SGordon Ross     }
40626f3cdf0SGordon Ross 
40726f3cdf0SGordon Ross     /* Validate WakeDevice is of type Device */
40826f3cdf0SGordon Ross 
40926f3cdf0SGordon Ross     if (DeviceNode->Type != ACPI_TYPE_DEVICE)
41026f3cdf0SGordon Ross     {
41126f3cdf0SGordon Ross         return_ACPI_STATUS (AE_BAD_PARAMETER);
41226f3cdf0SGordon Ross     }
41326f3cdf0SGordon Ross 
414*cb565728SJerry Jelinek     /*
415*cb565728SJerry Jelinek      * Allocate a new notify object up front, in case it is needed.
416*cb565728SJerry Jelinek      * Memory allocation while holding a spinlock is a big no-no
417*cb565728SJerry Jelinek      * on some hosts.
418*cb565728SJerry Jelinek      */
419*cb565728SJerry Jelinek     NewNotify = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_GPE_NOTIFY_INFO));
420*cb565728SJerry Jelinek     if (!NewNotify)
421*cb565728SJerry Jelinek     {
422*cb565728SJerry Jelinek         return_ACPI_STATUS (AE_NO_MEMORY);
423*cb565728SJerry Jelinek     }
424*cb565728SJerry Jelinek 
42526f3cdf0SGordon Ross     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
42626f3cdf0SGordon Ross 
42726f3cdf0SGordon Ross     /* Ensure that we have a valid GPE number */
42826f3cdf0SGordon Ross 
42926f3cdf0SGordon Ross     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
430*cb565728SJerry Jelinek     if (!GpeEventInfo)
43126f3cdf0SGordon Ross     {
432*cb565728SJerry Jelinek         Status = AE_BAD_PARAMETER;
433*cb565728SJerry Jelinek         goto UnlockAndExit;
434*cb565728SJerry Jelinek     }
435*cb565728SJerry Jelinek 
43626f3cdf0SGordon Ross     /*
43726f3cdf0SGordon Ross      * If there is no method or handler for this GPE, then the
438*cb565728SJerry Jelinek      * WakeDevice will be notified whenever this GPE fires. This is
439*cb565728SJerry Jelinek      * known as an "implicit notify". Note: The GPE is assumed to be
44026f3cdf0SGordon Ross      * level-triggered (for windows compatibility).
44126f3cdf0SGordon Ross      */
442*cb565728SJerry Jelinek     if (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) ==
44326f3cdf0SGordon Ross         ACPI_GPE_DISPATCH_NONE)
44426f3cdf0SGordon Ross     {
445*cb565728SJerry Jelinek         /*
446*cb565728SJerry Jelinek          * This is the first device for implicit notify on this GPE.
447*cb565728SJerry Jelinek          * Just set the flags here, and enter the NOTIFY block below.
448*cb565728SJerry Jelinek          */
44926f3cdf0SGordon Ross         GpeEventInfo->Flags =
45026f3cdf0SGordon Ross             (ACPI_GPE_DISPATCH_NOTIFY | ACPI_GPE_LEVEL_TRIGGERED);
45126f3cdf0SGordon Ross     }
45226f3cdf0SGordon Ross 
453*cb565728SJerry Jelinek     /*
454*cb565728SJerry Jelinek      * If we already have an implicit notify on this GPE, add
455*cb565728SJerry Jelinek      * this device to the notify list.
456*cb565728SJerry Jelinek      */
457*cb565728SJerry Jelinek     if (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) ==
458*cb565728SJerry Jelinek         ACPI_GPE_DISPATCH_NOTIFY)
459*cb565728SJerry Jelinek     {
460*cb565728SJerry Jelinek         /* Ensure that the device is not already in the list */
461*cb565728SJerry Jelinek 
462*cb565728SJerry Jelinek         Notify = GpeEventInfo->Dispatch.NotifyList;
463*cb565728SJerry Jelinek         while (Notify)
464*cb565728SJerry Jelinek         {
465*cb565728SJerry Jelinek             if (Notify->DeviceNode == DeviceNode)
466*cb565728SJerry Jelinek             {
467*cb565728SJerry Jelinek                 Status = AE_ALREADY_EXISTS;
468*cb565728SJerry Jelinek                 goto UnlockAndExit;
469*cb565728SJerry Jelinek             }
470*cb565728SJerry Jelinek             Notify = Notify->Next;
471*cb565728SJerry Jelinek         }
472*cb565728SJerry Jelinek 
473*cb565728SJerry Jelinek         /* Add this device to the notify list for this GPE */
474*cb565728SJerry Jelinek 
475*cb565728SJerry Jelinek         NewNotify->DeviceNode = DeviceNode;
476*cb565728SJerry Jelinek         NewNotify->Next = GpeEventInfo->Dispatch.NotifyList;
477*cb565728SJerry Jelinek         GpeEventInfo->Dispatch.NotifyList = NewNotify;
478*cb565728SJerry Jelinek         NewNotify = NULL;
479*cb565728SJerry Jelinek     }
480*cb565728SJerry Jelinek 
481*cb565728SJerry Jelinek     /* Mark the GPE as a possible wake event */
482*cb565728SJerry Jelinek 
48326f3cdf0SGordon Ross     GpeEventInfo->Flags |= ACPI_GPE_CAN_WAKE;
48426f3cdf0SGordon Ross     Status = AE_OK;
48526f3cdf0SGordon Ross 
486*cb565728SJerry Jelinek 
487*cb565728SJerry Jelinek UnlockAndExit:
48826f3cdf0SGordon Ross     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
489*cb565728SJerry Jelinek 
490*cb565728SJerry Jelinek     /* Delete the notify object if it was not used above */
491*cb565728SJerry Jelinek 
492*cb565728SJerry Jelinek     if (NewNotify)
493*cb565728SJerry Jelinek     {
494*cb565728SJerry Jelinek         ACPI_FREE (NewNotify);
495*cb565728SJerry Jelinek     }
49626f3cdf0SGordon Ross     return_ACPI_STATUS (Status);
49726f3cdf0SGordon Ross }
49826f3cdf0SGordon Ross 
ACPI_EXPORT_SYMBOL(AcpiSetupGpeForWake)49926f3cdf0SGordon Ross ACPI_EXPORT_SYMBOL (AcpiSetupGpeForWake)
50026f3cdf0SGordon Ross 
50126f3cdf0SGordon Ross 
50226f3cdf0SGordon Ross /*******************************************************************************
50326f3cdf0SGordon Ross  *
50426f3cdf0SGordon Ross  * FUNCTION:    AcpiSetGpeWakeMask
50526f3cdf0SGordon Ross  *
50626f3cdf0SGordon Ross  * PARAMETERS:  GpeDevice           - Parent GPE Device. NULL for GPE0/GPE1
50726f3cdf0SGordon Ross  *              GpeNumber           - GPE level within the GPE block
50826f3cdf0SGordon Ross  *              Action              - Enable or Disable
50926f3cdf0SGordon Ross  *
51026f3cdf0SGordon Ross  * RETURN:      Status
51126f3cdf0SGordon Ross  *
51226f3cdf0SGordon Ross  * DESCRIPTION: Set or clear the GPE's wakeup enable mask bit. The GPE must
51326f3cdf0SGordon Ross  *              already be marked as a WAKE GPE.
51426f3cdf0SGordon Ross  *
51526f3cdf0SGordon Ross  ******************************************************************************/
51626f3cdf0SGordon Ross 
51726f3cdf0SGordon Ross ACPI_STATUS
51826f3cdf0SGordon Ross AcpiSetGpeWakeMask (
51926f3cdf0SGordon Ross     ACPI_HANDLE             GpeDevice,
52026f3cdf0SGordon Ross     UINT32                  GpeNumber,
52126f3cdf0SGordon Ross     UINT8                   Action)
52226f3cdf0SGordon Ross {
52326f3cdf0SGordon Ross     ACPI_STATUS             Status = AE_OK;
52426f3cdf0SGordon Ross     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
52526f3cdf0SGordon Ross     ACPI_GPE_REGISTER_INFO  *GpeRegisterInfo;
52626f3cdf0SGordon Ross     ACPI_CPU_FLAGS          Flags;
52726f3cdf0SGordon Ross     UINT32                  RegisterBit;
52826f3cdf0SGordon Ross 
52926f3cdf0SGordon Ross 
53026f3cdf0SGordon Ross     ACPI_FUNCTION_TRACE (AcpiSetGpeWakeMask);
53126f3cdf0SGordon Ross 
53226f3cdf0SGordon Ross 
53326f3cdf0SGordon Ross     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
53426f3cdf0SGordon Ross 
53526f3cdf0SGordon Ross     /*
53626f3cdf0SGordon Ross      * Ensure that we have a valid GPE number and that this GPE is in
53726f3cdf0SGordon Ross      * fact a wake GPE
53826f3cdf0SGordon Ross      */
53926f3cdf0SGordon Ross     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
54026f3cdf0SGordon Ross     if (!GpeEventInfo)
54126f3cdf0SGordon Ross     {
54226f3cdf0SGordon Ross         Status = AE_BAD_PARAMETER;
54326f3cdf0SGordon Ross         goto UnlockAndExit;
54426f3cdf0SGordon Ross     }
54526f3cdf0SGordon Ross 
54626f3cdf0SGordon Ross     if (!(GpeEventInfo->Flags & ACPI_GPE_CAN_WAKE))
54726f3cdf0SGordon Ross     {
54826f3cdf0SGordon Ross         Status = AE_TYPE;
54926f3cdf0SGordon Ross         goto UnlockAndExit;
55026f3cdf0SGordon Ross     }
55126f3cdf0SGordon Ross 
55226f3cdf0SGordon Ross     GpeRegisterInfo = GpeEventInfo->RegisterInfo;
55326f3cdf0SGordon Ross     if (!GpeRegisterInfo)
55426f3cdf0SGordon Ross     {
55526f3cdf0SGordon Ross         Status = AE_NOT_EXIST;
55626f3cdf0SGordon Ross         goto UnlockAndExit;
55726f3cdf0SGordon Ross     }
55826f3cdf0SGordon Ross 
559*cb565728SJerry Jelinek     RegisterBit = AcpiHwGetGpeRegisterBit (GpeEventInfo);
56026f3cdf0SGordon Ross 
56126f3cdf0SGordon Ross     /* Perform the action */
56226f3cdf0SGordon Ross 
56326f3cdf0SGordon Ross     switch (Action)
56426f3cdf0SGordon Ross     {
56526f3cdf0SGordon Ross     case ACPI_GPE_ENABLE:
566*cb565728SJerry Jelinek 
56726f3cdf0SGordon Ross         ACPI_SET_BIT (GpeRegisterInfo->EnableForWake, (UINT8) RegisterBit);
56826f3cdf0SGordon Ross         break;
56926f3cdf0SGordon Ross 
57026f3cdf0SGordon Ross     case ACPI_GPE_DISABLE:
571*cb565728SJerry Jelinek 
57226f3cdf0SGordon Ross         ACPI_CLEAR_BIT (GpeRegisterInfo->EnableForWake, (UINT8) RegisterBit);
57326f3cdf0SGordon Ross         break;
57426f3cdf0SGordon Ross 
57526f3cdf0SGordon Ross     default:
576*cb565728SJerry Jelinek 
57726f3cdf0SGordon Ross         ACPI_ERROR ((AE_INFO, "%u, Invalid action", Action));
57826f3cdf0SGordon Ross         Status = AE_BAD_PARAMETER;
57926f3cdf0SGordon Ross         break;
58026f3cdf0SGordon Ross     }
58126f3cdf0SGordon Ross 
58226f3cdf0SGordon Ross UnlockAndExit:
58326f3cdf0SGordon Ross     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
58426f3cdf0SGordon Ross     return_ACPI_STATUS (Status);
58526f3cdf0SGordon Ross }
58626f3cdf0SGordon Ross 
ACPI_EXPORT_SYMBOL(AcpiSetGpeWakeMask)58726f3cdf0SGordon Ross ACPI_EXPORT_SYMBOL (AcpiSetGpeWakeMask)
58826f3cdf0SGordon Ross 
58926f3cdf0SGordon Ross 
59026f3cdf0SGordon Ross /*******************************************************************************
59126f3cdf0SGordon Ross  *
59226f3cdf0SGordon Ross  * FUNCTION:    AcpiClearGpe
59326f3cdf0SGordon Ross  *
59426f3cdf0SGordon Ross  * PARAMETERS:  GpeDevice           - Parent GPE Device. NULL for GPE0/GPE1
59526f3cdf0SGordon Ross  *              GpeNumber           - GPE level within the GPE block
59626f3cdf0SGordon Ross  *
59726f3cdf0SGordon Ross  * RETURN:      Status
59826f3cdf0SGordon Ross  *
59926f3cdf0SGordon Ross  * DESCRIPTION: Clear an ACPI event (general purpose)
60026f3cdf0SGordon Ross  *
60126f3cdf0SGordon Ross  ******************************************************************************/
60226f3cdf0SGordon Ross 
60326f3cdf0SGordon Ross ACPI_STATUS
60426f3cdf0SGordon Ross AcpiClearGpe (
60526f3cdf0SGordon Ross     ACPI_HANDLE             GpeDevice,
60626f3cdf0SGordon Ross     UINT32                  GpeNumber)
60726f3cdf0SGordon Ross {
60826f3cdf0SGordon Ross     ACPI_STATUS             Status = AE_OK;
60926f3cdf0SGordon Ross     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
61026f3cdf0SGordon Ross     ACPI_CPU_FLAGS          Flags;
61126f3cdf0SGordon Ross 
61226f3cdf0SGordon Ross 
61326f3cdf0SGordon Ross     ACPI_FUNCTION_TRACE (AcpiClearGpe);
61426f3cdf0SGordon Ross 
61526f3cdf0SGordon Ross 
61626f3cdf0SGordon Ross     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
61726f3cdf0SGordon Ross 
61826f3cdf0SGordon Ross     /* Ensure that we have a valid GPE number */
61926f3cdf0SGordon Ross 
62026f3cdf0SGordon Ross     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
62126f3cdf0SGordon Ross     if (!GpeEventInfo)
62226f3cdf0SGordon Ross     {
62326f3cdf0SGordon Ross         Status = AE_BAD_PARAMETER;
62426f3cdf0SGordon Ross         goto UnlockAndExit;
62526f3cdf0SGordon Ross     }
62626f3cdf0SGordon Ross 
62726f3cdf0SGordon Ross     Status = AcpiHwClearGpe (GpeEventInfo);
62826f3cdf0SGordon Ross 
62926f3cdf0SGordon Ross UnlockAndExit:
63026f3cdf0SGordon Ross     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
63126f3cdf0SGordon Ross     return_ACPI_STATUS (Status);
63226f3cdf0SGordon Ross }
63326f3cdf0SGordon Ross 
ACPI_EXPORT_SYMBOL(AcpiClearGpe)63426f3cdf0SGordon Ross ACPI_EXPORT_SYMBOL (AcpiClearGpe)
63526f3cdf0SGordon Ross 
63626f3cdf0SGordon Ross 
63726f3cdf0SGordon Ross /*******************************************************************************
63826f3cdf0SGordon Ross  *
63926f3cdf0SGordon Ross  * FUNCTION:    AcpiGetGpeStatus
64026f3cdf0SGordon Ross  *
64126f3cdf0SGordon Ross  * PARAMETERS:  GpeDevice           - Parent GPE Device. NULL for GPE0/GPE1
64226f3cdf0SGordon Ross  *              GpeNumber           - GPE level within the GPE block
64326f3cdf0SGordon Ross  *              EventStatus         - Where the current status of the event
64426f3cdf0SGordon Ross  *                                    will be returned
64526f3cdf0SGordon Ross  *
64626f3cdf0SGordon Ross  * RETURN:      Status
64726f3cdf0SGordon Ross  *
64826f3cdf0SGordon Ross  * DESCRIPTION: Get the current status of a GPE (signalled/not_signalled)
64926f3cdf0SGordon Ross  *
65026f3cdf0SGordon Ross  ******************************************************************************/
65126f3cdf0SGordon Ross 
65226f3cdf0SGordon Ross ACPI_STATUS
65326f3cdf0SGordon Ross AcpiGetGpeStatus (
65426f3cdf0SGordon Ross     ACPI_HANDLE             GpeDevice,
65526f3cdf0SGordon Ross     UINT32                  GpeNumber,
65626f3cdf0SGordon Ross     ACPI_EVENT_STATUS       *EventStatus)
65726f3cdf0SGordon Ross {
65826f3cdf0SGordon Ross     ACPI_STATUS             Status = AE_OK;
65926f3cdf0SGordon Ross     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
66026f3cdf0SGordon Ross     ACPI_CPU_FLAGS          Flags;
66126f3cdf0SGordon Ross 
66226f3cdf0SGordon Ross 
66326f3cdf0SGordon Ross     ACPI_FUNCTION_TRACE (AcpiGetGpeStatus);
66426f3cdf0SGordon Ross 
66526f3cdf0SGordon Ross 
66626f3cdf0SGordon Ross     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
66726f3cdf0SGordon Ross 
66826f3cdf0SGordon Ross     /* Ensure that we have a valid GPE number */
66926f3cdf0SGordon Ross 
67026f3cdf0SGordon Ross     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
67126f3cdf0SGordon Ross     if (!GpeEventInfo)
67226f3cdf0SGordon Ross     {
67326f3cdf0SGordon Ross         Status = AE_BAD_PARAMETER;
67426f3cdf0SGordon Ross         goto UnlockAndExit;
67526f3cdf0SGordon Ross     }
67626f3cdf0SGordon Ross 
67726f3cdf0SGordon Ross     /* Obtain status on the requested GPE number */
67826f3cdf0SGordon Ross 
67926f3cdf0SGordon Ross     Status = AcpiHwGetGpeStatus (GpeEventInfo, EventStatus);
68026f3cdf0SGordon Ross 
68126f3cdf0SGordon Ross UnlockAndExit:
68226f3cdf0SGordon Ross     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
68326f3cdf0SGordon Ross     return_ACPI_STATUS (Status);
68426f3cdf0SGordon Ross }
68526f3cdf0SGordon Ross 
ACPI_EXPORT_SYMBOL(AcpiGetGpeStatus)68626f3cdf0SGordon Ross ACPI_EXPORT_SYMBOL (AcpiGetGpeStatus)
68726f3cdf0SGordon Ross 
68826f3cdf0SGordon Ross 
68926f3cdf0SGordon Ross /*******************************************************************************
69026f3cdf0SGordon Ross  *
69126f3cdf0SGordon Ross  * FUNCTION:    AcpiFinishGpe
69226f3cdf0SGordon Ross  *
69326f3cdf0SGordon Ross  * PARAMETERS:  GpeDevice           - Namespace node for the GPE Block
69426f3cdf0SGordon Ross  *                                    (NULL for FADT defined GPEs)
69526f3cdf0SGordon Ross  *              GpeNumber           - GPE level within the GPE block
69626f3cdf0SGordon Ross  *
69726f3cdf0SGordon Ross  * RETURN:      Status
69826f3cdf0SGordon Ross  *
69926f3cdf0SGordon Ross  * DESCRIPTION: Clear and conditionally reenable a GPE. This completes the GPE
70026f3cdf0SGordon Ross  *              processing. Intended for use by asynchronous host-installed
70126f3cdf0SGordon Ross  *              GPE handlers. The GPE is only reenabled if the EnableForRun bit
70226f3cdf0SGordon Ross  *              is set in the GPE info.
70326f3cdf0SGordon Ross  *
70426f3cdf0SGordon Ross  ******************************************************************************/
70526f3cdf0SGordon Ross 
70626f3cdf0SGordon Ross ACPI_STATUS
70726f3cdf0SGordon Ross AcpiFinishGpe (
70826f3cdf0SGordon Ross     ACPI_HANDLE             GpeDevice,
70926f3cdf0SGordon Ross     UINT32                  GpeNumber)
71026f3cdf0SGordon Ross {
71126f3cdf0SGordon Ross     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
71226f3cdf0SGordon Ross     ACPI_STATUS             Status;
71326f3cdf0SGordon Ross     ACPI_CPU_FLAGS          Flags;
71426f3cdf0SGordon Ross 
71526f3cdf0SGordon Ross 
71626f3cdf0SGordon Ross     ACPI_FUNCTION_TRACE (AcpiFinishGpe);
71726f3cdf0SGordon Ross 
71826f3cdf0SGordon Ross 
71926f3cdf0SGordon Ross     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
72026f3cdf0SGordon Ross 
72126f3cdf0SGordon Ross     /* Ensure that we have a valid GPE number */
72226f3cdf0SGordon Ross 
72326f3cdf0SGordon Ross     GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber);
72426f3cdf0SGordon Ross     if (!GpeEventInfo)
72526f3cdf0SGordon Ross     {
72626f3cdf0SGordon Ross         Status = AE_BAD_PARAMETER;
72726f3cdf0SGordon Ross         goto UnlockAndExit;
72826f3cdf0SGordon Ross     }
72926f3cdf0SGordon Ross 
73026f3cdf0SGordon Ross     Status = AcpiEvFinishGpe (GpeEventInfo);
73126f3cdf0SGordon Ross 
73226f3cdf0SGordon Ross UnlockAndExit:
73326f3cdf0SGordon Ross     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
73426f3cdf0SGordon Ross     return_ACPI_STATUS (Status);
73526f3cdf0SGordon Ross }
73626f3cdf0SGordon Ross 
ACPI_EXPORT_SYMBOL(AcpiFinishGpe)73726f3cdf0SGordon Ross ACPI_EXPORT_SYMBOL (AcpiFinishGpe)
73826f3cdf0SGordon Ross 
73926f3cdf0SGordon Ross 
74026f3cdf0SGordon Ross /******************************************************************************
74126f3cdf0SGordon Ross  *
74226f3cdf0SGordon Ross  * FUNCTION:    AcpiDisableAllGpes
74326f3cdf0SGordon Ross  *
74426f3cdf0SGordon Ross  * PARAMETERS:  None
74526f3cdf0SGordon Ross  *
74626f3cdf0SGordon Ross  * RETURN:      Status
74726f3cdf0SGordon Ross  *
74826f3cdf0SGordon Ross  * DESCRIPTION: Disable and clear all GPEs in all GPE blocks
74926f3cdf0SGordon Ross  *
75026f3cdf0SGordon Ross  ******************************************************************************/
75126f3cdf0SGordon Ross 
75226f3cdf0SGordon Ross ACPI_STATUS
75326f3cdf0SGordon Ross AcpiDisableAllGpes (
75426f3cdf0SGordon Ross     void)
75526f3cdf0SGordon Ross {
75626f3cdf0SGordon Ross     ACPI_STATUS             Status;
75726f3cdf0SGordon Ross 
75826f3cdf0SGordon Ross 
75926f3cdf0SGordon Ross     ACPI_FUNCTION_TRACE (AcpiDisableAllGpes);
76026f3cdf0SGordon Ross 
76126f3cdf0SGordon Ross 
76226f3cdf0SGordon Ross     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
76326f3cdf0SGordon Ross     if (ACPI_FAILURE (Status))
76426f3cdf0SGordon Ross     {
76526f3cdf0SGordon Ross         return_ACPI_STATUS (Status);
76626f3cdf0SGordon Ross     }
76726f3cdf0SGordon Ross 
76826f3cdf0SGordon Ross     Status = AcpiHwDisableAllGpes ();
76926f3cdf0SGordon Ross     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
77026f3cdf0SGordon Ross 
77126f3cdf0SGordon Ross     return_ACPI_STATUS (Status);
77226f3cdf0SGordon Ross }
77326f3cdf0SGordon Ross 
ACPI_EXPORT_SYMBOL(AcpiDisableAllGpes)77426f3cdf0SGordon Ross ACPI_EXPORT_SYMBOL (AcpiDisableAllGpes)
77526f3cdf0SGordon Ross 
77626f3cdf0SGordon Ross 
77726f3cdf0SGordon Ross /******************************************************************************
77826f3cdf0SGordon Ross  *
77926f3cdf0SGordon Ross  * FUNCTION:    AcpiEnableAllRuntimeGpes
78026f3cdf0SGordon Ross  *
78126f3cdf0SGordon Ross  * PARAMETERS:  None
78226f3cdf0SGordon Ross  *
78326f3cdf0SGordon Ross  * RETURN:      Status
78426f3cdf0SGordon Ross  *
78526f3cdf0SGordon Ross  * DESCRIPTION: Enable all "runtime" GPEs, in all GPE blocks
78626f3cdf0SGordon Ross  *
78726f3cdf0SGordon Ross  ******************************************************************************/
78826f3cdf0SGordon Ross 
78926f3cdf0SGordon Ross ACPI_STATUS
79026f3cdf0SGordon Ross AcpiEnableAllRuntimeGpes (
79126f3cdf0SGordon Ross     void)
79226f3cdf0SGordon Ross {
79326f3cdf0SGordon Ross     ACPI_STATUS             Status;
79426f3cdf0SGordon Ross 
79526f3cdf0SGordon Ross 
79626f3cdf0SGordon Ross     ACPI_FUNCTION_TRACE (AcpiEnableAllRuntimeGpes);
79726f3cdf0SGordon Ross 
79826f3cdf0SGordon Ross 
79926f3cdf0SGordon Ross     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
80026f3cdf0SGordon Ross     if (ACPI_FAILURE (Status))
80126f3cdf0SGordon Ross     {
80226f3cdf0SGordon Ross         return_ACPI_STATUS (Status);
80326f3cdf0SGordon Ross     }
80426f3cdf0SGordon Ross 
80526f3cdf0SGordon Ross     Status = AcpiHwEnableAllRuntimeGpes ();
80626f3cdf0SGordon Ross     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
80726f3cdf0SGordon Ross 
80826f3cdf0SGordon Ross     return_ACPI_STATUS (Status);
80926f3cdf0SGordon Ross }
81026f3cdf0SGordon Ross 
ACPI_EXPORT_SYMBOL(AcpiEnableAllRuntimeGpes)81126f3cdf0SGordon Ross ACPI_EXPORT_SYMBOL (AcpiEnableAllRuntimeGpes)
81226f3cdf0SGordon Ross 
81326f3cdf0SGordon Ross 
814*cb565728SJerry Jelinek /******************************************************************************
815*cb565728SJerry Jelinek  *
816*cb565728SJerry Jelinek  * FUNCTION:    AcpiEnableAllWakeupGpes
817*cb565728SJerry Jelinek  *
818*cb565728SJerry Jelinek  * PARAMETERS:  None
819*cb565728SJerry Jelinek  *
820*cb565728SJerry Jelinek  * RETURN:      Status
821*cb565728SJerry Jelinek  *
822*cb565728SJerry Jelinek  * DESCRIPTION: Enable all "wakeup" GPEs and disable all of the other GPEs, in
823*cb565728SJerry Jelinek  *              all GPE blocks.
824*cb565728SJerry Jelinek  *
825*cb565728SJerry Jelinek  ******************************************************************************/
826*cb565728SJerry Jelinek 
827*cb565728SJerry Jelinek ACPI_STATUS
828*cb565728SJerry Jelinek AcpiEnableAllWakeupGpes (
829*cb565728SJerry Jelinek     void)
830*cb565728SJerry Jelinek {
831*cb565728SJerry Jelinek     ACPI_STATUS             Status;
832*cb565728SJerry Jelinek 
833*cb565728SJerry Jelinek 
834*cb565728SJerry Jelinek     ACPI_FUNCTION_TRACE (AcpiEnableAllWakeupGpes);
835*cb565728SJerry Jelinek 
836*cb565728SJerry Jelinek 
837*cb565728SJerry Jelinek     Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS);
838*cb565728SJerry Jelinek     if (ACPI_FAILURE (Status))
839*cb565728SJerry Jelinek     {
840*cb565728SJerry Jelinek         return_ACPI_STATUS (Status);
841*cb565728SJerry Jelinek     }
842*cb565728SJerry Jelinek 
843*cb565728SJerry Jelinek     Status = AcpiHwEnableAllWakeupGpes ();
844*cb565728SJerry Jelinek     (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS);
845*cb565728SJerry Jelinek 
846*cb565728SJerry Jelinek     return_ACPI_STATUS (Status);
847*cb565728SJerry Jelinek }
848*cb565728SJerry Jelinek 
ACPI_EXPORT_SYMBOL(AcpiEnableAllWakeupGpes)849*cb565728SJerry Jelinek ACPI_EXPORT_SYMBOL (AcpiEnableAllWakeupGpes)
850*cb565728SJerry Jelinek 
851*cb565728SJerry Jelinek 
85226f3cdf0SGordon Ross /*******************************************************************************
85326f3cdf0SGordon Ross  *
85426f3cdf0SGordon Ross  * FUNCTION:    AcpiInstallGpeBlock
85526f3cdf0SGordon Ross  *
85626f3cdf0SGordon Ross  * PARAMETERS:  GpeDevice           - Handle to the parent GPE Block Device
85726f3cdf0SGordon Ross  *              GpeBlockAddress     - Address and SpaceID
85826f3cdf0SGordon Ross  *              RegisterCount       - Number of GPE register pairs in the block
85926f3cdf0SGordon Ross  *              InterruptNumber     - H/W interrupt for the block
86026f3cdf0SGordon Ross  *
86126f3cdf0SGordon Ross  * RETURN:      Status
86226f3cdf0SGordon Ross  *
86326f3cdf0SGordon Ross  * DESCRIPTION: Create and Install a block of GPE registers. The GPEs are not
86426f3cdf0SGordon Ross  *              enabled here.
86526f3cdf0SGordon Ross  *
86626f3cdf0SGordon Ross  ******************************************************************************/
86726f3cdf0SGordon Ross 
86826f3cdf0SGordon Ross ACPI_STATUS
86926f3cdf0SGordon Ross AcpiInstallGpeBlock (
87026f3cdf0SGordon Ross     ACPI_HANDLE             GpeDevice,
87126f3cdf0SGordon Ross     ACPI_GENERIC_ADDRESS    *GpeBlockAddress,
87226f3cdf0SGordon Ross     UINT32                  RegisterCount,
87326f3cdf0SGordon Ross     UINT32                  InterruptNumber)
87426f3cdf0SGordon Ross {
87526f3cdf0SGordon Ross     ACPI_STATUS             Status;
87626f3cdf0SGordon Ross     ACPI_OPERAND_OBJECT     *ObjDesc;
87726f3cdf0SGordon Ross     ACPI_NAMESPACE_NODE     *Node;
87826f3cdf0SGordon Ross     ACPI_GPE_BLOCK_INFO     *GpeBlock;
87926f3cdf0SGordon Ross 
88026f3cdf0SGordon Ross 
88126f3cdf0SGordon Ross     ACPI_FUNCTION_TRACE (AcpiInstallGpeBlock);
88226f3cdf0SGordon Ross 
88326f3cdf0SGordon Ross 
88426f3cdf0SGordon Ross     if ((!GpeDevice)       ||
88526f3cdf0SGordon Ross         (!GpeBlockAddress) ||
88626f3cdf0SGordon Ross         (!RegisterCount))
88726f3cdf0SGordon Ross     {
88826f3cdf0SGordon Ross         return_ACPI_STATUS (AE_BAD_PARAMETER);
88926f3cdf0SGordon Ross     }
89026f3cdf0SGordon Ross 
89126f3cdf0SGordon Ross     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
89226f3cdf0SGordon Ross     if (ACPI_FAILURE (Status))
89326f3cdf0SGordon Ross     {
894*cb565728SJerry Jelinek         return_ACPI_STATUS (Status);
89526f3cdf0SGordon Ross     }
89626f3cdf0SGordon Ross 
89726f3cdf0SGordon Ross     Node = AcpiNsValidateHandle (GpeDevice);
89826f3cdf0SGordon Ross     if (!Node)
89926f3cdf0SGordon Ross     {
90026f3cdf0SGordon Ross         Status = AE_BAD_PARAMETER;
90126f3cdf0SGordon Ross         goto UnlockAndExit;
90226f3cdf0SGordon Ross     }
90326f3cdf0SGordon Ross 
904*cb565728SJerry Jelinek     /* Validate the parent device */
905*cb565728SJerry Jelinek 
906*cb565728SJerry Jelinek     if (Node->Type != ACPI_TYPE_DEVICE)
907*cb565728SJerry Jelinek     {
908*cb565728SJerry Jelinek         Status = AE_TYPE;
909*cb565728SJerry Jelinek         goto UnlockAndExit;
910*cb565728SJerry Jelinek     }
911*cb565728SJerry Jelinek 
912*cb565728SJerry Jelinek     if (Node->Object)
913*cb565728SJerry Jelinek     {
914*cb565728SJerry Jelinek         Status = AE_ALREADY_EXISTS;
915*cb565728SJerry Jelinek         goto UnlockAndExit;
916*cb565728SJerry Jelinek     }
917*cb565728SJerry Jelinek 
91826f3cdf0SGordon Ross     /*
91926f3cdf0SGordon Ross      * For user-installed GPE Block Devices, the GpeBlockBaseNumber
92026f3cdf0SGordon Ross      * is always zero
92126f3cdf0SGordon Ross      */
922*cb565728SJerry Jelinek     Status = AcpiEvCreateGpeBlock (Node, GpeBlockAddress->Address,
923*cb565728SJerry Jelinek         GpeBlockAddress->SpaceId, RegisterCount,
92426f3cdf0SGordon Ross         0, InterruptNumber, &GpeBlock);
92526f3cdf0SGordon Ross     if (ACPI_FAILURE (Status))
92626f3cdf0SGordon Ross     {
92726f3cdf0SGordon Ross         goto UnlockAndExit;
92826f3cdf0SGordon Ross     }
92926f3cdf0SGordon Ross 
93026f3cdf0SGordon Ross     /* Install block in the DeviceObject attached to the node */
93126f3cdf0SGordon Ross 
93226f3cdf0SGordon Ross     ObjDesc = AcpiNsGetAttachedObject (Node);
93326f3cdf0SGordon Ross     if (!ObjDesc)
93426f3cdf0SGordon Ross     {
93526f3cdf0SGordon Ross         /*
93626f3cdf0SGordon Ross          * No object, create a new one (Device nodes do not always have
93726f3cdf0SGordon Ross          * an attached object)
93826f3cdf0SGordon Ross          */
93926f3cdf0SGordon Ross         ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_DEVICE);
94026f3cdf0SGordon Ross         if (!ObjDesc)
94126f3cdf0SGordon Ross         {
94226f3cdf0SGordon Ross             Status = AE_NO_MEMORY;
94326f3cdf0SGordon Ross             goto UnlockAndExit;
94426f3cdf0SGordon Ross         }
94526f3cdf0SGordon Ross 
94626f3cdf0SGordon Ross         Status = AcpiNsAttachObject (Node, ObjDesc, ACPI_TYPE_DEVICE);
94726f3cdf0SGordon Ross 
94826f3cdf0SGordon Ross         /* Remove local reference to the object */
94926f3cdf0SGordon Ross 
95026f3cdf0SGordon Ross         AcpiUtRemoveReference (ObjDesc);
95126f3cdf0SGordon Ross         if (ACPI_FAILURE (Status))
95226f3cdf0SGordon Ross         {
95326f3cdf0SGordon Ross             goto UnlockAndExit;
95426f3cdf0SGordon Ross         }
95526f3cdf0SGordon Ross     }
95626f3cdf0SGordon Ross 
95726f3cdf0SGordon Ross     /* Now install the GPE block in the DeviceObject */
95826f3cdf0SGordon Ross 
95926f3cdf0SGordon Ross     ObjDesc->Device.GpeBlock = GpeBlock;
96026f3cdf0SGordon Ross 
96126f3cdf0SGordon Ross 
96226f3cdf0SGordon Ross UnlockAndExit:
96326f3cdf0SGordon Ross     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
96426f3cdf0SGordon Ross     return_ACPI_STATUS (Status);
96526f3cdf0SGordon Ross }
96626f3cdf0SGordon Ross 
ACPI_EXPORT_SYMBOL(AcpiInstallGpeBlock)96726f3cdf0SGordon Ross ACPI_EXPORT_SYMBOL (AcpiInstallGpeBlock)
96826f3cdf0SGordon Ross 
96926f3cdf0SGordon Ross 
97026f3cdf0SGordon Ross /*******************************************************************************
97126f3cdf0SGordon Ross  *
97226f3cdf0SGordon Ross  * FUNCTION:    AcpiRemoveGpeBlock
97326f3cdf0SGordon Ross  *
97426f3cdf0SGordon Ross  * PARAMETERS:  GpeDevice           - Handle to the parent GPE Block Device
97526f3cdf0SGordon Ross  *
97626f3cdf0SGordon Ross  * RETURN:      Status
97726f3cdf0SGordon Ross  *
97826f3cdf0SGordon Ross  * DESCRIPTION: Remove a previously installed block of GPE registers
97926f3cdf0SGordon Ross  *
98026f3cdf0SGordon Ross  ******************************************************************************/
98126f3cdf0SGordon Ross 
98226f3cdf0SGordon Ross ACPI_STATUS
98326f3cdf0SGordon Ross AcpiRemoveGpeBlock (
98426f3cdf0SGordon Ross     ACPI_HANDLE             GpeDevice)
98526f3cdf0SGordon Ross {
98626f3cdf0SGordon Ross     ACPI_OPERAND_OBJECT     *ObjDesc;
98726f3cdf0SGordon Ross     ACPI_STATUS             Status;
98826f3cdf0SGordon Ross     ACPI_NAMESPACE_NODE     *Node;
98926f3cdf0SGordon Ross 
99026f3cdf0SGordon Ross 
99126f3cdf0SGordon Ross     ACPI_FUNCTION_TRACE (AcpiRemoveGpeBlock);
99226f3cdf0SGordon Ross 
99326f3cdf0SGordon Ross 
99426f3cdf0SGordon Ross     if (!GpeDevice)
99526f3cdf0SGordon Ross     {
99626f3cdf0SGordon Ross         return_ACPI_STATUS (AE_BAD_PARAMETER);
99726f3cdf0SGordon Ross     }
99826f3cdf0SGordon Ross 
99926f3cdf0SGordon Ross     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
100026f3cdf0SGordon Ross     if (ACPI_FAILURE (Status))
100126f3cdf0SGordon Ross     {
1002*cb565728SJerry Jelinek         return_ACPI_STATUS (Status);
100326f3cdf0SGordon Ross     }
100426f3cdf0SGordon Ross 
100526f3cdf0SGordon Ross     Node = AcpiNsValidateHandle (GpeDevice);
100626f3cdf0SGordon Ross     if (!Node)
100726f3cdf0SGordon Ross     {
100826f3cdf0SGordon Ross         Status = AE_BAD_PARAMETER;
100926f3cdf0SGordon Ross         goto UnlockAndExit;
101026f3cdf0SGordon Ross     }
101126f3cdf0SGordon Ross 
1012*cb565728SJerry Jelinek     /* Validate the parent device */
1013*cb565728SJerry Jelinek 
1014*cb565728SJerry Jelinek     if (Node->Type != ACPI_TYPE_DEVICE)
1015*cb565728SJerry Jelinek     {
1016*cb565728SJerry Jelinek         Status = AE_TYPE;
1017*cb565728SJerry Jelinek         goto UnlockAndExit;
1018*cb565728SJerry Jelinek     }
1019*cb565728SJerry Jelinek 
102026f3cdf0SGordon Ross     /* Get the DeviceObject attached to the node */
102126f3cdf0SGordon Ross 
102226f3cdf0SGordon Ross     ObjDesc = AcpiNsGetAttachedObject (Node);
102326f3cdf0SGordon Ross     if (!ObjDesc ||
102426f3cdf0SGordon Ross         !ObjDesc->Device.GpeBlock)
102526f3cdf0SGordon Ross     {
102626f3cdf0SGordon Ross         return_ACPI_STATUS (AE_NULL_OBJECT);
102726f3cdf0SGordon Ross     }
102826f3cdf0SGordon Ross 
102926f3cdf0SGordon Ross     /* Delete the GPE block (but not the DeviceObject) */
103026f3cdf0SGordon Ross 
103126f3cdf0SGordon Ross     Status = AcpiEvDeleteGpeBlock (ObjDesc->Device.GpeBlock);
103226f3cdf0SGordon Ross     if (ACPI_SUCCESS (Status))
103326f3cdf0SGordon Ross     {
103426f3cdf0SGordon Ross         ObjDesc->Device.GpeBlock = NULL;
103526f3cdf0SGordon Ross     }
103626f3cdf0SGordon Ross 
103726f3cdf0SGordon Ross UnlockAndExit:
103826f3cdf0SGordon Ross     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
103926f3cdf0SGordon Ross     return_ACPI_STATUS (Status);
104026f3cdf0SGordon Ross }
104126f3cdf0SGordon Ross 
ACPI_EXPORT_SYMBOL(AcpiRemoveGpeBlock)104226f3cdf0SGordon Ross ACPI_EXPORT_SYMBOL (AcpiRemoveGpeBlock)
104326f3cdf0SGordon Ross 
104426f3cdf0SGordon Ross 
104526f3cdf0SGordon Ross /*******************************************************************************
104626f3cdf0SGordon Ross  *
104726f3cdf0SGordon Ross  * FUNCTION:    AcpiGetGpeDevice
104826f3cdf0SGordon Ross  *
104926f3cdf0SGordon Ross  * PARAMETERS:  Index               - System GPE index (0-CurrentGpeCount)
105026f3cdf0SGordon Ross  *              GpeDevice           - Where the parent GPE Device is returned
105126f3cdf0SGordon Ross  *
105226f3cdf0SGordon Ross  * RETURN:      Status
105326f3cdf0SGordon Ross  *
105426f3cdf0SGordon Ross  * DESCRIPTION: Obtain the GPE device associated with the input index. A NULL
105526f3cdf0SGordon Ross  *              gpe device indicates that the gpe number is contained in one of
105626f3cdf0SGordon Ross  *              the FADT-defined gpe blocks. Otherwise, the GPE block device.
105726f3cdf0SGordon Ross  *
105826f3cdf0SGordon Ross  ******************************************************************************/
105926f3cdf0SGordon Ross 
106026f3cdf0SGordon Ross ACPI_STATUS
106126f3cdf0SGordon Ross AcpiGetGpeDevice (
106226f3cdf0SGordon Ross     UINT32                  Index,
106326f3cdf0SGordon Ross     ACPI_HANDLE             *GpeDevice)
106426f3cdf0SGordon Ross {
106526f3cdf0SGordon Ross     ACPI_GPE_DEVICE_INFO    Info;
106626f3cdf0SGordon Ross     ACPI_STATUS             Status;
106726f3cdf0SGordon Ross 
106826f3cdf0SGordon Ross 
106926f3cdf0SGordon Ross     ACPI_FUNCTION_TRACE (AcpiGetGpeDevice);
107026f3cdf0SGordon Ross 
107126f3cdf0SGordon Ross 
107226f3cdf0SGordon Ross     if (!GpeDevice)
107326f3cdf0SGordon Ross     {
107426f3cdf0SGordon Ross         return_ACPI_STATUS (AE_BAD_PARAMETER);
107526f3cdf0SGordon Ross     }
107626f3cdf0SGordon Ross 
107726f3cdf0SGordon Ross     if (Index >= AcpiCurrentGpeCount)
107826f3cdf0SGordon Ross     {
107926f3cdf0SGordon Ross         return_ACPI_STATUS (AE_NOT_EXIST);
108026f3cdf0SGordon Ross     }
108126f3cdf0SGordon Ross 
108226f3cdf0SGordon Ross     /* Setup and walk the GPE list */
108326f3cdf0SGordon Ross 
108426f3cdf0SGordon Ross     Info.Index = Index;
108526f3cdf0SGordon Ross     Info.Status = AE_NOT_EXIST;
108626f3cdf0SGordon Ross     Info.GpeDevice = NULL;
108726f3cdf0SGordon Ross     Info.NextBlockBaseIndex = 0;
108826f3cdf0SGordon Ross 
108926f3cdf0SGordon Ross     Status = AcpiEvWalkGpeList (AcpiEvGetGpeDevice, &Info);
109026f3cdf0SGordon Ross     if (ACPI_FAILURE (Status))
109126f3cdf0SGordon Ross     {
109226f3cdf0SGordon Ross         return_ACPI_STATUS (Status);
109326f3cdf0SGordon Ross     }
109426f3cdf0SGordon Ross 
109526f3cdf0SGordon Ross     *GpeDevice = ACPI_CAST_PTR (ACPI_HANDLE, Info.GpeDevice);
109626f3cdf0SGordon Ross     return_ACPI_STATUS (Info.Status);
109726f3cdf0SGordon Ross }
109826f3cdf0SGordon Ross 
109926f3cdf0SGordon Ross ACPI_EXPORT_SYMBOL (AcpiGetGpeDevice)
1100*cb565728SJerry Jelinek 
1101*cb565728SJerry Jelinek #endif /* !ACPI_REDUCED_HARDWARE */
1102