17c478bd9Sstevel@tonic-gate /******************************************************************************
27c478bd9Sstevel@tonic-gate  *
37c478bd9Sstevel@tonic-gate  * Module Name: evgpe - General Purpose Event handling and dispatch
47c478bd9Sstevel@tonic-gate  *
57c478bd9Sstevel@tonic-gate  *****************************************************************************/
67c478bd9Sstevel@tonic-gate 
7*35786f68SRobert Mustacchi /******************************************************************************
8*35786f68SRobert Mustacchi  *
9*35786f68SRobert Mustacchi  * 1. Copyright Notice
10*35786f68SRobert Mustacchi  *
11*35786f68SRobert Mustacchi  * Some or all of this work - Copyright (c) 1999 - 2018, Intel Corp.
127c478bd9Sstevel@tonic-gate  * All rights reserved.
137c478bd9Sstevel@tonic-gate  *
14*35786f68SRobert Mustacchi  * 2. License
15*35786f68SRobert Mustacchi  *
16*35786f68SRobert Mustacchi  * 2.1. This is your license from Intel Corp. under its intellectual property
17*35786f68SRobert Mustacchi  * rights. You may have additional license terms from the party that provided
18*35786f68SRobert Mustacchi  * you this software, covering your right to use that party's intellectual
19*35786f68SRobert Mustacchi  * property rights.
20*35786f68SRobert Mustacchi  *
21*35786f68SRobert Mustacchi  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22*35786f68SRobert Mustacchi  * copy of the source code appearing in this file ("Covered Code") an
23*35786f68SRobert Mustacchi  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24*35786f68SRobert Mustacchi  * base code distributed originally by Intel ("Original Intel Code") to copy,
25*35786f68SRobert Mustacchi  * make derivatives, distribute, use and display any portion of the Covered
26*35786f68SRobert Mustacchi  * Code in any form, with the right to sublicense such rights; and
27*35786f68SRobert Mustacchi  *
28*35786f68SRobert Mustacchi  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29*35786f68SRobert Mustacchi  * license (with the right to sublicense), under only those claims of Intel
30*35786f68SRobert Mustacchi  * patents that are infringed by the Original Intel Code, to make, use, sell,
31*35786f68SRobert Mustacchi  * offer to sell, and import the Covered Code and derivative works thereof
32*35786f68SRobert Mustacchi  * solely to the minimum extent necessary to exercise the above copyright
33*35786f68SRobert Mustacchi  * license, and in no event shall the patent license extend to any additions
34*35786f68SRobert Mustacchi  * to or modifications of the Original Intel Code. No other license or right
35*35786f68SRobert Mustacchi  * is granted directly or by implication, estoppel or otherwise;
36*35786f68SRobert Mustacchi  *
37*35786f68SRobert Mustacchi  * The above copyright and patent license is granted only if the following
38*35786f68SRobert Mustacchi  * conditions are met:
39*35786f68SRobert Mustacchi  *
40*35786f68SRobert Mustacchi  * 3. Conditions
41*35786f68SRobert Mustacchi  *
42*35786f68SRobert Mustacchi  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43*35786f68SRobert Mustacchi  * Redistribution of source code of any substantial portion of the Covered
44*35786f68SRobert Mustacchi  * Code or modification with rights to further distribute source must include
45*35786f68SRobert Mustacchi  * the above Copyright Notice, the above License, this list of Conditions,
46*35786f68SRobert Mustacchi  * and the following Disclaimer and Export Compliance provision. In addition,
47*35786f68SRobert Mustacchi  * Licensee must cause all Covered Code to which Licensee contributes to
48*35786f68SRobert Mustacchi  * contain a file documenting the changes Licensee made to create that Covered
49*35786f68SRobert Mustacchi  * Code and the date of any change. Licensee must include in that file the
50*35786f68SRobert Mustacchi  * documentation of any changes made by any predecessor Licensee. Licensee
51*35786f68SRobert Mustacchi  * must include a prominent statement that the modification is derived,
52*35786f68SRobert Mustacchi  * directly or indirectly, from Original Intel Code.
53*35786f68SRobert Mustacchi  *
54*35786f68SRobert Mustacchi  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55*35786f68SRobert Mustacchi  * Redistribution of source code of any substantial portion of the Covered
56*35786f68SRobert Mustacchi  * Code or modification without rights to further distribute source must
57*35786f68SRobert Mustacchi  * include the following Disclaimer and Export Compliance provision in the
58*35786f68SRobert Mustacchi  * documentation and/or other materials provided with distribution. In
59*35786f68SRobert Mustacchi  * addition, Licensee may not authorize further sublicense of source of any
60*35786f68SRobert Mustacchi  * portion of the Covered Code, and must include terms to the effect that the
61*35786f68SRobert Mustacchi  * license from Licensee to its licensee is limited to the intellectual
62*35786f68SRobert Mustacchi  * property embodied in the software Licensee provides to its licensee, and
63*35786f68SRobert Mustacchi  * not to intellectual property embodied in modifications its licensee may
64*35786f68SRobert Mustacchi  * make.
65*35786f68SRobert Mustacchi  *
66*35786f68SRobert Mustacchi  * 3.3. Redistribution of Executable. Redistribution in executable form of any
67*35786f68SRobert Mustacchi  * substantial portion of the Covered Code or modification must reproduce the
68*35786f68SRobert Mustacchi  * above Copyright Notice, and the following Disclaimer and Export Compliance
69*35786f68SRobert Mustacchi  * provision in the documentation and/or other materials provided with the
70*35786f68SRobert Mustacchi  * distribution.
71*35786f68SRobert Mustacchi  *
72*35786f68SRobert Mustacchi  * 3.4. Intel retains all right, title, and interest in and to the Original
73*35786f68SRobert Mustacchi  * Intel Code.
74*35786f68SRobert Mustacchi  *
75*35786f68SRobert Mustacchi  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76*35786f68SRobert Mustacchi  * Intel shall be used in advertising or otherwise to promote the sale, use or
77*35786f68SRobert Mustacchi  * other dealings in products derived from or relating to the Covered Code
78*35786f68SRobert Mustacchi  * without prior written authorization from Intel.
79*35786f68SRobert Mustacchi  *
80*35786f68SRobert Mustacchi  * 4. Disclaimer and Export Compliance
81*35786f68SRobert Mustacchi  *
82*35786f68SRobert Mustacchi  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83*35786f68SRobert Mustacchi  * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84*35786f68SRobert Mustacchi  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
85*35786f68SRobert Mustacchi  * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
86*35786f68SRobert Mustacchi  * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
87*35786f68SRobert Mustacchi  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88*35786f68SRobert Mustacchi  * PARTICULAR PURPOSE.
89*35786f68SRobert Mustacchi  *
90*35786f68SRobert Mustacchi  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91*35786f68SRobert Mustacchi  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92*35786f68SRobert Mustacchi  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93*35786f68SRobert Mustacchi  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94*35786f68SRobert Mustacchi  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95*35786f68SRobert Mustacchi  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
96*35786f68SRobert Mustacchi  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97*35786f68SRobert Mustacchi  * LIMITED REMEDY.
98*35786f68SRobert Mustacchi  *
99*35786f68SRobert Mustacchi  * 4.3. Licensee shall not export, either directly or indirectly, any of this
100*35786f68SRobert Mustacchi  * software or system incorporating such software without first obtaining any
101*35786f68SRobert Mustacchi  * required license or other approval from the U. S. Department of Commerce or
102*35786f68SRobert Mustacchi  * any other agency or department of the United States Government. In the
103*35786f68SRobert Mustacchi  * event Licensee exports any such software from the United States or
104*35786f68SRobert Mustacchi  * re-exports any such software from a foreign destination, Licensee shall
105*35786f68SRobert Mustacchi  * ensure that the distribution and export/re-export of the software is in
106*35786f68SRobert Mustacchi  * compliance with all laws, regulations, orders, or other restrictions of the
107*35786f68SRobert Mustacchi  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108*35786f68SRobert Mustacchi  * any of its subsidiaries will export/re-export any technical data, process,
109*35786f68SRobert Mustacchi  * software, or service, directly or indirectly, to any country for which the
110*35786f68SRobert Mustacchi  * United States government or any agency thereof requires an export license,
111*35786f68SRobert Mustacchi  * other governmental approval, or letter of assurance, without first obtaining
112*35786f68SRobert Mustacchi  * such license, approval or letter.
113*35786f68SRobert Mustacchi  *
114*35786f68SRobert Mustacchi  *****************************************************************************
115*35786f68SRobert Mustacchi  *
116*35786f68SRobert Mustacchi  * Alternatively, you may choose to be licensed under the terms of the
117*35786f68SRobert Mustacchi  * following license:
118*35786f68SRobert Mustacchi  *
11926f3cdf0SGordon Ross  * Redistribution and use in source and binary forms, with or without
12026f3cdf0SGordon Ross  * modification, are permitted provided that the following conditions
12126f3cdf0SGordon Ross  * are met:
12226f3cdf0SGordon Ross  * 1. Redistributions of source code must retain the above copyright
12326f3cdf0SGordon Ross  *    notice, this list of conditions, and the following disclaimer,
12426f3cdf0SGordon Ross  *    without modification.
12526f3cdf0SGordon Ross  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
12626f3cdf0SGordon Ross  *    substantially similar to the "NO WARRANTY" disclaimer below
12726f3cdf0SGordon Ross  *    ("Disclaimer") and any redistribution must be conditioned upon
12826f3cdf0SGordon Ross  *    including a substantially similar Disclaimer requirement for further
12926f3cdf0SGordon Ross  *    binary redistribution.
13026f3cdf0SGordon Ross  * 3. Neither the names of the above-listed copyright holders nor the names
13126f3cdf0SGordon Ross  *    of any contributors may be used to endorse or promote products derived
13226f3cdf0SGordon Ross  *    from this software without specific prior written permission.
13326f3cdf0SGordon Ross  *
13426f3cdf0SGordon Ross  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
13526f3cdf0SGordon Ross  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
136*35786f68SRobert Mustacchi  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
13726f3cdf0SGordon Ross  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
138*35786f68SRobert Mustacchi  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
139*35786f68SRobert Mustacchi  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
140*35786f68SRobert Mustacchi  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
141*35786f68SRobert Mustacchi  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
142*35786f68SRobert Mustacchi  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143*35786f68SRobert Mustacchi  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
144*35786f68SRobert Mustacchi  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
145*35786f68SRobert Mustacchi  *
146*35786f68SRobert Mustacchi  * Alternatively, you may choose to be licensed under the terms of the
147*35786f68SRobert Mustacchi  * GNU General Public License ("GPL") version 2 as published by the Free
148*35786f68SRobert Mustacchi  * Software Foundation.
149*35786f68SRobert Mustacchi  *
150*35786f68SRobert Mustacchi  *****************************************************************************/
1517c478bd9Sstevel@tonic-gate 
1527c478bd9Sstevel@tonic-gate #include "acpi.h"
153aa2aa9a6SDana Myers #include "accommon.h"
1547c478bd9Sstevel@tonic-gate #include "acevents.h"
1557c478bd9Sstevel@tonic-gate #include "acnamesp.h"
1567c478bd9Sstevel@tonic-gate 
1577c478bd9Sstevel@tonic-gate #define _COMPONENT          ACPI_EVENTS
1587c478bd9Sstevel@tonic-gate         ACPI_MODULE_NAME    ("evgpe")
1597c478bd9Sstevel@tonic-gate 
1607b1019a6SJerry Jelinek #if (!ACPI_REDUCED_HARDWARE) /* Entire module */
1617b1019a6SJerry Jelinek 
1627c478bd9Sstevel@tonic-gate /* Local prototypes */
1637c478bd9Sstevel@tonic-gate 
1647c478bd9Sstevel@tonic-gate static void ACPI_SYSTEM_XFACE
1657c478bd9Sstevel@tonic-gate AcpiEvAsynchExecuteGpeMethod (
1667c478bd9Sstevel@tonic-gate     void                    *Context);
1677c478bd9Sstevel@tonic-gate 
168db2bae30SDana Myers static void ACPI_SYSTEM_XFACE
169db2bae30SDana Myers AcpiEvAsynchEnableGpe (
170db2bae30SDana Myers     void                    *Context);
171db2bae30SDana Myers 
1727c478bd9Sstevel@tonic-gate 
1737c478bd9Sstevel@tonic-gate /*******************************************************************************
1747c478bd9Sstevel@tonic-gate  *
17526f3cdf0SGordon Ross  * FUNCTION:    AcpiEvUpdateGpeEnableMask
1767c478bd9Sstevel@tonic-gate  *
17726f3cdf0SGordon Ross  * PARAMETERS:  GpeEventInfo            - GPE to update
1787c478bd9Sstevel@tonic-gate  *
1797c478bd9Sstevel@tonic-gate  * RETURN:      Status
1807c478bd9Sstevel@tonic-gate  *
18126f3cdf0SGordon Ross  * DESCRIPTION: Updates GPE register enable mask based upon whether there are
18226f3cdf0SGordon Ross  *              runtime references to this GPE
1837c478bd9Sstevel@tonic-gate  *
1847c478bd9Sstevel@tonic-gate  ******************************************************************************/
1857c478bd9Sstevel@tonic-gate 
1867c478bd9Sstevel@tonic-gate ACPI_STATUS
AcpiEvUpdateGpeEnableMask(ACPI_GPE_EVENT_INFO * GpeEventInfo)18726f3cdf0SGordon Ross AcpiEvUpdateGpeEnableMask (
18826f3cdf0SGordon Ross     ACPI_GPE_EVENT_INFO     *GpeEventInfo)
1897c478bd9Sstevel@tonic-gate {
19026f3cdf0SGordon Ross     ACPI_GPE_REGISTER_INFO  *GpeRegisterInfo;
19126f3cdf0SGordon Ross     UINT32                  RegisterBit;
1927c478bd9Sstevel@tonic-gate 
1937c478bd9Sstevel@tonic-gate 
19426f3cdf0SGordon Ross     ACPI_FUNCTION_TRACE (EvUpdateGpeEnableMask);
1957c478bd9Sstevel@tonic-gate 
1967c478bd9Sstevel@tonic-gate 
19726f3cdf0SGordon Ross     GpeRegisterInfo = GpeEventInfo->RegisterInfo;
19826f3cdf0SGordon Ross     if (!GpeRegisterInfo)
1997c478bd9Sstevel@tonic-gate     {
20026f3cdf0SGordon Ross         return_ACPI_STATUS (AE_NOT_EXIST);
2017c478bd9Sstevel@tonic-gate     }
2027c478bd9Sstevel@tonic-gate 
2037b1019a6SJerry Jelinek     RegisterBit = AcpiHwGetGpeRegisterBit (GpeEventInfo);
2047c478bd9Sstevel@tonic-gate 
20526f3cdf0SGordon Ross     /* Clear the run bit up front */
2067c478bd9Sstevel@tonic-gate 
20726f3cdf0SGordon Ross     ACPI_CLEAR_BIT (GpeRegisterInfo->EnableForRun, RegisterBit);
2087c478bd9Sstevel@tonic-gate 
20926f3cdf0SGordon Ross     /* Set the mask bit only if there are references to this GPE */
21026f3cdf0SGordon Ross 
21126f3cdf0SGordon Ross     if (GpeEventInfo->RuntimeCount)
21226f3cdf0SGordon Ross     {
21326f3cdf0SGordon Ross         ACPI_SET_BIT (GpeRegisterInfo->EnableForRun, (UINT8) RegisterBit);
21426f3cdf0SGordon Ross     }
21526f3cdf0SGordon Ross 
2167b1019a6SJerry Jelinek     GpeRegisterInfo->EnableMask = GpeRegisterInfo->EnableForRun;
21726f3cdf0SGordon Ross     return_ACPI_STATUS (AE_OK);
2187c478bd9Sstevel@tonic-gate }
2197c478bd9Sstevel@tonic-gate 
2207c478bd9Sstevel@tonic-gate 
2217c478bd9Sstevel@tonic-gate /*******************************************************************************
2227c478bd9Sstevel@tonic-gate  *
22326f3cdf0SGordon Ross  * FUNCTION:    AcpiEvEnableGpe
2247c478bd9Sstevel@tonic-gate  *
22526f3cdf0SGordon Ross  * PARAMETERS:  GpeEventInfo            - GPE to enable
2267c478bd9Sstevel@tonic-gate  *
2277c478bd9Sstevel@tonic-gate  * RETURN:      Status
2287c478bd9Sstevel@tonic-gate  *
229*35786f68SRobert Mustacchi  * DESCRIPTION: Enable a GPE.
2307c478bd9Sstevel@tonic-gate  *
2317c478bd9Sstevel@tonic-gate  ******************************************************************************/
2327c478bd9Sstevel@tonic-gate 
2337c478bd9Sstevel@tonic-gate ACPI_STATUS
AcpiEvEnableGpe(ACPI_GPE_EVENT_INFO * GpeEventInfo)23426f3cdf0SGordon Ross AcpiEvEnableGpe (
23526f3cdf0SGordon Ross     ACPI_GPE_EVENT_INFO     *GpeEventInfo)
2367c478bd9Sstevel@tonic-gate {
23726f3cdf0SGordon Ross     ACPI_STATUS             Status;
2387c478bd9Sstevel@tonic-gate 
2397c478bd9Sstevel@tonic-gate 
24026f3cdf0SGordon Ross     ACPI_FUNCTION_TRACE (EvEnableGpe);
2417c478bd9Sstevel@tonic-gate 
2427c478bd9Sstevel@tonic-gate 
243*35786f68SRobert Mustacchi     /* Enable the requested GPE */
2447c478bd9Sstevel@tonic-gate 
245*35786f68SRobert Mustacchi     Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_ENABLE);
246*35786f68SRobert Mustacchi     return_ACPI_STATUS (Status);
247*35786f68SRobert Mustacchi }
248*35786f68SRobert Mustacchi 
249*35786f68SRobert Mustacchi 
250*35786f68SRobert Mustacchi /*******************************************************************************
251*35786f68SRobert Mustacchi  *
252*35786f68SRobert Mustacchi  * FUNCTION:    AcpiEvMaskGpe
253*35786f68SRobert Mustacchi  *
254*35786f68SRobert Mustacchi  * PARAMETERS:  GpeEventInfo            - GPE to be blocked/unblocked
255*35786f68SRobert Mustacchi  *              IsMasked                - Whether the GPE is masked or not
256*35786f68SRobert Mustacchi  *
257*35786f68SRobert Mustacchi  * RETURN:      Status
258*35786f68SRobert Mustacchi  *
259*35786f68SRobert Mustacchi  * DESCRIPTION: Unconditionally mask/unmask a GPE during runtime.
260*35786f68SRobert Mustacchi  *
261*35786f68SRobert Mustacchi  ******************************************************************************/
262*35786f68SRobert Mustacchi 
263*35786f68SRobert Mustacchi ACPI_STATUS
AcpiEvMaskGpe(ACPI_GPE_EVENT_INFO * GpeEventInfo,BOOLEAN IsMasked)264*35786f68SRobert Mustacchi AcpiEvMaskGpe (
265*35786f68SRobert Mustacchi     ACPI_GPE_EVENT_INFO     *GpeEventInfo,
266*35786f68SRobert Mustacchi     BOOLEAN                 IsMasked)
267*35786f68SRobert Mustacchi {
268*35786f68SRobert Mustacchi     ACPI_GPE_REGISTER_INFO  *GpeRegisterInfo;
269*35786f68SRobert Mustacchi     UINT32                  RegisterBit;
270*35786f68SRobert Mustacchi 
271*35786f68SRobert Mustacchi 
272*35786f68SRobert Mustacchi     ACPI_FUNCTION_TRACE (EvMaskGpe);
273*35786f68SRobert Mustacchi 
274*35786f68SRobert Mustacchi 
275*35786f68SRobert Mustacchi     GpeRegisterInfo = GpeEventInfo->RegisterInfo;
276*35786f68SRobert Mustacchi     if (!GpeRegisterInfo)
2777c478bd9Sstevel@tonic-gate     {
278*35786f68SRobert Mustacchi         return_ACPI_STATUS (AE_NOT_EXIST);
2797c478bd9Sstevel@tonic-gate     }
2807c478bd9Sstevel@tonic-gate 
281*35786f68SRobert Mustacchi     RegisterBit = AcpiHwGetGpeRegisterBit (GpeEventInfo);
2827c478bd9Sstevel@tonic-gate 
283*35786f68SRobert Mustacchi     /* Perform the action */
284*35786f68SRobert Mustacchi 
285*35786f68SRobert Mustacchi     if (IsMasked)
286*35786f68SRobert Mustacchi     {
287*35786f68SRobert Mustacchi         if (RegisterBit & GpeRegisterInfo->MaskForRun)
288*35786f68SRobert Mustacchi         {
289*35786f68SRobert Mustacchi             return_ACPI_STATUS (AE_BAD_PARAMETER);
290*35786f68SRobert Mustacchi         }
291*35786f68SRobert Mustacchi 
292*35786f68SRobert Mustacchi         (void) AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_DISABLE);
293*35786f68SRobert Mustacchi         ACPI_SET_BIT (GpeRegisterInfo->MaskForRun, (UINT8) RegisterBit);
294*35786f68SRobert Mustacchi     }
295*35786f68SRobert Mustacchi     else
296*35786f68SRobert Mustacchi     {
297*35786f68SRobert Mustacchi         if (!(RegisterBit & GpeRegisterInfo->MaskForRun))
298*35786f68SRobert Mustacchi         {
299*35786f68SRobert Mustacchi             return_ACPI_STATUS (AE_BAD_PARAMETER);
300*35786f68SRobert Mustacchi         }
301*35786f68SRobert Mustacchi 
302*35786f68SRobert Mustacchi         ACPI_CLEAR_BIT (GpeRegisterInfo->MaskForRun, (UINT8) RegisterBit);
303*35786f68SRobert Mustacchi         if (GpeEventInfo->RuntimeCount &&
304*35786f68SRobert Mustacchi             !GpeEventInfo->DisableForDispatch)
305*35786f68SRobert Mustacchi         {
306*35786f68SRobert Mustacchi             (void) AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_ENABLE);
307*35786f68SRobert Mustacchi         }
308*35786f68SRobert Mustacchi     }
309*35786f68SRobert Mustacchi 
310*35786f68SRobert Mustacchi     return_ACPI_STATUS (AE_OK);
3117c478bd9Sstevel@tonic-gate }
3127c478bd9Sstevel@tonic-gate 
3137c478bd9Sstevel@tonic-gate 
3147c478bd9Sstevel@tonic-gate /*******************************************************************************
3157c478bd9Sstevel@tonic-gate  *
31626f3cdf0SGordon Ross  * FUNCTION:    AcpiEvAddGpeReference
3177c478bd9Sstevel@tonic-gate  *
31826f3cdf0SGordon Ross  * PARAMETERS:  GpeEventInfo            - Add a reference to this GPE
3197c478bd9Sstevel@tonic-gate  *
3207c478bd9Sstevel@tonic-gate  * RETURN:      Status
3217c478bd9Sstevel@tonic-gate  *
32226f3cdf0SGordon Ross  * DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is
32326f3cdf0SGordon Ross  *              hardware-enabled.
3247c478bd9Sstevel@tonic-gate  *
3257c478bd9Sstevel@tonic-gate  ******************************************************************************/
3267c478bd9Sstevel@tonic-gate 
3277c478bd9Sstevel@tonic-gate ACPI_STATUS
AcpiEvAddGpeReference(ACPI_GPE_EVENT_INFO * GpeEventInfo)32826f3cdf0SGordon Ross AcpiEvAddGpeReference (
32926f3cdf0SGordon Ross     ACPI_GPE_EVENT_INFO     *GpeEventInfo)
3307c478bd9Sstevel@tonic-gate {
33126f3cdf0SGordon Ross     ACPI_STATUS             Status = AE_OK;
3327c478bd9Sstevel@tonic-gate 
3337c478bd9Sstevel@tonic-gate 
33426f3cdf0SGordon Ross     ACPI_FUNCTION_TRACE (EvAddGpeReference);
3357c478bd9Sstevel@tonic-gate 
3367c478bd9Sstevel@tonic-gate 
33726f3cdf0SGordon Ross     if (GpeEventInfo->RuntimeCount == ACPI_UINT8_MAX)
3387c478bd9Sstevel@tonic-gate     {
33926f3cdf0SGordon Ross         return_ACPI_STATUS (AE_LIMIT);
3407c478bd9Sstevel@tonic-gate     }
3417c478bd9Sstevel@tonic-gate 
34226f3cdf0SGordon Ross     GpeEventInfo->RuntimeCount++;
34326f3cdf0SGordon Ross     if (GpeEventInfo->RuntimeCount == 1)
3447c478bd9Sstevel@tonic-gate     {
34526f3cdf0SGordon Ross         /* Enable on first reference */
3467c478bd9Sstevel@tonic-gate 
34726f3cdf0SGordon Ross         Status = AcpiEvUpdateGpeEnableMask (GpeEventInfo);
34826f3cdf0SGordon Ross         if (ACPI_SUCCESS (Status))
3497c478bd9Sstevel@tonic-gate         {
35026f3cdf0SGordon Ross             Status = AcpiEvEnableGpe (GpeEventInfo);
3517c478bd9Sstevel@tonic-gate         }
3527c478bd9Sstevel@tonic-gate 
35326f3cdf0SGordon Ross         if (ACPI_FAILURE (Status))
35426f3cdf0SGordon Ross         {
35526f3cdf0SGordon Ross             GpeEventInfo->RuntimeCount--;
35626f3cdf0SGordon Ross         }
3577c478bd9Sstevel@tonic-gate     }
3587c478bd9Sstevel@tonic-gate 
35926f3cdf0SGordon Ross     return_ACPI_STATUS (Status);
3607c478bd9Sstevel@tonic-gate }
3617c478bd9Sstevel@tonic-gate 
3627c478bd9Sstevel@tonic-gate 
3637c478bd9Sstevel@tonic-gate /*******************************************************************************
3647c478bd9Sstevel@tonic-gate  *
36526f3cdf0SGordon Ross  * FUNCTION:    AcpiEvRemoveGpeReference
3667c478bd9Sstevel@tonic-gate  *
36726f3cdf0SGordon Ross  * PARAMETERS:  GpeEventInfo            - Remove a reference to this GPE
3687c478bd9Sstevel@tonic-gate  *
3697c478bd9Sstevel@tonic-gate  * RETURN:      Status
3707c478bd9Sstevel@tonic-gate  *
37126f3cdf0SGordon Ross  * DESCRIPTION: Remove a reference to a GPE. When the last reference is
37226f3cdf0SGordon Ross  *              removed, the GPE is hardware-disabled.
3737c478bd9Sstevel@tonic-gate  *
3747c478bd9Sstevel@tonic-gate  ******************************************************************************/
3757c478bd9Sstevel@tonic-gate 
3767c478bd9Sstevel@tonic-gate ACPI_STATUS
AcpiEvRemoveGpeReference(ACPI_GPE_EVENT_INFO * GpeEventInfo)37726f3cdf0SGordon Ross AcpiEvRemoveGpeReference (
3787c478bd9Sstevel@tonic-gate     ACPI_GPE_EVENT_INFO     *GpeEventInfo)
3797c478bd9Sstevel@tonic-gate {
38026f3cdf0SGordon Ross     ACPI_STATUS             Status = AE_OK;
3817c478bd9Sstevel@tonic-gate 
3827c478bd9Sstevel@tonic-gate 
38326f3cdf0SGordon Ross     ACPI_FUNCTION_TRACE (EvRemoveGpeReference);
3847c478bd9Sstevel@tonic-gate 
3857c478bd9Sstevel@tonic-gate 
38626f3cdf0SGordon Ross     if (!GpeEventInfo->RuntimeCount)
3877c478bd9Sstevel@tonic-gate     {
38826f3cdf0SGordon Ross         return_ACPI_STATUS (AE_LIMIT);
3897c478bd9Sstevel@tonic-gate     }
3907c478bd9Sstevel@tonic-gate 
39126f3cdf0SGordon Ross     GpeEventInfo->RuntimeCount--;
39226f3cdf0SGordon Ross     if (!GpeEventInfo->RuntimeCount)
3937c478bd9Sstevel@tonic-gate     {
39426f3cdf0SGordon Ross         /* Disable on last reference */
395db2bae30SDana Myers 
39626f3cdf0SGordon Ross         Status = AcpiEvUpdateGpeEnableMask (GpeEventInfo);
39726f3cdf0SGordon Ross         if (ACPI_SUCCESS (Status))
39826f3cdf0SGordon Ross         {
39926f3cdf0SGordon Ross             Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_DISABLE);
40026f3cdf0SGordon Ross         }
401db2bae30SDana Myers 
40226f3cdf0SGordon Ross         if (ACPI_FAILURE (Status))
40326f3cdf0SGordon Ross         {
40426f3cdf0SGordon Ross             GpeEventInfo->RuntimeCount++;
40526f3cdf0SGordon Ross         }
40626f3cdf0SGordon Ross     }
4077c478bd9Sstevel@tonic-gate 
40826f3cdf0SGordon Ross     return_ACPI_STATUS (Status);
40926f3cdf0SGordon Ross }
4107c478bd9Sstevel@tonic-gate 
4117c478bd9Sstevel@tonic-gate 
41226f3cdf0SGordon Ross /*******************************************************************************
41326f3cdf0SGordon Ross  *
41426f3cdf0SGordon Ross  * FUNCTION:    AcpiEvLowGetGpeInfo
41526f3cdf0SGordon Ross  *
41626f3cdf0SGordon Ross  * PARAMETERS:  GpeNumber           - Raw GPE number
41726f3cdf0SGordon Ross  *              GpeBlock            - A GPE info block
41826f3cdf0SGordon Ross  *
41926f3cdf0SGordon Ross  * RETURN:      A GPE EventInfo struct. NULL if not a valid GPE (The GpeNumber
42026f3cdf0SGordon Ross  *              is not within the specified GPE block)
42126f3cdf0SGordon Ross  *
42226f3cdf0SGordon Ross  * DESCRIPTION: Returns the EventInfo struct associated with this GPE. This is
42326f3cdf0SGordon Ross  *              the low-level implementation of EvGetGpeEventInfo.
42426f3cdf0SGordon Ross  *
42526f3cdf0SGordon Ross  ******************************************************************************/
4267c478bd9Sstevel@tonic-gate 
42726f3cdf0SGordon Ross ACPI_GPE_EVENT_INFO *
AcpiEvLowGetGpeInfo(UINT32 GpeNumber,ACPI_GPE_BLOCK_INFO * GpeBlock)42826f3cdf0SGordon Ross AcpiEvLowGetGpeInfo (
42926f3cdf0SGordon Ross     UINT32                  GpeNumber,
43026f3cdf0SGordon Ross     ACPI_GPE_BLOCK_INFO     *GpeBlock)
43126f3cdf0SGordon Ross {
43226f3cdf0SGordon Ross     UINT32                  GpeIndex;
4337c478bd9Sstevel@tonic-gate 
4347c478bd9Sstevel@tonic-gate 
435db2bae30SDana Myers     /*
43626f3cdf0SGordon Ross      * Validate that the GpeNumber is within the specified GpeBlock.
43726f3cdf0SGordon Ross      * (Two steps)
438db2bae30SDana Myers      */
43926f3cdf0SGordon Ross     if (!GpeBlock ||
44026f3cdf0SGordon Ross         (GpeNumber < GpeBlock->BlockBaseNumber))
44126f3cdf0SGordon Ross     {
44226f3cdf0SGordon Ross         return (NULL);
44326f3cdf0SGordon Ross     }
44426f3cdf0SGordon Ross 
44526f3cdf0SGordon Ross     GpeIndex = GpeNumber - GpeBlock->BlockBaseNumber;
44626f3cdf0SGordon Ross     if (GpeIndex >= GpeBlock->GpeCount)
44726f3cdf0SGordon Ross     {
44826f3cdf0SGordon Ross         return (NULL);
44926f3cdf0SGordon Ross     }
45026f3cdf0SGordon Ross 
45126f3cdf0SGordon Ross     return (&GpeBlock->EventInfo[GpeIndex]);
4527c478bd9Sstevel@tonic-gate }
4537c478bd9Sstevel@tonic-gate 
4547c478bd9Sstevel@tonic-gate 
4557c478bd9Sstevel@tonic-gate /*******************************************************************************
4567c478bd9Sstevel@tonic-gate  *
4577c478bd9Sstevel@tonic-gate  * FUNCTION:    AcpiEvGetGpeEventInfo
4587c478bd9Sstevel@tonic-gate  *
459aa2aa9a6SDana Myers  * PARAMETERS:  GpeDevice           - Device node. NULL for GPE0/GPE1
4607c478bd9Sstevel@tonic-gate  *              GpeNumber           - Raw GPE number
4617c478bd9Sstevel@tonic-gate  *
462aa2aa9a6SDana Myers  * RETURN:      A GPE EventInfo struct. NULL if not a valid GPE
4637c478bd9Sstevel@tonic-gate  *
4647c478bd9Sstevel@tonic-gate  * DESCRIPTION: Returns the EventInfo struct associated with this GPE.
4657c478bd9Sstevel@tonic-gate  *              Validates the GpeBlock and the GpeNumber
4667c478bd9Sstevel@tonic-gate  *
4677c478bd9Sstevel@tonic-gate  *              Should be called only when the GPE lists are semaphore locked
4687c478bd9Sstevel@tonic-gate  *              and not subject to change.
4697c478bd9Sstevel@tonic-gate  *
4707c478bd9Sstevel@tonic-gate  ******************************************************************************/
4717c478bd9Sstevel@tonic-gate 
4727c478bd9Sstevel@tonic-gate ACPI_GPE_EVENT_INFO *
AcpiEvGetGpeEventInfo(ACPI_HANDLE GpeDevice,UINT32 GpeNumber)4737c478bd9Sstevel@tonic-gate AcpiEvGetGpeEventInfo (
4747c478bd9Sstevel@tonic-gate     ACPI_HANDLE             GpeDevice,
4757c478bd9Sstevel@tonic-gate     UINT32                  GpeNumber)
4767c478bd9Sstevel@tonic-gate {
4777c478bd9Sstevel@tonic-gate     ACPI_OPERAND_OBJECT     *ObjDesc;
47826f3cdf0SGordon Ross     ACPI_GPE_EVENT_INFO     *GpeInfo;
479db2bae30SDana Myers     UINT32                  i;
4807c478bd9Sstevel@tonic-gate 
4817c478bd9Sstevel@tonic-gate 
4827c478bd9Sstevel@tonic-gate     ACPI_FUNCTION_ENTRY ();
4837c478bd9Sstevel@tonic-gate 
4847c478bd9Sstevel@tonic-gate 
48526f3cdf0SGordon Ross     /* A NULL GpeDevice means use the FADT-defined GPE block(s) */
4867c478bd9Sstevel@tonic-gate 
4877c478bd9Sstevel@tonic-gate     if (!GpeDevice)
4887c478bd9Sstevel@tonic-gate     {
4897c478bd9Sstevel@tonic-gate         /* Examine GPE Block 0 and 1 (These blocks are permanent) */
4907c478bd9Sstevel@tonic-gate 
4917c478bd9Sstevel@tonic-gate         for (i = 0; i < ACPI_MAX_GPE_BLOCKS; i++)
4927c478bd9Sstevel@tonic-gate         {
49326f3cdf0SGordon Ross             GpeInfo = AcpiEvLowGetGpeInfo (GpeNumber,
4947b1019a6SJerry Jelinek                 AcpiGbl_GpeFadtBlocks[i]);
49526f3cdf0SGordon Ross             if (GpeInfo)
4967c478bd9Sstevel@tonic-gate             {
49726f3cdf0SGordon Ross                 return (GpeInfo);
4987c478bd9Sstevel@tonic-gate             }
4997c478bd9Sstevel@tonic-gate         }
5007c478bd9Sstevel@tonic-gate 
5017c478bd9Sstevel@tonic-gate         /* The GpeNumber was not in the range of either FADT GPE block */
5027c478bd9Sstevel@tonic-gate 
5037c478bd9Sstevel@tonic-gate         return (NULL);
5047c478bd9Sstevel@tonic-gate     }
5057c478bd9Sstevel@tonic-gate 
5067c478bd9Sstevel@tonic-gate     /* A Non-NULL GpeDevice means this is a GPE Block Device */
5077c478bd9Sstevel@tonic-gate 
5087c478bd9Sstevel@tonic-gate     ObjDesc = AcpiNsGetAttachedObject ((ACPI_NAMESPACE_NODE *) GpeDevice);
5097c478bd9Sstevel@tonic-gate     if (!ObjDesc ||
5107c478bd9Sstevel@tonic-gate         !ObjDesc->Device.GpeBlock)
5117c478bd9Sstevel@tonic-gate     {
5127c478bd9Sstevel@tonic-gate         return (NULL);
5137c478bd9Sstevel@tonic-gate     }
5147c478bd9Sstevel@tonic-gate 
51526f3cdf0SGordon Ross     return (AcpiEvLowGetGpeInfo (GpeNumber, ObjDesc->Device.GpeBlock));
5167c478bd9Sstevel@tonic-gate }
5177c478bd9Sstevel@tonic-gate 
5187c478bd9Sstevel@tonic-gate 
5197c478bd9Sstevel@tonic-gate /*******************************************************************************
5207c478bd9Sstevel@tonic-gate  *
5217c478bd9Sstevel@tonic-gate  * FUNCTION:    AcpiEvGpeDetect
5227c478bd9Sstevel@tonic-gate  *
5237c478bd9Sstevel@tonic-gate  * PARAMETERS:  GpeXruptList        - Interrupt block for this interrupt.
5247c478bd9Sstevel@tonic-gate  *                                    Can have multiple GPE blocks attached.
5257c478bd9Sstevel@tonic-gate  *
5267c478bd9Sstevel@tonic-gate  * RETURN:      INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED
5277c478bd9Sstevel@tonic-gate  *
528aa2aa9a6SDana Myers  * DESCRIPTION: Detect if any GP events have occurred. This function is
5297c478bd9Sstevel@tonic-gate  *              executed at interrupt level.
5307c478bd9Sstevel@tonic-gate  *
5317c478bd9Sstevel@tonic-gate  ******************************************************************************/
5327c478bd9Sstevel@tonic-gate 
5337c478bd9Sstevel@tonic-gate UINT32
AcpiEvGpeDetect(ACPI_GPE_XRUPT_INFO * GpeXruptList)5347c478bd9Sstevel@tonic-gate AcpiEvGpeDetect (
5357c478bd9Sstevel@tonic-gate     ACPI_GPE_XRUPT_INFO     *GpeXruptList)
5367c478bd9Sstevel@tonic-gate {
53730082d0cSmyers     ACPI_GPE_BLOCK_INFO     *GpeBlock;
5387b1019a6SJerry Jelinek     ACPI_NAMESPACE_NODE     *GpeDevice;
53930082d0cSmyers     ACPI_GPE_REGISTER_INFO  *GpeRegisterInfo;
5407b1019a6SJerry Jelinek     ACPI_GPE_EVENT_INFO     *GpeEventInfo;
5417b1019a6SJerry Jelinek     UINT32                  GpeNumber;
5427c478bd9Sstevel@tonic-gate     UINT32                  IntStatus = ACPI_INTERRUPT_NOT_HANDLED;
54330082d0cSmyers     ACPI_CPU_FLAGS          Flags;
544db2bae30SDana Myers     UINT32                  i;
545db2bae30SDana Myers     UINT32                  j;
5467c478bd9Sstevel@tonic-gate 
5477c478bd9Sstevel@tonic-gate 
54827f7c583Smyers     ACPI_FUNCTION_NAME (EvGpeDetect);
5497c478bd9Sstevel@tonic-gate 
5507c478bd9Sstevel@tonic-gate     /* Check for the case where there are no GPEs */
5517c478bd9Sstevel@tonic-gate 
5527c478bd9Sstevel@tonic-gate     if (!GpeXruptList)
5537c478bd9Sstevel@tonic-gate     {
5547c478bd9Sstevel@tonic-gate         return (IntStatus);
5557c478bd9Sstevel@tonic-gate     }
5567c478bd9Sstevel@tonic-gate 
55727f7c583Smyers     /*
55827f7c583Smyers      * We need to obtain the GPE lock for both the data structs and registers
559aa2aa9a6SDana Myers      * Note: Not necessary to obtain the hardware lock, since the GPE
560aa2aa9a6SDana Myers      * registers are owned by the GpeLock.
56127f7c583Smyers      */
56227f7c583Smyers     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
56327f7c583Smyers 
5647c478bd9Sstevel@tonic-gate     /* Examine all GPE blocks attached to this interrupt level */
5657c478bd9Sstevel@tonic-gate 
5667c478bd9Sstevel@tonic-gate     GpeBlock = GpeXruptList->GpeBlockListHead;
5677c478bd9Sstevel@tonic-gate     while (GpeBlock)
5687c478bd9Sstevel@tonic-gate     {
5697b1019a6SJerry Jelinek         GpeDevice = GpeBlock->Node;
5707b1019a6SJerry Jelinek 
5717c478bd9Sstevel@tonic-gate         /*
572aa2aa9a6SDana Myers          * Read all of the 8-bit GPE status and enable registers in this GPE
573aa2aa9a6SDana Myers          * block, saving all of them. Find all currently active GP events.
5747c478bd9Sstevel@tonic-gate          */
5757c478bd9Sstevel@tonic-gate         for (i = 0; i < GpeBlock->RegisterCount; i++)
5767c478bd9Sstevel@tonic-gate         {
5777c478bd9Sstevel@tonic-gate             /* Get the next status/enable pair */
5787c478bd9Sstevel@tonic-gate 
5797c478bd9Sstevel@tonic-gate             GpeRegisterInfo = &GpeBlock->RegisterInfo[i];
5807c478bd9Sstevel@tonic-gate 
58126f3cdf0SGordon Ross             /*
58226f3cdf0SGordon Ross              * Optimization: If there are no GPEs enabled within this
58326f3cdf0SGordon Ross              * register, we can safely ignore the entire register.
58426f3cdf0SGordon Ross              */
58526f3cdf0SGordon Ross             if (!(GpeRegisterInfo->EnableForRun |
58626f3cdf0SGordon Ross                   GpeRegisterInfo->EnableForWake))
58726f3cdf0SGordon Ross             {
5887b1019a6SJerry Jelinek                 ACPI_DEBUG_PRINT ((ACPI_DB_INTERRUPTS,
5897b1019a6SJerry Jelinek                     "Ignore disabled registers for GPE %02X-%02X: "
5907b1019a6SJerry Jelinek                     "RunEnable=%02X, WakeEnable=%02X\n",
5917b1019a6SJerry Jelinek                     GpeRegisterInfo->BaseGpeNumber,
5927b1019a6SJerry Jelinek                     GpeRegisterInfo->BaseGpeNumber + (ACPI_GPE_REGISTER_WIDTH - 1),
5937b1019a6SJerry Jelinek                     GpeRegisterInfo->EnableForRun,
5947b1019a6SJerry Jelinek                     GpeRegisterInfo->EnableForWake));
59526f3cdf0SGordon Ross                 continue;
59626f3cdf0SGordon Ross             }
59726f3cdf0SGordon Ross 
5987c478bd9Sstevel@tonic-gate             /* Now look at the individual GPEs in this byte register */
5997c478bd9Sstevel@tonic-gate 
6007c478bd9Sstevel@tonic-gate             for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++)
6017c478bd9Sstevel@tonic-gate             {
602*35786f68SRobert Mustacchi                 /* Detect and dispatch one GPE bit */
6037c478bd9Sstevel@tonic-gate 
6047b1019a6SJerry Jelinek                 GpeEventInfo = &GpeBlock->EventInfo[((ACPI_SIZE) i *
6057b1019a6SJerry Jelinek                     ACPI_GPE_REGISTER_WIDTH) + j];
6067b1019a6SJerry Jelinek                 GpeNumber = j + GpeRegisterInfo->BaseGpeNumber;
607*35786f68SRobert Mustacchi                 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
608*35786f68SRobert Mustacchi                 IntStatus |= AcpiEvDetectGpe (
609*35786f68SRobert Mustacchi                     GpeDevice, GpeEventInfo, GpeNumber);
610*35786f68SRobert Mustacchi                 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
6117c478bd9Sstevel@tonic-gate             }
6127c478bd9Sstevel@tonic-gate         }
6137c478bd9Sstevel@tonic-gate 
6147c478bd9Sstevel@tonic-gate         GpeBlock = GpeBlock->Next;
6157c478bd9Sstevel@tonic-gate     }
6167c478bd9Sstevel@tonic-gate 
617450d6964Smyers     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
6187c478bd9Sstevel@tonic-gate     return (IntStatus);
6197c478bd9Sstevel@tonic-gate }
6207c478bd9Sstevel@tonic-gate 
6217c478bd9Sstevel@tonic-gate 
6227c478bd9Sstevel@tonic-gate /*******************************************************************************
6237c478bd9Sstevel@tonic-gate  *
6247c478bd9Sstevel@tonic-gate  * FUNCTION:    AcpiEvAsynchExecuteGpeMethod
6257c478bd9Sstevel@tonic-gate  *
6267c478bd9Sstevel@tonic-gate  * PARAMETERS:  Context (GpeEventInfo) - Info for this GPE
6277c478bd9Sstevel@tonic-gate  *
6287c478bd9Sstevel@tonic-gate  * RETURN:      None
6297c478bd9Sstevel@tonic-gate  *
63027f7c583Smyers  * DESCRIPTION: Perform the actual execution of a GPE control method. This
63127f7c583Smyers  *              function is called from an invocation of AcpiOsExecute and
63227f7c583Smyers  *              therefore does NOT execute at interrupt level - so that
6337c478bd9Sstevel@tonic-gate  *              the control method itself is not executed in the context of
6347c478bd9Sstevel@tonic-gate  *              an interrupt handler.
6357c478bd9Sstevel@tonic-gate  *
6367c478bd9Sstevel@tonic-gate  ******************************************************************************/
6377c478bd9Sstevel@tonic-gate 
6387c478bd9Sstevel@tonic-gate static void ACPI_SYSTEM_XFACE
AcpiEvAsynchExecuteGpeMethod(void * Context)6397c478bd9Sstevel@tonic-gate AcpiEvAsynchExecuteGpeMethod (
6407c478bd9Sstevel@tonic-gate     void                    *Context)
6417c478bd9Sstevel@tonic-gate {
642db2bae30SDana Myers     ACPI_GPE_EVENT_INFO     *GpeEventInfo = Context;
6437b1019a6SJerry Jelinek     ACPI_STATUS             Status = AE_OK;
64427f7c583Smyers     ACPI_EVALUATE_INFO      *Info;
6457b1019a6SJerry Jelinek     ACPI_GPE_NOTIFY_INFO    *Notify;
6467c478bd9Sstevel@tonic-gate 
6477c478bd9Sstevel@tonic-gate 
64827f7c583Smyers     ACPI_FUNCTION_TRACE (EvAsynchExecuteGpeMethod);
6497c478bd9Sstevel@tonic-gate 
6507c478bd9Sstevel@tonic-gate 
65126f3cdf0SGordon Ross     /* Do the correct dispatch - normal method or implicit notify */
65226f3cdf0SGordon Ross 
6537b1019a6SJerry Jelinek     switch (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags))
6547c478bd9Sstevel@tonic-gate     {
65526f3cdf0SGordon Ross     case ACPI_GPE_DISPATCH_NOTIFY:
65626f3cdf0SGordon Ross         /*
65726f3cdf0SGordon Ross          * Implicit notify.
65826f3cdf0SGordon Ross          * Dispatch a DEVICE_WAKE notify to the appropriate handler.
65926f3cdf0SGordon Ross          * NOTE: the request is queued for execution after this method
66026f3cdf0SGordon Ross          * completes. The notify handlers are NOT invoked synchronously
66126f3cdf0SGordon Ross          * from this thread -- because handlers may in turn run other
66226f3cdf0SGordon Ross          * control methods.
6637b1019a6SJerry Jelinek          *
6647b1019a6SJerry Jelinek          * June 2012: Expand implicit notify mechanism to support
6657b1019a6SJerry Jelinek          * notifies on multiple device objects.
66626f3cdf0SGordon Ross          */
6677b1019a6SJerry Jelinek         Notify = GpeEventInfo->Dispatch.NotifyList;
6687b1019a6SJerry Jelinek         while (ACPI_SUCCESS (Status) && Notify)
6697b1019a6SJerry Jelinek         {
6707b1019a6SJerry Jelinek             Status = AcpiEvQueueNotifyRequest (
6717b1019a6SJerry Jelinek                 Notify->DeviceNode, ACPI_NOTIFY_DEVICE_WAKE);
6727b1019a6SJerry Jelinek 
6737b1019a6SJerry Jelinek             Notify = Notify->Next;
6747b1019a6SJerry Jelinek         }
67526f3cdf0SGordon Ross         break;
67626f3cdf0SGordon Ross 
67726f3cdf0SGordon Ross     case ACPI_GPE_DISPATCH_METHOD:
67826f3cdf0SGordon Ross 
67927f7c583Smyers         /* Allocate the evaluation information block */
68027f7c583Smyers 
68127f7c583Smyers         Info = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO));
68227f7c583Smyers         if (!Info)
68327f7c583Smyers         {
68427f7c583Smyers             Status = AE_NO_MEMORY;
68527f7c583Smyers         }
68627f7c583Smyers         else
68727f7c583Smyers         {
68827f7c583Smyers             /*
68926f3cdf0SGordon Ross              * Invoke the GPE Method (_Lxx, _Exx) i.e., evaluate the
69026f3cdf0SGordon Ross              * _Lxx/_Exx control method that corresponds to this GPE
69127f7c583Smyers              */
6927b1019a6SJerry Jelinek             Info->PrefixNode = GpeEventInfo->Dispatch.MethodNode;
69327f7c583Smyers             Info->Flags = ACPI_IGNORE_RETURN_VALUE;
69427f7c583Smyers 
69527f7c583Smyers             Status = AcpiNsEvaluate (Info);
69627f7c583Smyers             ACPI_FREE (Info);
69727f7c583Smyers         }
6987c478bd9Sstevel@tonic-gate 
6997c478bd9Sstevel@tonic-gate         if (ACPI_FAILURE (Status))
7007c478bd9Sstevel@tonic-gate         {
70130082d0cSmyers             ACPI_EXCEPTION ((AE_INFO, Status,
702db2bae30SDana Myers                 "while evaluating GPE method [%4.4s]",
7037b1019a6SJerry Jelinek                 AcpiUtGetNodeName (GpeEventInfo->Dispatch.MethodNode)));
7047c478bd9Sstevel@tonic-gate         }
70526f3cdf0SGordon Ross         break;
70626f3cdf0SGordon Ross 
70726f3cdf0SGordon Ross     default:
7087b1019a6SJerry Jelinek 
7097b1019a6SJerry Jelinek         goto ErrorExit; /* Should never happen */
7107c478bd9Sstevel@tonic-gate     }
7117c478bd9Sstevel@tonic-gate 
712db2bae30SDana Myers     /* Defer enabling of GPE until all notify handlers are done */
713db2bae30SDana Myers 
714db2bae30SDana Myers     Status = AcpiOsExecute (OSL_NOTIFY_HANDLER,
7157b1019a6SJerry Jelinek         AcpiEvAsynchEnableGpe, GpeEventInfo);
7167b1019a6SJerry Jelinek     if (ACPI_SUCCESS (Status))
717db2bae30SDana Myers     {
7187b1019a6SJerry Jelinek         return_VOID;
719db2bae30SDana Myers     }
7207b1019a6SJerry Jelinek 
7217b1019a6SJerry Jelinek ErrorExit:
7227b1019a6SJerry Jelinek     AcpiEvAsynchEnableGpe (GpeEventInfo);
723db2bae30SDana Myers     return_VOID;
724db2bae30SDana Myers }
725db2bae30SDana Myers 
726db2bae30SDana Myers 
727db2bae30SDana Myers /*******************************************************************************
728db2bae30SDana Myers  *
729db2bae30SDana Myers  * FUNCTION:    AcpiEvAsynchEnableGpe
730db2bae30SDana Myers  *
731db2bae30SDana Myers  * PARAMETERS:  Context (GpeEventInfo) - Info for this GPE
73226f3cdf0SGordon Ross  *              Callback from AcpiOsExecute
733db2bae30SDana Myers  *
734db2bae30SDana Myers  * RETURN:      None
735db2bae30SDana Myers  *
736db2bae30SDana Myers  * DESCRIPTION: Asynchronous clear/enable for GPE. This allows the GPE to
737db2bae30SDana Myers  *              complete (i.e., finish execution of Notify)
738db2bae30SDana Myers  *
739db2bae30SDana Myers  ******************************************************************************/
740db2bae30SDana Myers 
741db2bae30SDana Myers static void ACPI_SYSTEM_XFACE
AcpiEvAsynchEnableGpe(void * Context)742db2bae30SDana Myers AcpiEvAsynchEnableGpe (
743db2bae30SDana Myers     void                    *Context)
744db2bae30SDana Myers {
745db2bae30SDana Myers     ACPI_GPE_EVENT_INFO     *GpeEventInfo = Context;
7467b1019a6SJerry Jelinek     ACPI_CPU_FLAGS          Flags;
74726f3cdf0SGordon Ross 
74826f3cdf0SGordon Ross 
7497b1019a6SJerry Jelinek     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
75026f3cdf0SGordon Ross     (void) AcpiEvFinishGpe (GpeEventInfo);
7517b1019a6SJerry Jelinek     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
75226f3cdf0SGordon Ross 
75326f3cdf0SGordon Ross     return;
75426f3cdf0SGordon Ross }
75526f3cdf0SGordon Ross 
75626f3cdf0SGordon Ross 
75726f3cdf0SGordon Ross /*******************************************************************************
75826f3cdf0SGordon Ross  *
75926f3cdf0SGordon Ross  * FUNCTION:    AcpiEvFinishGpe
76026f3cdf0SGordon Ross  *
76126f3cdf0SGordon Ross  * PARAMETERS:  GpeEventInfo        - Info for this GPE
76226f3cdf0SGordon Ross  *
76326f3cdf0SGordon Ross  * RETURN:      Status
76426f3cdf0SGordon Ross  *
76526f3cdf0SGordon Ross  * DESCRIPTION: Clear/Enable a GPE. Common code that is used after execution
76626f3cdf0SGordon Ross  *              of a GPE method or a synchronous or asynchronous GPE handler.
76726f3cdf0SGordon Ross  *
76826f3cdf0SGordon Ross  ******************************************************************************/
76926f3cdf0SGordon Ross 
77026f3cdf0SGordon Ross ACPI_STATUS
AcpiEvFinishGpe(ACPI_GPE_EVENT_INFO * GpeEventInfo)77126f3cdf0SGordon Ross AcpiEvFinishGpe (
77226f3cdf0SGordon Ross     ACPI_GPE_EVENT_INFO     *GpeEventInfo)
77326f3cdf0SGordon Ross {
774db2bae30SDana Myers     ACPI_STATUS             Status;
775db2bae30SDana Myers 
776db2bae30SDana Myers 
777db2bae30SDana Myers     if ((GpeEventInfo->Flags & ACPI_GPE_XRUPT_TYPE_MASK) ==
7787c478bd9Sstevel@tonic-gate             ACPI_GPE_LEVEL_TRIGGERED)
7797c478bd9Sstevel@tonic-gate     {
7807c478bd9Sstevel@tonic-gate         /*
78126f3cdf0SGordon Ross          * GPE is level-triggered, we clear the GPE status bit after
78226f3cdf0SGordon Ross          * handling the event.
7837c478bd9Sstevel@tonic-gate          */
784db2bae30SDana Myers         Status = AcpiHwClearGpe (GpeEventInfo);
7857c478bd9Sstevel@tonic-gate         if (ACPI_FAILURE (Status))
7867c478bd9Sstevel@tonic-gate         {
78726f3cdf0SGordon Ross             return (Status);
7887c478bd9Sstevel@tonic-gate         }
7897c478bd9Sstevel@tonic-gate     }
7907c478bd9Sstevel@tonic-gate 
79126f3cdf0SGordon Ross     /*
79226f3cdf0SGordon Ross      * Enable this GPE, conditionally. This means that the GPE will
7937b1019a6SJerry Jelinek      * only be physically enabled if the EnableMask bit is set
79426f3cdf0SGordon Ross      * in the EventInfo.
79526f3cdf0SGordon Ross      */
79626f3cdf0SGordon Ross     (void) AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_CONDITIONAL_ENABLE);
797*35786f68SRobert Mustacchi     GpeEventInfo->DisableForDispatch = FALSE;
79826f3cdf0SGordon Ross     return (AE_OK);
7997c478bd9Sstevel@tonic-gate }
8007c478bd9Sstevel@tonic-gate 
8017c478bd9Sstevel@tonic-gate 
802*35786f68SRobert Mustacchi /*******************************************************************************
803*35786f68SRobert Mustacchi  *
804*35786f68SRobert Mustacchi  * FUNCTION:    AcpiEvDetectGpe
805*35786f68SRobert Mustacchi  *
806*35786f68SRobert Mustacchi  * PARAMETERS:  GpeDevice           - Device node. NULL for GPE0/GPE1
807*35786f68SRobert Mustacchi  *              GpeEventInfo        - Info for this GPE
808*35786f68SRobert Mustacchi  *              GpeNumber           - Number relative to the parent GPE block
809*35786f68SRobert Mustacchi  *
810*35786f68SRobert Mustacchi  * RETURN:      INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED
811*35786f68SRobert Mustacchi  *
812*35786f68SRobert Mustacchi  * DESCRIPTION: Detect and dispatch a General Purpose Event to either a function
813*35786f68SRobert Mustacchi  *              (e.g. EC) or method (e.g. _Lxx/_Exx) handler.
814*35786f68SRobert Mustacchi  * NOTE:        GPE is W1C, so it is possible to handle a single GPE from both
815*35786f68SRobert Mustacchi  *              task and irq context in parallel as long as the process to
816*35786f68SRobert Mustacchi  *              detect and mask the GPE is atomic.
817*35786f68SRobert Mustacchi  *              However the atomicity of ACPI_GPE_DISPATCH_RAW_HANDLER is
818*35786f68SRobert Mustacchi  *              dependent on the raw handler itself.
819*35786f68SRobert Mustacchi  *
820*35786f68SRobert Mustacchi  ******************************************************************************/
821*35786f68SRobert Mustacchi 
822*35786f68SRobert Mustacchi UINT32
AcpiEvDetectGpe(ACPI_NAMESPACE_NODE * GpeDevice,ACPI_GPE_EVENT_INFO * GpeEventInfo,UINT32 GpeNumber)823*35786f68SRobert Mustacchi AcpiEvDetectGpe (
824*35786f68SRobert Mustacchi     ACPI_NAMESPACE_NODE     *GpeDevice,
825*35786f68SRobert Mustacchi     ACPI_GPE_EVENT_INFO     *GpeEventInfo,
826*35786f68SRobert Mustacchi     UINT32                  GpeNumber)
827*35786f68SRobert Mustacchi {
828*35786f68SRobert Mustacchi     UINT32                  IntStatus = ACPI_INTERRUPT_NOT_HANDLED;
829*35786f68SRobert Mustacchi     UINT8                   EnabledStatusByte;
830*35786f68SRobert Mustacchi     UINT64                  StatusReg;
831*35786f68SRobert Mustacchi     UINT64                  EnableReg;
832*35786f68SRobert Mustacchi     UINT32                  RegisterBit;
833*35786f68SRobert Mustacchi     ACPI_GPE_REGISTER_INFO  *GpeRegisterInfo;
834*35786f68SRobert Mustacchi     ACPI_GPE_HANDLER_INFO   *GpeHandlerInfo;
835*35786f68SRobert Mustacchi     ACPI_CPU_FLAGS          Flags;
836*35786f68SRobert Mustacchi     ACPI_STATUS             Status;
837*35786f68SRobert Mustacchi 
838*35786f68SRobert Mustacchi 
839*35786f68SRobert Mustacchi     ACPI_FUNCTION_TRACE (EvGpeDetect);
840*35786f68SRobert Mustacchi 
841*35786f68SRobert Mustacchi 
842*35786f68SRobert Mustacchi     Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
843*35786f68SRobert Mustacchi 
844*35786f68SRobert Mustacchi     /* Get the info block for the entire GPE register */
845*35786f68SRobert Mustacchi 
846*35786f68SRobert Mustacchi     GpeRegisterInfo = GpeEventInfo->RegisterInfo;
847*35786f68SRobert Mustacchi 
848*35786f68SRobert Mustacchi     /* Get the register bitmask for this GPE */
849*35786f68SRobert Mustacchi 
850*35786f68SRobert Mustacchi     RegisterBit = AcpiHwGetGpeRegisterBit (GpeEventInfo);
851*35786f68SRobert Mustacchi 
852*35786f68SRobert Mustacchi     /* GPE currently enabled (enable bit == 1)? */
853*35786f68SRobert Mustacchi 
854*35786f68SRobert Mustacchi     Status = AcpiHwRead (&EnableReg, &GpeRegisterInfo->EnableAddress);
855*35786f68SRobert Mustacchi     if (ACPI_FAILURE (Status))
856*35786f68SRobert Mustacchi     {
857*35786f68SRobert Mustacchi         goto ErrorExit;
858*35786f68SRobert Mustacchi     }
859*35786f68SRobert Mustacchi 
860*35786f68SRobert Mustacchi     /* GPE currently active (status bit == 1)? */
861*35786f68SRobert Mustacchi 
862*35786f68SRobert Mustacchi     Status = AcpiHwRead (&StatusReg, &GpeRegisterInfo->StatusAddress);
863*35786f68SRobert Mustacchi     if (ACPI_FAILURE (Status))
864*35786f68SRobert Mustacchi     {
865*35786f68SRobert Mustacchi         goto ErrorExit;
866*35786f68SRobert Mustacchi     }
867*35786f68SRobert Mustacchi 
868*35786f68SRobert Mustacchi     /* Check if there is anything active at all in this GPE */
869*35786f68SRobert Mustacchi 
870*35786f68SRobert Mustacchi     ACPI_DEBUG_PRINT ((ACPI_DB_INTERRUPTS,
871*35786f68SRobert Mustacchi         "Read registers for GPE %02X: Status=%02X, Enable=%02X, "
872*35786f68SRobert Mustacchi         "RunEnable=%02X, WakeEnable=%02X\n",
873*35786f68SRobert Mustacchi         GpeNumber,
874*35786f68SRobert Mustacchi         (UINT32) (StatusReg & RegisterBit),
875*35786f68SRobert Mustacchi         (UINT32) (EnableReg & RegisterBit),
876*35786f68SRobert Mustacchi         GpeRegisterInfo->EnableForRun,
877*35786f68SRobert Mustacchi         GpeRegisterInfo->EnableForWake));
878*35786f68SRobert Mustacchi 
879*35786f68SRobert Mustacchi     EnabledStatusByte = (UINT8) (StatusReg & EnableReg);
880*35786f68SRobert Mustacchi     if (!(EnabledStatusByte & RegisterBit))
881*35786f68SRobert Mustacchi     {
882*35786f68SRobert Mustacchi         goto ErrorExit;
883*35786f68SRobert Mustacchi     }
884*35786f68SRobert Mustacchi 
885*35786f68SRobert Mustacchi     /* Invoke global event handler if present */
886*35786f68SRobert Mustacchi 
887*35786f68SRobert Mustacchi     AcpiGpeCount++;
888*35786f68SRobert Mustacchi     if (AcpiGbl_GlobalEventHandler)
889*35786f68SRobert Mustacchi     {
890*35786f68SRobert Mustacchi         AcpiGbl_GlobalEventHandler (ACPI_EVENT_TYPE_GPE,
891*35786f68SRobert Mustacchi             GpeDevice, GpeNumber,
892*35786f68SRobert Mustacchi             AcpiGbl_GlobalEventHandlerContext);
893*35786f68SRobert Mustacchi     }
894*35786f68SRobert Mustacchi 
895*35786f68SRobert Mustacchi     /* Found an active GPE */
896*35786f68SRobert Mustacchi 
897*35786f68SRobert Mustacchi     if (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) ==
898*35786f68SRobert Mustacchi         ACPI_GPE_DISPATCH_RAW_HANDLER)
899*35786f68SRobert Mustacchi     {
900*35786f68SRobert Mustacchi         /* Dispatch the event to a raw handler */
901*35786f68SRobert Mustacchi 
902*35786f68SRobert Mustacchi         GpeHandlerInfo = GpeEventInfo->Dispatch.Handler;
903*35786f68SRobert Mustacchi 
904*35786f68SRobert Mustacchi         /*
905*35786f68SRobert Mustacchi          * There is no protection around the namespace node
906*35786f68SRobert Mustacchi          * and the GPE handler to ensure a safe destruction
907*35786f68SRobert Mustacchi          * because:
908*35786f68SRobert Mustacchi          * 1. The namespace node is expected to always
909*35786f68SRobert Mustacchi          *    exist after loading a table.
910*35786f68SRobert Mustacchi          * 2. The GPE handler is expected to be flushed by
911*35786f68SRobert Mustacchi          *    AcpiOsWaitEventsComplete() before the
912*35786f68SRobert Mustacchi          *    destruction.
913*35786f68SRobert Mustacchi          */
914*35786f68SRobert Mustacchi         AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
915*35786f68SRobert Mustacchi         IntStatus |= GpeHandlerInfo->Address (
916*35786f68SRobert Mustacchi             GpeDevice, GpeNumber, GpeHandlerInfo->Context);
917*35786f68SRobert Mustacchi         Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock);
918*35786f68SRobert Mustacchi     }
919*35786f68SRobert Mustacchi     else
920*35786f68SRobert Mustacchi     {
921*35786f68SRobert Mustacchi         /* Dispatch the event to a standard handler or method. */
922*35786f68SRobert Mustacchi 
923*35786f68SRobert Mustacchi         IntStatus |= AcpiEvGpeDispatch (GpeDevice,
924*35786f68SRobert Mustacchi             GpeEventInfo, GpeNumber);
925*35786f68SRobert Mustacchi     }
926*35786f68SRobert Mustacchi 
927*35786f68SRobert Mustacchi ErrorExit:
928*35786f68SRobert Mustacchi     AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags);
929*35786f68SRobert Mustacchi     return (IntStatus);
930*35786f68SRobert Mustacchi }
931*35786f68SRobert Mustacchi 
932*35786f68SRobert Mustacchi 
9337c478bd9Sstevel@tonic-gate /*******************************************************************************
9347c478bd9Sstevel@tonic-gate  *
9357c478bd9Sstevel@tonic-gate  * FUNCTION:    AcpiEvGpeDispatch
9367c478bd9Sstevel@tonic-gate  *
93726f3cdf0SGordon Ross  * PARAMETERS:  GpeDevice           - Device node. NULL for GPE0/GPE1
93826f3cdf0SGordon Ross  *              GpeEventInfo        - Info for this GPE
93926f3cdf0SGordon Ross  *              GpeNumber           - Number relative to the parent GPE block
9407c478bd9Sstevel@tonic-gate  *
9417c478bd9Sstevel@tonic-gate  * RETURN:      INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED
9427c478bd9Sstevel@tonic-gate  *
9437c478bd9Sstevel@tonic-gate  * DESCRIPTION: Dispatch a General Purpose Event to either a function (e.g. EC)
9447c478bd9Sstevel@tonic-gate  *              or method (e.g. _Lxx/_Exx) handler.
9457c478bd9Sstevel@tonic-gate  *
9467c478bd9Sstevel@tonic-gate  ******************************************************************************/
9477c478bd9Sstevel@tonic-gate 
9487c478bd9Sstevel@tonic-gate UINT32
AcpiEvGpeDispatch(ACPI_NAMESPACE_NODE * GpeDevice,ACPI_GPE_EVENT_INFO * GpeEventInfo,UINT32 GpeNumber)9497c478bd9Sstevel@tonic-gate AcpiEvGpeDispatch (
95026f3cdf0SGordon Ross     ACPI_NAMESPACE_NODE     *GpeDevice,
9517c478bd9Sstevel@tonic-gate     ACPI_GPE_EVENT_INFO     *GpeEventInfo,
9527c478bd9Sstevel@tonic-gate     UINT32                  GpeNumber)
9537c478bd9Sstevel@tonic-gate {
9547c478bd9Sstevel@tonic-gate     ACPI_STATUS             Status;
95526f3cdf0SGordon Ross     UINT32                  ReturnValue;
9567c478bd9Sstevel@tonic-gate 
9577c478bd9Sstevel@tonic-gate 
95827f7c583Smyers     ACPI_FUNCTION_TRACE (EvGpeDispatch);
9597c478bd9Sstevel@tonic-gate 
9607c478bd9Sstevel@tonic-gate 
9617b1019a6SJerry Jelinek     /*
9627b1019a6SJerry Jelinek      * Always disable the GPE so that it does not keep firing before
9637b1019a6SJerry Jelinek      * any asynchronous activity completes (either from the execution
9647b1019a6SJerry Jelinek      * of a GPE method or an asynchronous GPE handler.)
9657b1019a6SJerry Jelinek      *
9667b1019a6SJerry Jelinek      * If there is no handler or method to run, just disable the
9677b1019a6SJerry Jelinek      * GPE and leave it disabled permanently to prevent further such
9687b1019a6SJerry Jelinek      * pointless events from firing.
9697b1019a6SJerry Jelinek      */
9707b1019a6SJerry Jelinek     Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_DISABLE);
9717b1019a6SJerry Jelinek     if (ACPI_FAILURE (Status))
97226f3cdf0SGordon Ross     {
9737b1019a6SJerry Jelinek         ACPI_EXCEPTION ((AE_INFO, Status,
9747b1019a6SJerry Jelinek             "Unable to disable GPE %02X", GpeNumber));
9757b1019a6SJerry Jelinek         return_UINT32 (ACPI_INTERRUPT_NOT_HANDLED);
97626f3cdf0SGordon Ross     }
977db2bae30SDana Myers 
9787c478bd9Sstevel@tonic-gate     /*
979aa2aa9a6SDana Myers      * If edge-triggered, clear the GPE status bit now. Note that
9807c478bd9Sstevel@tonic-gate      * level-triggered events are cleared after the GPE is serviced.
9817c478bd9Sstevel@tonic-gate      */
9827c478bd9Sstevel@tonic-gate     if ((GpeEventInfo->Flags & ACPI_GPE_XRUPT_TYPE_MASK) ==
9837c478bd9Sstevel@tonic-gate             ACPI_GPE_EDGE_TRIGGERED)
9847c478bd9Sstevel@tonic-gate     {
9857c478bd9Sstevel@tonic-gate         Status = AcpiHwClearGpe (GpeEventInfo);
9867c478bd9Sstevel@tonic-gate         if (ACPI_FAILURE (Status))
9877c478bd9Sstevel@tonic-gate         {
98830082d0cSmyers             ACPI_EXCEPTION ((AE_INFO, Status,
9897b1019a6SJerry Jelinek                 "Unable to clear GPE %02X", GpeNumber));
9907b1019a6SJerry Jelinek             (void) AcpiHwLowSetGpe (
9917b1019a6SJerry Jelinek                 GpeEventInfo, ACPI_GPE_CONDITIONAL_ENABLE);
992186507a7Smyers             return_UINT32 (ACPI_INTERRUPT_NOT_HANDLED);
9937c478bd9Sstevel@tonic-gate         }
9947c478bd9Sstevel@tonic-gate     }
9957c478bd9Sstevel@tonic-gate 
996*35786f68SRobert Mustacchi     GpeEventInfo->DisableForDispatch = TRUE;
997*35786f68SRobert Mustacchi 
99826f3cdf0SGordon Ross     /*
99926f3cdf0SGordon Ross      * Dispatch the GPE to either an installed handler or the control
100026f3cdf0SGordon Ross      * method associated with this GPE (_Lxx or _Exx). If a handler
100126f3cdf0SGordon Ross      * exists, we invoke it and do not attempt to run the method.
100226f3cdf0SGordon Ross      * If there is neither a handler nor a method, leave the GPE
100326f3cdf0SGordon Ross      * disabled.
10047c478bd9Sstevel@tonic-gate      */
10057b1019a6SJerry Jelinek     switch (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags))
10067c478bd9Sstevel@tonic-gate     {
10077c478bd9Sstevel@tonic-gate     case ACPI_GPE_DISPATCH_HANDLER:
10087c478bd9Sstevel@tonic-gate 
100926f3cdf0SGordon Ross         /* Invoke the installed handler (at interrupt level) */
101026f3cdf0SGordon Ross 
101126f3cdf0SGordon Ross         ReturnValue = GpeEventInfo->Dispatch.Handler->Address (
101226f3cdf0SGordon Ross             GpeDevice, GpeNumber,
101326f3cdf0SGordon Ross             GpeEventInfo->Dispatch.Handler->Context);
10147c478bd9Sstevel@tonic-gate 
101526f3cdf0SGordon Ross         /* If requested, clear (if level-triggered) and reenable the GPE */
10167c478bd9Sstevel@tonic-gate 
101726f3cdf0SGordon Ross         if (ReturnValue & ACPI_REENABLE_GPE)
10187c478bd9Sstevel@tonic-gate         {
101926f3cdf0SGordon Ross             (void) AcpiEvFinishGpe (GpeEventInfo);
10207c478bd9Sstevel@tonic-gate         }
10217c478bd9Sstevel@tonic-gate         break;
10227c478bd9Sstevel@tonic-gate 
10237c478bd9Sstevel@tonic-gate     case ACPI_GPE_DISPATCH_METHOD:
102426f3cdf0SGordon Ross     case ACPI_GPE_DISPATCH_NOTIFY:
10257c478bd9Sstevel@tonic-gate         /*
10267c478bd9Sstevel@tonic-gate          * Execute the method associated with the GPE
10277c478bd9Sstevel@tonic-gate          * NOTE: Level-triggered GPEs are cleared after the method completes.
10287c478bd9Sstevel@tonic-gate          */
102927f7c583Smyers         Status = AcpiOsExecute (OSL_GPE_HANDLER,
10307b1019a6SJerry Jelinek             AcpiEvAsynchExecuteGpeMethod, GpeEventInfo);
10317c478bd9Sstevel@tonic-gate         if (ACPI_FAILURE (Status))
10327c478bd9Sstevel@tonic-gate         {
103330082d0cSmyers             ACPI_EXCEPTION ((AE_INFO, Status,
10347b1019a6SJerry Jelinek                 "Unable to queue handler for GPE %02X - event disabled",
103530082d0cSmyers                 GpeNumber));
10367c478bd9Sstevel@tonic-gate         }
10377c478bd9Sstevel@tonic-gate         break;
10387c478bd9Sstevel@tonic-gate 
10397c478bd9Sstevel@tonic-gate     default:
10407c478bd9Sstevel@tonic-gate         /*
104126f3cdf0SGordon Ross          * No handler or method to run!
104226f3cdf0SGordon Ross          * 03/2010: This case should no longer be possible. We will not allow
104326f3cdf0SGordon Ross          * a GPE to be enabled if it has no handler or method.
10447c478bd9Sstevel@tonic-gate          */
104526f3cdf0SGordon Ross         ACPI_ERROR ((AE_INFO,
10467b1019a6SJerry Jelinek             "No handler or method for GPE %02X, disabling event",
104726f3cdf0SGordon Ross             GpeNumber));
10487c478bd9Sstevel@tonic-gate         break;
10497c478bd9Sstevel@tonic-gate     }
10507c478bd9Sstevel@tonic-gate 
1051186507a7Smyers     return_UINT32 (ACPI_INTERRUPT_HANDLED);
10527c478bd9Sstevel@tonic-gate }
10537c478bd9Sstevel@tonic-gate 
10547b1019a6SJerry Jelinek #endif /* !ACPI_REDUCED_HARDWARE */
1055