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