1114239Snjl/****************************************************************************** 2114239Snjl * 3114239Snjl * Module Name: evgpe - General Purpose Event handling and dispatch 4114239Snjl * 5114239Snjl *****************************************************************************/ 6114239Snjl 7316303Sjkim/****************************************************************************** 8316303Sjkim * 9316303Sjkim * 1. Copyright Notice 10316303Sjkim * 11316303Sjkim * Some or all of this work - Copyright (c) 1999 - 2017, Intel Corp. 12114239Snjl * All rights reserved. 13114239Snjl * 14316303Sjkim * 2. License 15316303Sjkim * 16316303Sjkim * 2.1. This is your license from Intel Corp. under its intellectual property 17316303Sjkim * rights. You may have additional license terms from the party that provided 18316303Sjkim * you this software, covering your right to use that party's intellectual 19316303Sjkim * property rights. 20316303Sjkim * 21316303Sjkim * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 22316303Sjkim * copy of the source code appearing in this file ("Covered Code") an 23316303Sjkim * irrevocable, perpetual, worldwide license under Intel's copyrights in the 24316303Sjkim * base code distributed originally by Intel ("Original Intel Code") to copy, 25316303Sjkim * make derivatives, distribute, use and display any portion of the Covered 26316303Sjkim * Code in any form, with the right to sublicense such rights; and 27316303Sjkim * 28316303Sjkim * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 29316303Sjkim * license (with the right to sublicense), under only those claims of Intel 30316303Sjkim * patents that are infringed by the Original Intel Code, to make, use, sell, 31316303Sjkim * offer to sell, and import the Covered Code and derivative works thereof 32316303Sjkim * solely to the minimum extent necessary to exercise the above copyright 33316303Sjkim * license, and in no event shall the patent license extend to any additions 34316303Sjkim * to or modifications of the Original Intel Code. No other license or right 35316303Sjkim * is granted directly or by implication, estoppel or otherwise; 36316303Sjkim * 37316303Sjkim * The above copyright and patent license is granted only if the following 38316303Sjkim * conditions are met: 39316303Sjkim * 40316303Sjkim * 3. Conditions 41316303Sjkim * 42316303Sjkim * 3.1. Redistribution of Source with Rights to Further Distribute Source. 43316303Sjkim * Redistribution of source code of any substantial portion of the Covered 44316303Sjkim * Code or modification with rights to further distribute source must include 45316303Sjkim * the above Copyright Notice, the above License, this list of Conditions, 46316303Sjkim * and the following Disclaimer and Export Compliance provision. In addition, 47316303Sjkim * Licensee must cause all Covered Code to which Licensee contributes to 48316303Sjkim * contain a file documenting the changes Licensee made to create that Covered 49316303Sjkim * Code and the date of any change. Licensee must include in that file the 50316303Sjkim * documentation of any changes made by any predecessor Licensee. Licensee 51316303Sjkim * must include a prominent statement that the modification is derived, 52316303Sjkim * directly or indirectly, from Original Intel Code. 53316303Sjkim * 54316303Sjkim * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 55316303Sjkim * Redistribution of source code of any substantial portion of the Covered 56316303Sjkim * Code or modification without rights to further distribute source must 57316303Sjkim * include the following Disclaimer and Export Compliance provision in the 58316303Sjkim * documentation and/or other materials provided with distribution. In 59316303Sjkim * addition, Licensee may not authorize further sublicense of source of any 60316303Sjkim * portion of the Covered Code, and must include terms to the effect that the 61316303Sjkim * license from Licensee to its licensee is limited to the intellectual 62316303Sjkim * property embodied in the software Licensee provides to its licensee, and 63316303Sjkim * not to intellectual property embodied in modifications its licensee may 64316303Sjkim * make. 65316303Sjkim * 66316303Sjkim * 3.3. Redistribution of Executable. Redistribution in executable form of any 67316303Sjkim * substantial portion of the Covered Code or modification must reproduce the 68316303Sjkim * above Copyright Notice, and the following Disclaimer and Export Compliance 69316303Sjkim * provision in the documentation and/or other materials provided with the 70316303Sjkim * distribution. 71316303Sjkim * 72316303Sjkim * 3.4. Intel retains all right, title, and interest in and to the Original 73316303Sjkim * Intel Code. 74316303Sjkim * 75316303Sjkim * 3.5. Neither the name Intel nor any other trademark owned or controlled by 76316303Sjkim * Intel shall be used in advertising or otherwise to promote the sale, use or 77316303Sjkim * other dealings in products derived from or relating to the Covered Code 78316303Sjkim * without prior written authorization from Intel. 79316303Sjkim * 80316303Sjkim * 4. Disclaimer and Export Compliance 81316303Sjkim * 82316303Sjkim * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 83316303Sjkim * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 84316303Sjkim * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 85316303Sjkim * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 86316303Sjkim * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 87316303Sjkim * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 88316303Sjkim * PARTICULAR PURPOSE. 89316303Sjkim * 90316303Sjkim * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 91316303Sjkim * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 92316303Sjkim * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 93316303Sjkim * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 94316303Sjkim * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 95316303Sjkim * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 96316303Sjkim * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 97316303Sjkim * LIMITED REMEDY. 98316303Sjkim * 99316303Sjkim * 4.3. Licensee shall not export, either directly or indirectly, any of this 100316303Sjkim * software or system incorporating such software without first obtaining any 101316303Sjkim * required license or other approval from the U. S. Department of Commerce or 102316303Sjkim * any other agency or department of the United States Government. In the 103316303Sjkim * event Licensee exports any such software from the United States or 104316303Sjkim * re-exports any such software from a foreign destination, Licensee shall 105316303Sjkim * ensure that the distribution and export/re-export of the software is in 106316303Sjkim * compliance with all laws, regulations, orders, or other restrictions of the 107316303Sjkim * U.S. Export Administration Regulations. Licensee agrees that neither it nor 108316303Sjkim * any of its subsidiaries will export/re-export any technical data, process, 109316303Sjkim * software, or service, directly or indirectly, to any country for which the 110316303Sjkim * United States government or any agency thereof requires an export license, 111316303Sjkim * other governmental approval, or letter of assurance, without first obtaining 112316303Sjkim * such license, approval or letter. 113316303Sjkim * 114316303Sjkim ***************************************************************************** 115316303Sjkim * 116316303Sjkim * Alternatively, you may choose to be licensed under the terms of the 117316303Sjkim * following license: 118316303Sjkim * 119217365Sjkim * Redistribution and use in source and binary forms, with or without 120217365Sjkim * modification, are permitted provided that the following conditions 121217365Sjkim * are met: 122217365Sjkim * 1. Redistributions of source code must retain the above copyright 123217365Sjkim * notice, this list of conditions, and the following disclaimer, 124217365Sjkim * without modification. 125217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 126217365Sjkim * substantially similar to the "NO WARRANTY" disclaimer below 127217365Sjkim * ("Disclaimer") and any redistribution must be conditioned upon 128217365Sjkim * including a substantially similar Disclaimer requirement for further 129217365Sjkim * binary redistribution. 130217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names 131217365Sjkim * of any contributors may be used to endorse or promote products derived 132217365Sjkim * from this software without specific prior written permission. 133114239Snjl * 134316303Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 135316303Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 136316303Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 137316303Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 138316303Sjkim * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 139316303Sjkim * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 140316303Sjkim * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 141316303Sjkim * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 142316303Sjkim * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 143316303Sjkim * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 144316303Sjkim * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 145316303Sjkim * 146316303Sjkim * Alternatively, you may choose to be licensed under the terms of the 147217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free 148217365Sjkim * Software Foundation. 149114239Snjl * 150316303Sjkim *****************************************************************************/ 151114239Snjl 152193341Sjkim#include <contrib/dev/acpica/include/acpi.h> 153193341Sjkim#include <contrib/dev/acpica/include/accommon.h> 154193341Sjkim#include <contrib/dev/acpica/include/acevents.h> 155193341Sjkim#include <contrib/dev/acpica/include/acnamesp.h> 156114239Snjl 157114239Snjl#define _COMPONENT ACPI_EVENTS 158114239Snjl ACPI_MODULE_NAME ("evgpe") 159114239Snjl 160231844Sjkim#if (!ACPI_REDUCED_HARDWARE) /* Entire module */ 161231844Sjkim 162151937Sjkim/* Local prototypes */ 163114239Snjl 164193267Sjkimstatic void ACPI_SYSTEM_XFACE 165193267SjkimAcpiEvAsynchExecuteGpeMethod ( 166175256Snjl void *Context); 167175256Snjl 168151937Sjkimstatic void ACPI_SYSTEM_XFACE 169193267SjkimAcpiEvAsynchEnableGpe ( 170151937Sjkim void *Context); 171151937Sjkim 172151937Sjkim 173114239Snjl/******************************************************************************* 174114239Snjl * 175209746Sjkim * FUNCTION: AcpiEvUpdateGpeEnableMask 176129684Snjl * 177129684Snjl * PARAMETERS: GpeEventInfo - GPE to update 178129684Snjl * 179129684Snjl * RETURN: Status 180129684Snjl * 181209746Sjkim * DESCRIPTION: Updates GPE register enable mask based upon whether there are 182209746Sjkim * runtime references to this GPE 183129684Snjl * 184129684Snjl ******************************************************************************/ 185129684Snjl 186129684SnjlACPI_STATUS 187209746SjkimAcpiEvUpdateGpeEnableMask ( 188206117Sjkim ACPI_GPE_EVENT_INFO *GpeEventInfo) 189129684Snjl{ 190129684Snjl ACPI_GPE_REGISTER_INFO *GpeRegisterInfo; 191209746Sjkim UINT32 RegisterBit; 192129684Snjl 193129684Snjl 194209746Sjkim ACPI_FUNCTION_TRACE (EvUpdateGpeEnableMask); 195129684Snjl 196129684Snjl 197129684Snjl GpeRegisterInfo = GpeEventInfo->RegisterInfo; 198129684Snjl if (!GpeRegisterInfo) 199129684Snjl { 200129684Snjl return_ACPI_STATUS (AE_NOT_EXIST); 201129684Snjl } 202193267Sjkim 203239340Sjkim RegisterBit = AcpiHwGetGpeRegisterBit (GpeEventInfo); 204129684Snjl 205209746Sjkim /* Clear the run bit up front */ 206129684Snjl 207206117Sjkim ACPI_CLEAR_BIT (GpeRegisterInfo->EnableForRun, RegisterBit); 208206117Sjkim 209209746Sjkim /* Set the mask bit only if there are references to this GPE */ 210206117Sjkim 211206117Sjkim if (GpeEventInfo->RuntimeCount) 212129684Snjl { 213209746Sjkim ACPI_SET_BIT (GpeRegisterInfo->EnableForRun, (UINT8) RegisterBit); 214129684Snjl } 215298714Sjkim 216284583Sjkim GpeRegisterInfo->EnableMask = GpeRegisterInfo->EnableForRun; 217129684Snjl return_ACPI_STATUS (AE_OK); 218129684Snjl} 219129684Snjl 220129684Snjl 221129684Snjl/******************************************************************************* 222129684Snjl * 223129684Snjl * FUNCTION: AcpiEvEnableGpe 224129684Snjl * 225129684Snjl * PARAMETERS: GpeEventInfo - GPE to enable 226129684Snjl * 227129684Snjl * RETURN: Status 228129684Snjl * 229209746Sjkim * DESCRIPTION: Clear a GPE of stale events and enable it. 230129684Snjl * 231129684Snjl ******************************************************************************/ 232129684Snjl 233129684SnjlACPI_STATUS 234129684SnjlAcpiEvEnableGpe ( 235206117Sjkim ACPI_GPE_EVENT_INFO *GpeEventInfo) 236129684Snjl{ 237129684Snjl ACPI_STATUS Status; 238129684Snjl 239129684Snjl 240167802Sjkim ACPI_FUNCTION_TRACE (EvEnableGpe); 241129684Snjl 242129684Snjl 243206117Sjkim /* Clear the GPE (of stale events) */ 244129684Snjl 245206117Sjkim Status = AcpiHwClearGpe (GpeEventInfo); 246206117Sjkim if (ACPI_FAILURE (Status)) 247129684Snjl { 248206117Sjkim return_ACPI_STATUS (Status); 249206117Sjkim } 250131440Smarks 251206117Sjkim /* Enable the requested GPE */ 252129684Snjl 253284583Sjkim Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_ENABLE); 254206117Sjkim return_ACPI_STATUS (Status); 255129684Snjl} 256129684Snjl 257129684Snjl 258129684Snjl/******************************************************************************* 259129684Snjl * 260316303Sjkim * FUNCTION: AcpiEvMaskGpe 261316303Sjkim * 262316303Sjkim * PARAMETERS: GpeEventInfo - GPE to be blocked/unblocked 263316303Sjkim * IsMasked - Whether the GPE is masked or not 264316303Sjkim * 265316303Sjkim * RETURN: Status 266316303Sjkim * 267316303Sjkim * DESCRIPTION: Unconditionally mask/unmask a GPE during runtime. 268316303Sjkim * 269316303Sjkim ******************************************************************************/ 270316303Sjkim 271316303SjkimACPI_STATUS 272316303SjkimAcpiEvMaskGpe ( 273316303Sjkim ACPI_GPE_EVENT_INFO *GpeEventInfo, 274316303Sjkim BOOLEAN IsMasked) 275316303Sjkim{ 276316303Sjkim ACPI_GPE_REGISTER_INFO *GpeRegisterInfo; 277316303Sjkim UINT32 RegisterBit; 278316303Sjkim 279316303Sjkim 280316303Sjkim ACPI_FUNCTION_TRACE (EvMaskGpe); 281316303Sjkim 282316303Sjkim 283316303Sjkim GpeRegisterInfo = GpeEventInfo->RegisterInfo; 284316303Sjkim if (!GpeRegisterInfo) 285316303Sjkim { 286316303Sjkim return_ACPI_STATUS (AE_NOT_EXIST); 287316303Sjkim } 288316303Sjkim 289316303Sjkim RegisterBit = AcpiHwGetGpeRegisterBit (GpeEventInfo); 290316303Sjkim 291316303Sjkim /* Perform the action */ 292316303Sjkim 293316303Sjkim if (IsMasked) 294316303Sjkim { 295316303Sjkim if (RegisterBit & GpeRegisterInfo->MaskForRun) 296316303Sjkim { 297316303Sjkim return_ACPI_STATUS (AE_BAD_PARAMETER); 298316303Sjkim } 299316303Sjkim 300316303Sjkim (void) AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_DISABLE); 301316303Sjkim ACPI_SET_BIT (GpeRegisterInfo->MaskForRun, (UINT8) RegisterBit); 302316303Sjkim } 303316303Sjkim else 304316303Sjkim { 305316303Sjkim if (!(RegisterBit & GpeRegisterInfo->MaskForRun)) 306316303Sjkim { 307316303Sjkim return_ACPI_STATUS (AE_BAD_PARAMETER); 308316303Sjkim } 309316303Sjkim 310316303Sjkim ACPI_CLEAR_BIT (GpeRegisterInfo->MaskForRun, (UINT8) RegisterBit); 311316303Sjkim if (GpeEventInfo->RuntimeCount && 312316303Sjkim !GpeEventInfo->DisableForDispatch) 313316303Sjkim { 314316303Sjkim (void) AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_ENABLE); 315316303Sjkim } 316316303Sjkim } 317316303Sjkim 318316303Sjkim return_ACPI_STATUS (AE_OK); 319316303Sjkim} 320316303Sjkim 321316303Sjkim 322316303Sjkim/******************************************************************************* 323316303Sjkim * 324216471Sjkim * FUNCTION: AcpiEvAddGpeReference 325216471Sjkim * 326216471Sjkim * PARAMETERS: GpeEventInfo - Add a reference to this GPE 327216471Sjkim * 328216471Sjkim * RETURN: Status 329216471Sjkim * 330216471Sjkim * DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is 331216471Sjkim * hardware-enabled. 332216471Sjkim * 333216471Sjkim ******************************************************************************/ 334216471Sjkim 335216471SjkimACPI_STATUS 336216471SjkimAcpiEvAddGpeReference ( 337216471Sjkim ACPI_GPE_EVENT_INFO *GpeEventInfo) 338216471Sjkim{ 339216471Sjkim ACPI_STATUS Status = AE_OK; 340216471Sjkim 341216471Sjkim 342216471Sjkim ACPI_FUNCTION_TRACE (EvAddGpeReference); 343216471Sjkim 344216471Sjkim 345216471Sjkim if (GpeEventInfo->RuntimeCount == ACPI_UINT8_MAX) 346216471Sjkim { 347216471Sjkim return_ACPI_STATUS (AE_LIMIT); 348216471Sjkim } 349216471Sjkim 350216471Sjkim GpeEventInfo->RuntimeCount++; 351216471Sjkim if (GpeEventInfo->RuntimeCount == 1) 352216471Sjkim { 353216471Sjkim /* Enable on first reference */ 354216471Sjkim 355216471Sjkim Status = AcpiEvUpdateGpeEnableMask (GpeEventInfo); 356216471Sjkim if (ACPI_SUCCESS (Status)) 357216471Sjkim { 358216471Sjkim Status = AcpiEvEnableGpe (GpeEventInfo); 359216471Sjkim } 360216471Sjkim 361216471Sjkim if (ACPI_FAILURE (Status)) 362216471Sjkim { 363216471Sjkim GpeEventInfo->RuntimeCount--; 364216471Sjkim } 365216471Sjkim } 366216471Sjkim 367216471Sjkim return_ACPI_STATUS (Status); 368216471Sjkim} 369216471Sjkim 370216471Sjkim 371216471Sjkim/******************************************************************************* 372216471Sjkim * 373216471Sjkim * FUNCTION: AcpiEvRemoveGpeReference 374216471Sjkim * 375216471Sjkim * PARAMETERS: GpeEventInfo - Remove a reference to this GPE 376216471Sjkim * 377216471Sjkim * RETURN: Status 378216471Sjkim * 379216471Sjkim * DESCRIPTION: Remove a reference to a GPE. When the last reference is 380216471Sjkim * removed, the GPE is hardware-disabled. 381216471Sjkim * 382216471Sjkim ******************************************************************************/ 383216471Sjkim 384216471SjkimACPI_STATUS 385216471SjkimAcpiEvRemoveGpeReference ( 386216471Sjkim ACPI_GPE_EVENT_INFO *GpeEventInfo) 387216471Sjkim{ 388216471Sjkim ACPI_STATUS Status = AE_OK; 389216471Sjkim 390216471Sjkim 391216471Sjkim ACPI_FUNCTION_TRACE (EvRemoveGpeReference); 392216471Sjkim 393216471Sjkim 394216471Sjkim if (!GpeEventInfo->RuntimeCount) 395216471Sjkim { 396216471Sjkim return_ACPI_STATUS (AE_LIMIT); 397216471Sjkim } 398216471Sjkim 399216471Sjkim GpeEventInfo->RuntimeCount--; 400216471Sjkim if (!GpeEventInfo->RuntimeCount) 401216471Sjkim { 402216471Sjkim /* Disable on last reference */ 403216471Sjkim 404216471Sjkim Status = AcpiEvUpdateGpeEnableMask (GpeEventInfo); 405216471Sjkim if (ACPI_SUCCESS (Status)) 406216471Sjkim { 407284583Sjkim Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_DISABLE); 408216471Sjkim } 409216471Sjkim 410216471Sjkim if (ACPI_FAILURE (Status)) 411216471Sjkim { 412216471Sjkim GpeEventInfo->RuntimeCount++; 413216471Sjkim } 414216471Sjkim } 415216471Sjkim 416216471Sjkim return_ACPI_STATUS (Status); 417216471Sjkim} 418216471Sjkim 419216471Sjkim 420216471Sjkim/******************************************************************************* 421216471Sjkim * 422206117Sjkim * FUNCTION: AcpiEvLowGetGpeInfo 423206117Sjkim * 424206117Sjkim * PARAMETERS: GpeNumber - Raw GPE number 425206117Sjkim * GpeBlock - A GPE info block 426206117Sjkim * 427206117Sjkim * RETURN: A GPE EventInfo struct. NULL if not a valid GPE (The GpeNumber 428206117Sjkim * is not within the specified GPE block) 429206117Sjkim * 430206117Sjkim * DESCRIPTION: Returns the EventInfo struct associated with this GPE. This is 431206117Sjkim * the low-level implementation of EvGetGpeEventInfo. 432206117Sjkim * 433206117Sjkim ******************************************************************************/ 434206117Sjkim 435206117SjkimACPI_GPE_EVENT_INFO * 436206117SjkimAcpiEvLowGetGpeInfo ( 437206117Sjkim UINT32 GpeNumber, 438206117Sjkim ACPI_GPE_BLOCK_INFO *GpeBlock) 439206117Sjkim{ 440206117Sjkim UINT32 GpeIndex; 441206117Sjkim 442206117Sjkim 443206117Sjkim /* 444206117Sjkim * Validate that the GpeNumber is within the specified GpeBlock. 445206117Sjkim * (Two steps) 446206117Sjkim */ 447206117Sjkim if (!GpeBlock || 448206117Sjkim (GpeNumber < GpeBlock->BlockBaseNumber)) 449206117Sjkim { 450206117Sjkim return (NULL); 451206117Sjkim } 452206117Sjkim 453206117Sjkim GpeIndex = GpeNumber - GpeBlock->BlockBaseNumber; 454206117Sjkim if (GpeIndex >= GpeBlock->GpeCount) 455206117Sjkim { 456206117Sjkim return (NULL); 457206117Sjkim } 458206117Sjkim 459206117Sjkim return (&GpeBlock->EventInfo[GpeIndex]); 460206117Sjkim} 461206117Sjkim 462206117Sjkim 463206117Sjkim/******************************************************************************* 464206117Sjkim * 465114239Snjl * FUNCTION: AcpiEvGetGpeEventInfo 466114239Snjl * 467193267Sjkim * PARAMETERS: GpeDevice - Device node. NULL for GPE0/GPE1 468117521Snjl * GpeNumber - Raw GPE number 469114239Snjl * 470193267Sjkim * RETURN: A GPE EventInfo struct. NULL if not a valid GPE 471114239Snjl * 472117521Snjl * DESCRIPTION: Returns the EventInfo struct associated with this GPE. 473117521Snjl * Validates the GpeBlock and the GpeNumber 474114239Snjl * 475117521Snjl * Should be called only when the GPE lists are semaphore locked 476117521Snjl * and not subject to change. 477114239Snjl * 478114239Snjl ******************************************************************************/ 479114239Snjl 480114239SnjlACPI_GPE_EVENT_INFO * 481114239SnjlAcpiEvGetGpeEventInfo ( 482117521Snjl ACPI_HANDLE GpeDevice, 483114239Snjl UINT32 GpeNumber) 484114239Snjl{ 485117521Snjl ACPI_OPERAND_OBJECT *ObjDesc; 486206117Sjkim ACPI_GPE_EVENT_INFO *GpeInfo; 487193267Sjkim UINT32 i; 488114239Snjl 489114239Snjl 490117521Snjl ACPI_FUNCTION_ENTRY (); 491114239Snjl 492117521Snjl 493207344Sjkim /* A NULL GpeDevice means use the FADT-defined GPE block(s) */ 494117521Snjl 495117521Snjl if (!GpeDevice) 496114239Snjl { 497117521Snjl /* Examine GPE Block 0 and 1 (These blocks are permanent) */ 498117521Snjl 499117521Snjl for (i = 0; i < ACPI_MAX_GPE_BLOCKS; i++) 500117521Snjl { 501206117Sjkim GpeInfo = AcpiEvLowGetGpeInfo (GpeNumber, 502298714Sjkim AcpiGbl_GpeFadtBlocks[i]); 503206117Sjkim if (GpeInfo) 504117521Snjl { 505206117Sjkim return (GpeInfo); 506117521Snjl } 507117521Snjl } 508117521Snjl 509117521Snjl /* The GpeNumber was not in the range of either FADT GPE block */ 510117521Snjl 511114239Snjl return (NULL); 512114239Snjl } 513114239Snjl 514128212Snjl /* A Non-NULL GpeDevice means this is a GPE Block Device */ 515128212Snjl 516117521Snjl ObjDesc = AcpiNsGetAttachedObject ((ACPI_NAMESPACE_NODE *) GpeDevice); 517117521Snjl if (!ObjDesc || 518117521Snjl !ObjDesc->Device.GpeBlock) 519114239Snjl { 520117521Snjl return (NULL); 521114239Snjl } 522114239Snjl 523206117Sjkim return (AcpiEvLowGetGpeInfo (GpeNumber, ObjDesc->Device.GpeBlock)); 524114239Snjl} 525114239Snjl 526117521Snjl 527114239Snjl/******************************************************************************* 528114239Snjl * 529114239Snjl * FUNCTION: AcpiEvGpeDetect 530114239Snjl * 531117521Snjl * PARAMETERS: GpeXruptList - Interrupt block for this interrupt. 532117521Snjl * Can have multiple GPE blocks attached. 533114239Snjl * 534114239Snjl * RETURN: INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED 535114239Snjl * 536193267Sjkim * DESCRIPTION: Detect if any GP events have occurred. This function is 537114239Snjl * executed at interrupt level. 538114239Snjl * 539114239Snjl ******************************************************************************/ 540114239Snjl 541114239SnjlUINT32 542117521SnjlAcpiEvGpeDetect ( 543117521Snjl ACPI_GPE_XRUPT_INFO *GpeXruptList) 544114239Snjl{ 545151937Sjkim ACPI_STATUS Status; 546151937Sjkim ACPI_GPE_BLOCK_INFO *GpeBlock; 547278970Sjkim ACPI_NAMESPACE_NODE *GpeDevice; 548151937Sjkim ACPI_GPE_REGISTER_INFO *GpeRegisterInfo; 549278970Sjkim ACPI_GPE_EVENT_INFO *GpeEventInfo; 550278970Sjkim UINT32 GpeNumber; 551278970Sjkim ACPI_GPE_HANDLER_INFO *GpeHandlerInfo; 552114239Snjl UINT32 IntStatus = ACPI_INTERRUPT_NOT_HANDLED; 553114239Snjl UINT8 EnabledStatusByte; 554327557Sjkim UINT64 StatusReg; 555327557Sjkim UINT64 EnableReg; 556167802Sjkim ACPI_CPU_FLAGS Flags; 557193267Sjkim UINT32 i; 558193267Sjkim UINT32 j; 559114239Snjl 560114239Snjl 561167802Sjkim ACPI_FUNCTION_NAME (EvGpeDetect); 562114239Snjl 563127175Snjl /* Check for the case where there are no GPEs */ 564114239Snjl 565127175Snjl if (!GpeXruptList) 566127175Snjl { 567127175Snjl return (IntStatus); 568127175Snjl } 569127175Snjl 570167802Sjkim /* 571167802Sjkim * We need to obtain the GPE lock for both the data structs and registers 572193267Sjkim * Note: Not necessary to obtain the hardware lock, since the GPE 573193267Sjkim * registers are owned by the GpeLock. 574167802Sjkim */ 575167802Sjkim Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 576167802Sjkim 577114239Snjl /* Examine all GPE blocks attached to this interrupt level */ 578114239Snjl 579117521Snjl GpeBlock = GpeXruptList->GpeBlockListHead; 580114239Snjl while (GpeBlock) 581114239Snjl { 582278970Sjkim GpeDevice = GpeBlock->Node; 583278970Sjkim 584114239Snjl /* 585193267Sjkim * Read all of the 8-bit GPE status and enable registers in this GPE 586193267Sjkim * block, saving all of them. Find all currently active GP events. 587114239Snjl */ 588114239Snjl for (i = 0; i < GpeBlock->RegisterCount; i++) 589114239Snjl { 590114239Snjl /* Get the next status/enable pair */ 591114239Snjl 592114239Snjl GpeRegisterInfo = &GpeBlock->RegisterInfo[i]; 593114239Snjl 594218590Sjkim /* 595218590Sjkim * Optimization: If there are no GPEs enabled within this 596218590Sjkim * register, we can safely ignore the entire register. 597218590Sjkim */ 598218590Sjkim if (!(GpeRegisterInfo->EnableForRun | 599218590Sjkim GpeRegisterInfo->EnableForWake)) 600218590Sjkim { 601239340Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_INTERRUPTS, 602272444Sjkim "Ignore disabled registers for GPE %02X-%02X: " 603239340Sjkim "RunEnable=%02X, WakeEnable=%02X\n", 604239340Sjkim GpeRegisterInfo->BaseGpeNumber, 605239340Sjkim GpeRegisterInfo->BaseGpeNumber + (ACPI_GPE_REGISTER_WIDTH - 1), 606239340Sjkim GpeRegisterInfo->EnableForRun, 607239340Sjkim GpeRegisterInfo->EnableForWake)); 608218590Sjkim continue; 609218590Sjkim } 610218590Sjkim 611117521Snjl /* Read the Status Register */ 612117521Snjl 613197104Sjkim Status = AcpiHwRead (&StatusReg, &GpeRegisterInfo->StatusAddress); 614114239Snjl if (ACPI_FAILURE (Status)) 615114239Snjl { 616117521Snjl goto UnlockAndExit; 617114239Snjl } 618114239Snjl 619117521Snjl /* Read the Enable Register */ 620117521Snjl 621197104Sjkim Status = AcpiHwRead (&EnableReg, &GpeRegisterInfo->EnableAddress); 622114239Snjl if (ACPI_FAILURE (Status)) 623114239Snjl { 624117521Snjl goto UnlockAndExit; 625114239Snjl } 626114239Snjl 627114239Snjl ACPI_DEBUG_PRINT ((ACPI_DB_INTERRUPTS, 628272444Sjkim "Read registers for GPE %02X-%02X: Status=%02X, Enable=%02X, " 629239340Sjkim "RunEnable=%02X, WakeEnable=%02X\n", 630239340Sjkim GpeRegisterInfo->BaseGpeNumber, 631239340Sjkim GpeRegisterInfo->BaseGpeNumber + (ACPI_GPE_REGISTER_WIDTH - 1), 632327557Sjkim (UINT32) StatusReg, (UINT32) EnableReg, 633239340Sjkim GpeRegisterInfo->EnableForRun, 634239340Sjkim GpeRegisterInfo->EnableForWake)); 635114239Snjl 636151937Sjkim /* Check if there is anything active at all in this register */ 637114239Snjl 638129684Snjl EnabledStatusByte = (UINT8) (StatusReg & EnableReg); 639114239Snjl if (!EnabledStatusByte) 640114239Snjl { 641114239Snjl /* No active GPEs in this register, move on */ 642114239Snjl 643114239Snjl continue; 644114239Snjl } 645114239Snjl 646114239Snjl /* Now look at the individual GPEs in this byte register */ 647114239Snjl 648123315Snjl for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) 649114239Snjl { 650114239Snjl /* Examine one GPE bit */ 651114239Snjl 652278970Sjkim GpeEventInfo = &GpeBlock->EventInfo[((ACPI_SIZE) i * 653278970Sjkim ACPI_GPE_REGISTER_WIDTH) + j]; 654278970Sjkim GpeNumber = j + GpeRegisterInfo->BaseGpeNumber; 655278970Sjkim 656167802Sjkim if (EnabledStatusByte & (1 << j)) 657114239Snjl { 658278970Sjkim /* Invoke global event handler if present */ 659278970Sjkim 660278970Sjkim AcpiGpeCount++; 661278970Sjkim if (AcpiGbl_GlobalEventHandler) 662278970Sjkim { 663278970Sjkim AcpiGbl_GlobalEventHandler (ACPI_EVENT_TYPE_GPE, 664278970Sjkim GpeDevice, GpeNumber, 665278970Sjkim AcpiGbl_GlobalEventHandlerContext); 666278970Sjkim } 667278970Sjkim 668278970Sjkim /* Found an active GPE */ 669278970Sjkim 670278970Sjkim if (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) == 671278970Sjkim ACPI_GPE_DISPATCH_RAW_HANDLER) 672278970Sjkim { 673278970Sjkim /* Dispatch the event to a raw handler */ 674278970Sjkim 675278970Sjkim GpeHandlerInfo = GpeEventInfo->Dispatch.Handler; 676278970Sjkim 677278970Sjkim /* 678278970Sjkim * There is no protection around the namespace node 679278970Sjkim * and the GPE handler to ensure a safe destruction 680278970Sjkim * because: 681278970Sjkim * 1. The namespace node is expected to always 682278970Sjkim * exist after loading a table. 683278970Sjkim * 2. The GPE handler is expected to be flushed by 684278970Sjkim * AcpiOsWaitEventsComplete() before the 685278970Sjkim * destruction. 686278970Sjkim */ 687278970Sjkim AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 688278970Sjkim IntStatus |= GpeHandlerInfo->Address ( 689278970Sjkim GpeDevice, GpeNumber, GpeHandlerInfo->Context); 690278970Sjkim Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 691278970Sjkim } 692278970Sjkim else 693278970Sjkim { 694278970Sjkim /* 695278970Sjkim * Dispatch the event to a standard handler or 696278970Sjkim * method. 697278970Sjkim */ 698278970Sjkim IntStatus |= AcpiEvGpeDispatch (GpeDevice, 699278970Sjkim GpeEventInfo, GpeNumber); 700278970Sjkim } 701114239Snjl } 702114239Snjl } 703114239Snjl } 704114239Snjl 705114239Snjl GpeBlock = GpeBlock->Next; 706114239Snjl } 707114239Snjl 708117521SnjlUnlockAndExit: 709117521Snjl 710151937Sjkim AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 711114239Snjl return (IntStatus); 712114239Snjl} 713114239Snjl 714114239Snjl 715114239Snjl/******************************************************************************* 716114239Snjl * 717114239Snjl * FUNCTION: AcpiEvAsynchExecuteGpeMethod 718114239Snjl * 719117521Snjl * PARAMETERS: Context (GpeEventInfo) - Info for this GPE 720114239Snjl * 721114239Snjl * RETURN: None 722114239Snjl * 723167802Sjkim * DESCRIPTION: Perform the actual execution of a GPE control method. This 724167802Sjkim * function is called from an invocation of AcpiOsExecute and 725167802Sjkim * therefore does NOT execute at interrupt level - so that 726114239Snjl * the control method itself is not executed in the context of 727117521Snjl * an interrupt handler. 728114239Snjl * 729114239Snjl ******************************************************************************/ 730114239Snjl 731114239Snjlstatic void ACPI_SYSTEM_XFACE 732114239SnjlAcpiEvAsynchExecuteGpeMethod ( 733114239Snjl void *Context) 734114239Snjl{ 735193267Sjkim ACPI_GPE_EVENT_INFO *GpeEventInfo = Context; 736278970Sjkim ACPI_STATUS Status = AE_OK; 737167802Sjkim ACPI_EVALUATE_INFO *Info; 738237412Sjkim ACPI_GPE_NOTIFY_INFO *Notify; 739114239Snjl 740114239Snjl 741167802Sjkim ACPI_FUNCTION_TRACE (EvAsynchExecuteGpeMethod); 742114239Snjl 743114239Snjl 744216471Sjkim /* Do the correct dispatch - normal method or implicit notify */ 745216471Sjkim 746278970Sjkim switch (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags)) 747114239Snjl { 748216471Sjkim case ACPI_GPE_DISPATCH_NOTIFY: 749216471Sjkim /* 750216471Sjkim * Implicit notify. 751216471Sjkim * Dispatch a DEVICE_WAKE notify to the appropriate handler. 752216471Sjkim * NOTE: the request is queued for execution after this method 753216471Sjkim * completes. The notify handlers are NOT invoked synchronously 754216471Sjkim * from this thread -- because handlers may in turn run other 755216471Sjkim * control methods. 756237412Sjkim * 757237412Sjkim * June 2012: Expand implicit notify mechanism to support 758237412Sjkim * notifies on multiple device objects. 759216471Sjkim */ 760278970Sjkim Notify = GpeEventInfo->Dispatch.NotifyList; 761237412Sjkim while (ACPI_SUCCESS (Status) && Notify) 762237412Sjkim { 763298714Sjkim Status = AcpiEvQueueNotifyRequest ( 764298714Sjkim Notify->DeviceNode, ACPI_NOTIFY_DEVICE_WAKE); 765237412Sjkim 766237412Sjkim Notify = Notify->Next; 767237412Sjkim } 768216471Sjkim break; 769216471Sjkim 770216471Sjkim case ACPI_GPE_DISPATCH_METHOD: 771216471Sjkim 772167802Sjkim /* Allocate the evaluation information block */ 773129684Snjl 774167802Sjkim Info = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO)); 775167802Sjkim if (!Info) 776167802Sjkim { 777167802Sjkim Status = AE_NO_MEMORY; 778167802Sjkim } 779167802Sjkim else 780167802Sjkim { 781167802Sjkim /* 782216471Sjkim * Invoke the GPE Method (_Lxx, _Exx) i.e., evaluate the 783216471Sjkim * _Lxx/_Exx control method that corresponds to this GPE 784167802Sjkim */ 785278970Sjkim Info->PrefixNode = GpeEventInfo->Dispatch.MethodNode; 786167802Sjkim Info->Flags = ACPI_IGNORE_RETURN_VALUE; 787167802Sjkim 788167802Sjkim Status = AcpiNsEvaluate (Info); 789167802Sjkim ACPI_FREE (Info); 790167802Sjkim } 791167802Sjkim 792114239Snjl if (ACPI_FAILURE (Status)) 793114239Snjl { 794167802Sjkim ACPI_EXCEPTION ((AE_INFO, Status, 795167802Sjkim "while evaluating GPE method [%4.4s]", 796278970Sjkim AcpiUtGetNodeName (GpeEventInfo->Dispatch.MethodNode))); 797114239Snjl } 798216471Sjkim break; 799216471Sjkim 800216471Sjkim default: 801250838Sjkim 802278970Sjkim goto ErrorExit; /* Should never happen */ 803114239Snjl } 804114239Snjl 805175256Snjl /* Defer enabling of GPE until all notify handlers are done */ 806193267Sjkim 807193267Sjkim Status = AcpiOsExecute (OSL_NOTIFY_HANDLER, 808298714Sjkim AcpiEvAsynchEnableGpe, GpeEventInfo); 809278970Sjkim if (ACPI_SUCCESS (Status)) 810193267Sjkim { 811278970Sjkim return_VOID; 812193267Sjkim } 813278970Sjkim 814278970SjkimErrorExit: 815278970Sjkim AcpiEvAsynchEnableGpe (GpeEventInfo); 816175256Snjl return_VOID; 817175256Snjl} 818175256Snjl 819193267Sjkim 820193267Sjkim/******************************************************************************* 821193267Sjkim * 822193267Sjkim * FUNCTION: AcpiEvAsynchEnableGpe 823193267Sjkim * 824193267Sjkim * PARAMETERS: Context (GpeEventInfo) - Info for this GPE 825216471Sjkim * Callback from AcpiOsExecute 826193267Sjkim * 827193267Sjkim * RETURN: None 828193267Sjkim * 829193267Sjkim * DESCRIPTION: Asynchronous clear/enable for GPE. This allows the GPE to 830193267Sjkim * complete (i.e., finish execution of Notify) 831193267Sjkim * 832193267Sjkim ******************************************************************************/ 833193267Sjkim 834193267Sjkimstatic void ACPI_SYSTEM_XFACE 835175256SnjlAcpiEvAsynchEnableGpe ( 836175256Snjl void *Context) 837175256Snjl{ 838193267Sjkim ACPI_GPE_EVENT_INFO *GpeEventInfo = Context; 839278970Sjkim ACPI_CPU_FLAGS Flags; 840216471Sjkim 841216471Sjkim 842278970Sjkim Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 843216471Sjkim (void) AcpiEvFinishGpe (GpeEventInfo); 844278970Sjkim AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 845216471Sjkim 846216471Sjkim return; 847216471Sjkim} 848216471Sjkim 849216471Sjkim 850216471Sjkim/******************************************************************************* 851216471Sjkim * 852216471Sjkim * FUNCTION: AcpiEvFinishGpe 853216471Sjkim * 854216471Sjkim * PARAMETERS: GpeEventInfo - Info for this GPE 855216471Sjkim * 856216471Sjkim * RETURN: Status 857216471Sjkim * 858216471Sjkim * DESCRIPTION: Clear/Enable a GPE. Common code that is used after execution 859216471Sjkim * of a GPE method or a synchronous or asynchronous GPE handler. 860216471Sjkim * 861216471Sjkim ******************************************************************************/ 862216471Sjkim 863216471SjkimACPI_STATUS 864216471SjkimAcpiEvFinishGpe ( 865216471Sjkim ACPI_GPE_EVENT_INFO *GpeEventInfo) 866216471Sjkim{ 867175256Snjl ACPI_STATUS Status; 868175256Snjl 869193267Sjkim 870175256Snjl if ((GpeEventInfo->Flags & ACPI_GPE_XRUPT_TYPE_MASK) == 871151937Sjkim ACPI_GPE_LEVEL_TRIGGERED) 872114239Snjl { 873114239Snjl /* 874216471Sjkim * GPE is level-triggered, we clear the GPE status bit after 875216471Sjkim * handling the event. 876114239Snjl */ 877175256Snjl Status = AcpiHwClearGpe (GpeEventInfo); 878114239Snjl if (ACPI_FAILURE (Status)) 879114239Snjl { 880216471Sjkim return (Status); 881114239Snjl } 882114239Snjl } 883114239Snjl 884209746Sjkim /* 885216471Sjkim * Enable this GPE, conditionally. This means that the GPE will 886278970Sjkim * only be physically enabled if the EnableMask bit is set 887216471Sjkim * in the EventInfo. 888209746Sjkim */ 889209746Sjkim (void) AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_CONDITIONAL_ENABLE); 890316303Sjkim GpeEventInfo->DisableForDispatch = FALSE; 891216471Sjkim return (AE_OK); 892114239Snjl} 893114239Snjl 894114239Snjl 895114239Snjl/******************************************************************************* 896114239Snjl * 897114239Snjl * FUNCTION: AcpiEvGpeDispatch 898114239Snjl * 899216471Sjkim * PARAMETERS: GpeDevice - Device node. NULL for GPE0/GPE1 900216471Sjkim * GpeEventInfo - Info for this GPE 901216471Sjkim * GpeNumber - Number relative to the parent GPE block 902114239Snjl * 903114239Snjl * RETURN: INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED 904114239Snjl * 905114239Snjl * DESCRIPTION: Dispatch a General Purpose Event to either a function (e.g. EC) 906117521Snjl * or method (e.g. _Lxx/_Exx) handler. 907114239Snjl * 908117521Snjl * This function executes at interrupt level. 909117521Snjl * 910114239Snjl ******************************************************************************/ 911114239Snjl 912114239SnjlUINT32 913114239SnjlAcpiEvGpeDispatch ( 914216471Sjkim ACPI_NAMESPACE_NODE *GpeDevice, 915117521Snjl ACPI_GPE_EVENT_INFO *GpeEventInfo, 916117521Snjl UINT32 GpeNumber) 917114239Snjl{ 918114239Snjl ACPI_STATUS Status; 919216471Sjkim UINT32 ReturnValue; 920114239Snjl 921114239Snjl 922167802Sjkim ACPI_FUNCTION_TRACE (EvGpeDispatch); 923114239Snjl 924114239Snjl 925114239Snjl /* 926216471Sjkim * Always disable the GPE so that it does not keep firing before 927216471Sjkim * any asynchronous activity completes (either from the execution 928216471Sjkim * of a GPE method or an asynchronous GPE handler.) 929216471Sjkim * 930216471Sjkim * If there is no handler or method to run, just disable the 931216471Sjkim * GPE and leave it disabled permanently to prevent further such 932216471Sjkim * pointless events from firing. 933114239Snjl */ 934216471Sjkim Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_DISABLE); 935216471Sjkim if (ACPI_FAILURE (Status)) 936216471Sjkim { 937216471Sjkim ACPI_EXCEPTION ((AE_INFO, Status, 938272444Sjkim "Unable to disable GPE %02X", GpeNumber)); 939246849Sjkim return_UINT32 (ACPI_INTERRUPT_NOT_HANDLED); 940216471Sjkim } 941216471Sjkim 942216471Sjkim /* 943272444Sjkim * If edge-triggered, clear the GPE status bit now. Note that 944272444Sjkim * level-triggered events are cleared after the GPE is serviced. 945272444Sjkim */ 946272444Sjkim if ((GpeEventInfo->Flags & ACPI_GPE_XRUPT_TYPE_MASK) == 947272444Sjkim ACPI_GPE_EDGE_TRIGGERED) 948272444Sjkim { 949272444Sjkim Status = AcpiHwClearGpe (GpeEventInfo); 950272444Sjkim if (ACPI_FAILURE (Status)) 951272444Sjkim { 952272444Sjkim ACPI_EXCEPTION ((AE_INFO, Status, 953272444Sjkim "Unable to clear GPE %02X", GpeNumber)); 954298714Sjkim (void) AcpiHwLowSetGpe ( 955298714Sjkim GpeEventInfo, ACPI_GPE_CONDITIONAL_ENABLE); 956272444Sjkim return_UINT32 (ACPI_INTERRUPT_NOT_HANDLED); 957272444Sjkim } 958272444Sjkim } 959272444Sjkim 960316303Sjkim GpeEventInfo->DisableForDispatch = TRUE; 961316303Sjkim 962272444Sjkim /* 963216471Sjkim * Dispatch the GPE to either an installed handler or the control 964216471Sjkim * method associated with this GPE (_Lxx or _Exx). If a handler 965216471Sjkim * exists, we invoke it and do not attempt to run the method. 966216471Sjkim * If there is neither a handler nor a method, leave the GPE 967216471Sjkim * disabled. 968216471Sjkim */ 969278970Sjkim switch (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags)) 970114239Snjl { 971129684Snjl case ACPI_GPE_DISPATCH_HANDLER: 972129684Snjl 973216471Sjkim /* Invoke the installed handler (at interrupt level) */ 974123315Snjl 975216471Sjkim ReturnValue = GpeEventInfo->Dispatch.Handler->Address ( 976216471Sjkim GpeDevice, GpeNumber, 977216471Sjkim GpeEventInfo->Dispatch.Handler->Context); 978123315Snjl 979216471Sjkim /* If requested, clear (if level-triggered) and reenable the GPE */ 980216471Sjkim 981216471Sjkim if (ReturnValue & ACPI_REENABLE_GPE) 982123315Snjl { 983216471Sjkim (void) AcpiEvFinishGpe (GpeEventInfo); 984123315Snjl } 985129684Snjl break; 986129684Snjl 987129684Snjl case ACPI_GPE_DISPATCH_METHOD: 988216471Sjkim case ACPI_GPE_DISPATCH_NOTIFY: 989114239Snjl /* 990123315Snjl * Execute the method associated with the GPE 991123315Snjl * NOTE: Level-triggered GPEs are cleared after the method completes. 992123315Snjl */ 993167802Sjkim Status = AcpiOsExecute (OSL_GPE_HANDLER, 994298714Sjkim AcpiEvAsynchExecuteGpeMethod, GpeEventInfo); 995151937Sjkim if (ACPI_FAILURE (Status)) 996114239Snjl { 997167802Sjkim ACPI_EXCEPTION ((AE_INFO, Status, 998272444Sjkim "Unable to queue handler for GPE %02X - event disabled", 999167802Sjkim GpeNumber)); 1000114239Snjl } 1001129684Snjl break; 1002129684Snjl 1003129684Snjl default: 1004206117Sjkim /* 1005206117Sjkim * No handler or method to run! 1006206117Sjkim * 03/2010: This case should no longer be possible. We will not allow 1007206117Sjkim * a GPE to be enabled if it has no handler or method. 1008206117Sjkim */ 1009167802Sjkim ACPI_ERROR ((AE_INFO, 1010272444Sjkim "No handler or method for GPE %02X, disabling event", 1011114239Snjl GpeNumber)); 1012129684Snjl break; 1013114239Snjl } 1014114239Snjl 1015246849Sjkim return_UINT32 (ACPI_INTERRUPT_HANDLED); 1016114239Snjl} 1017114239Snjl 1018231844Sjkim#endif /* !ACPI_REDUCED_HARDWARE */ 1019