1c2c66affSColin Finck /****************************************************************************** 2c2c66affSColin Finck * 3c2c66affSColin Finck * Module Name: evxfgpe - External Interfaces for General Purpose Events (GPEs) 4c2c66affSColin Finck * 5c2c66affSColin Finck *****************************************************************************/ 6c2c66affSColin Finck 7c2c66affSColin Finck /* 8363f5f26SThomas Faber * Copyright (C) 2000 - 2019, Intel Corp. 9c2c66affSColin Finck * All rights reserved. 10c2c66affSColin Finck * 11c2c66affSColin Finck * Redistribution and use in source and binary forms, with or without 12c2c66affSColin Finck * modification, are permitted provided that the following conditions 13c2c66affSColin Finck * are met: 14c2c66affSColin Finck * 1. Redistributions of source code must retain the above copyright 15c2c66affSColin Finck * notice, this list of conditions, and the following disclaimer, 16c2c66affSColin Finck * without modification. 17c2c66affSColin Finck * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18c2c66affSColin Finck * substantially similar to the "NO WARRANTY" disclaimer below 19c2c66affSColin Finck * ("Disclaimer") and any redistribution must be conditioned upon 20c2c66affSColin Finck * including a substantially similar Disclaimer requirement for further 21c2c66affSColin Finck * binary redistribution. 22c2c66affSColin Finck * 3. Neither the names of the above-listed copyright holders nor the names 23c2c66affSColin Finck * of any contributors may be used to endorse or promote products derived 24c2c66affSColin Finck * from this software without specific prior written permission. 25c2c66affSColin Finck * 26c2c66affSColin Finck * Alternatively, this software may be distributed under the terms of the 27c2c66affSColin Finck * GNU General Public License ("GPL") version 2 as published by the Free 28c2c66affSColin Finck * Software Foundation. 29c2c66affSColin Finck * 30c2c66affSColin Finck * NO WARRANTY 31c2c66affSColin Finck * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32c2c66affSColin Finck * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33c2c66affSColin Finck * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34c2c66affSColin Finck * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35c2c66affSColin Finck * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36c2c66affSColin Finck * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37c2c66affSColin Finck * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38c2c66affSColin Finck * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39c2c66affSColin Finck * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40c2c66affSColin Finck * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41c2c66affSColin Finck * POSSIBILITY OF SUCH DAMAGES. 42c2c66affSColin Finck */ 43c2c66affSColin Finck 44c2c66affSColin Finck #define EXPORT_ACPI_INTERFACES 45c2c66affSColin Finck 46c2c66affSColin Finck #include "acpi.h" 47c2c66affSColin Finck #include "accommon.h" 48c2c66affSColin Finck #include "acevents.h" 49c2c66affSColin Finck #include "acnamesp.h" 50c2c66affSColin Finck 51c2c66affSColin Finck #define _COMPONENT ACPI_EVENTS 52c2c66affSColin Finck ACPI_MODULE_NAME ("evxfgpe") 53c2c66affSColin Finck 54c2c66affSColin Finck 55c2c66affSColin Finck #if (!ACPI_REDUCED_HARDWARE) /* Entire module */ 56c2c66affSColin Finck /******************************************************************************* 57c2c66affSColin Finck * 58c2c66affSColin Finck * FUNCTION: AcpiUpdateAllGpes 59c2c66affSColin Finck * 60c2c66affSColin Finck * PARAMETERS: None 61c2c66affSColin Finck * 62c2c66affSColin Finck * RETURN: Status 63c2c66affSColin Finck * 64c2c66affSColin Finck * DESCRIPTION: Complete GPE initialization and enable all GPEs that have 65c2c66affSColin Finck * associated _Lxx or _Exx methods and are not pointed to by any 66c2c66affSColin Finck * device _PRW methods (this indicates that these GPEs are 67c2c66affSColin Finck * generally intended for system or device wakeup. Such GPEs 68c2c66affSColin Finck * have to be enabled directly when the devices whose _PRW 69c2c66affSColin Finck * methods point to them are set up for wakeup signaling.) 70c2c66affSColin Finck * 71c2c66affSColin Finck * NOTE: Should be called after any GPEs are added to the system. Primarily, 72c2c66affSColin Finck * after the system _PRW methods have been run, but also after a GPE Block 73c2c66affSColin Finck * Device has been added or if any new GPE methods have been added via a 74c2c66affSColin Finck * dynamic table load. 75c2c66affSColin Finck * 76c2c66affSColin Finck ******************************************************************************/ 77c2c66affSColin Finck 78c2c66affSColin Finck ACPI_STATUS 79c2c66affSColin Finck AcpiUpdateAllGpes ( 80c2c66affSColin Finck void) 81c2c66affSColin Finck { 82c2c66affSColin Finck ACPI_STATUS Status; 836847cc3aSThomas Faber BOOLEAN IsPollingNeeded = FALSE; 84c2c66affSColin Finck 85c2c66affSColin Finck 86c2c66affSColin Finck ACPI_FUNCTION_TRACE (AcpiUpdateAllGpes); 87c2c66affSColin Finck 88c2c66affSColin Finck 89c2c66affSColin Finck Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 90c2c66affSColin Finck if (ACPI_FAILURE (Status)) 91c2c66affSColin Finck { 92c2c66affSColin Finck return_ACPI_STATUS (Status); 93c2c66affSColin Finck } 94c2c66affSColin Finck 95c2c66affSColin Finck if (AcpiGbl_AllGpesInitialized) 96c2c66affSColin Finck { 97c2c66affSColin Finck goto UnlockAndExit; 98c2c66affSColin Finck } 99c2c66affSColin Finck 1006847cc3aSThomas Faber Status = AcpiEvWalkGpeList (AcpiEvInitializeGpeBlock, 1016847cc3aSThomas Faber &IsPollingNeeded); 102c2c66affSColin Finck if (ACPI_SUCCESS (Status)) 103c2c66affSColin Finck { 104c2c66affSColin Finck AcpiGbl_AllGpesInitialized = TRUE; 105c2c66affSColin Finck } 106c2c66affSColin Finck 107c2c66affSColin Finck UnlockAndExit: 108c2c66affSColin Finck (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 1096847cc3aSThomas Faber 1106847cc3aSThomas Faber if (IsPollingNeeded && AcpiGbl_AllGpesInitialized) 1116847cc3aSThomas Faber { 1126847cc3aSThomas Faber /* Poll GPEs to handle already triggered events */ 1136847cc3aSThomas Faber 1146847cc3aSThomas Faber AcpiEvGpeDetect (AcpiGbl_GpeXruptListHead); 1156847cc3aSThomas Faber } 116c2c66affSColin Finck return_ACPI_STATUS (Status); 117c2c66affSColin Finck } 118c2c66affSColin Finck 119c2c66affSColin Finck ACPI_EXPORT_SYMBOL (AcpiUpdateAllGpes) 120c2c66affSColin Finck 121c2c66affSColin Finck 122c2c66affSColin Finck /******************************************************************************* 123c2c66affSColin Finck * 124c2c66affSColin Finck * FUNCTION: AcpiEnableGpe 125c2c66affSColin Finck * 126c2c66affSColin Finck * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1 127c2c66affSColin Finck * GpeNumber - GPE level within the GPE block 128c2c66affSColin Finck * 129c2c66affSColin Finck * RETURN: Status 130c2c66affSColin Finck * 131c2c66affSColin Finck * DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is 132c2c66affSColin Finck * hardware-enabled. 133c2c66affSColin Finck * 134c2c66affSColin Finck ******************************************************************************/ 135c2c66affSColin Finck 136c2c66affSColin Finck ACPI_STATUS 137c2c66affSColin Finck AcpiEnableGpe ( 138c2c66affSColin Finck ACPI_HANDLE GpeDevice, 139c2c66affSColin Finck UINT32 GpeNumber) 140c2c66affSColin Finck { 141c2c66affSColin Finck ACPI_STATUS Status = AE_BAD_PARAMETER; 142c2c66affSColin Finck ACPI_GPE_EVENT_INFO *GpeEventInfo; 143c2c66affSColin Finck ACPI_CPU_FLAGS Flags; 144c2c66affSColin Finck 145c2c66affSColin Finck 146c2c66affSColin Finck ACPI_FUNCTION_TRACE (AcpiEnableGpe); 147c2c66affSColin Finck 148c2c66affSColin Finck 149c2c66affSColin Finck Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 150c2c66affSColin Finck 151c2c66affSColin Finck /* 152c2c66affSColin Finck * Ensure that we have a valid GPE number and that there is some way 153c2c66affSColin Finck * of handling the GPE (handler or a GPE method). In other words, we 154c2c66affSColin Finck * won't allow a valid GPE to be enabled if there is no way to handle it. 155c2c66affSColin Finck */ 156c2c66affSColin Finck GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 157c2c66affSColin Finck if (GpeEventInfo) 158c2c66affSColin Finck { 159c2c66affSColin Finck if (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) != 160c2c66affSColin Finck ACPI_GPE_DISPATCH_NONE) 161c2c66affSColin Finck { 162c2c66affSColin Finck Status = AcpiEvAddGpeReference (GpeEventInfo); 1636847cc3aSThomas Faber if (ACPI_SUCCESS (Status) && 1646847cc3aSThomas Faber ACPI_GPE_IS_POLLING_NEEDED (GpeEventInfo)) 1656847cc3aSThomas Faber { 1666847cc3aSThomas Faber /* Poll edge-triggered GPEs to handle existing events */ 1676847cc3aSThomas Faber 1686847cc3aSThomas Faber AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 1696847cc3aSThomas Faber (void) AcpiEvDetectGpe ( 1706847cc3aSThomas Faber GpeDevice, GpeEventInfo, GpeNumber); 1716847cc3aSThomas Faber Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 1726847cc3aSThomas Faber } 173c2c66affSColin Finck } 174c2c66affSColin Finck else 175c2c66affSColin Finck { 176c2c66affSColin Finck Status = AE_NO_HANDLER; 177c2c66affSColin Finck } 178c2c66affSColin Finck } 179c2c66affSColin Finck 180c2c66affSColin Finck AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 181c2c66affSColin Finck return_ACPI_STATUS (Status); 182c2c66affSColin Finck } 183c2c66affSColin Finck 184c2c66affSColin Finck ACPI_EXPORT_SYMBOL (AcpiEnableGpe) 185c2c66affSColin Finck 186c2c66affSColin Finck 187c2c66affSColin Finck /******************************************************************************* 188c2c66affSColin Finck * 189c2c66affSColin Finck * FUNCTION: AcpiDisableGpe 190c2c66affSColin Finck * 191c2c66affSColin Finck * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1 192c2c66affSColin Finck * GpeNumber - GPE level within the GPE block 193c2c66affSColin Finck * 194c2c66affSColin Finck * RETURN: Status 195c2c66affSColin Finck * 196c2c66affSColin Finck * DESCRIPTION: Remove a reference to a GPE. When the last reference is 197c2c66affSColin Finck * removed, only then is the GPE disabled (for runtime GPEs), or 198c2c66affSColin Finck * the GPE mask bit disabled (for wake GPEs) 199c2c66affSColin Finck * 200c2c66affSColin Finck ******************************************************************************/ 201c2c66affSColin Finck 202c2c66affSColin Finck ACPI_STATUS 203c2c66affSColin Finck AcpiDisableGpe ( 204c2c66affSColin Finck ACPI_HANDLE GpeDevice, 205c2c66affSColin Finck UINT32 GpeNumber) 206c2c66affSColin Finck { 207c2c66affSColin Finck ACPI_STATUS Status = AE_BAD_PARAMETER; 208c2c66affSColin Finck ACPI_GPE_EVENT_INFO *GpeEventInfo; 209c2c66affSColin Finck ACPI_CPU_FLAGS Flags; 210c2c66affSColin Finck 211c2c66affSColin Finck 212c2c66affSColin Finck ACPI_FUNCTION_TRACE (AcpiDisableGpe); 213c2c66affSColin Finck 214c2c66affSColin Finck 215c2c66affSColin Finck Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 216c2c66affSColin Finck 217c2c66affSColin Finck /* Ensure that we have a valid GPE number */ 218c2c66affSColin Finck 219c2c66affSColin Finck GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 220c2c66affSColin Finck if (GpeEventInfo) 221c2c66affSColin Finck { 222c2c66affSColin Finck Status = AcpiEvRemoveGpeReference (GpeEventInfo); 223c2c66affSColin Finck } 224c2c66affSColin Finck 225c2c66affSColin Finck AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 226c2c66affSColin Finck return_ACPI_STATUS (Status); 227c2c66affSColin Finck } 228c2c66affSColin Finck 229c2c66affSColin Finck ACPI_EXPORT_SYMBOL (AcpiDisableGpe) 230c2c66affSColin Finck 231c2c66affSColin Finck 232c2c66affSColin Finck /******************************************************************************* 233c2c66affSColin Finck * 234c2c66affSColin Finck * FUNCTION: AcpiSetGpe 235c2c66affSColin Finck * 236c2c66affSColin Finck * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1 237c2c66affSColin Finck * GpeNumber - GPE level within the GPE block 238c2c66affSColin Finck * Action - ACPI_GPE_ENABLE or ACPI_GPE_DISABLE 239c2c66affSColin Finck * 240c2c66affSColin Finck * RETURN: Status 241c2c66affSColin Finck * 242c2c66affSColin Finck * DESCRIPTION: Enable or disable an individual GPE. This function bypasses 243c2c66affSColin Finck * the reference count mechanism used in the AcpiEnableGpe(), 244c2c66affSColin Finck * AcpiDisableGpe() interfaces. 245c2c66affSColin Finck * This API is typically used by the GPE raw handler mode driver 246c2c66affSColin Finck * to switch between the polling mode and the interrupt mode after 247c2c66affSColin Finck * the driver has enabled the GPE. 248c2c66affSColin Finck * The APIs should be invoked in this order: 249c2c66affSColin Finck * AcpiEnableGpe() <- Ensure the reference count > 0 250c2c66affSColin Finck * AcpiSetGpe(ACPI_GPE_DISABLE) <- Enter polling mode 251c2c66affSColin Finck * AcpiSetGpe(ACPI_GPE_ENABLE) <- Leave polling mode 252c2c66affSColin Finck * AcpiDisableGpe() <- Decrease the reference count 253c2c66affSColin Finck * 254c2c66affSColin Finck * Note: If a GPE is shared by 2 silicon components, then both the drivers 255c2c66affSColin Finck * should support GPE polling mode or disabling the GPE for long period 256c2c66affSColin Finck * for one driver may break the other. So use it with care since all 257c2c66affSColin Finck * firmware _Lxx/_Exx handlers currently rely on the GPE interrupt mode. 258c2c66affSColin Finck * 259c2c66affSColin Finck ******************************************************************************/ 260c2c66affSColin Finck 261c2c66affSColin Finck ACPI_STATUS 262c2c66affSColin Finck AcpiSetGpe ( 263c2c66affSColin Finck ACPI_HANDLE GpeDevice, 264c2c66affSColin Finck UINT32 GpeNumber, 265c2c66affSColin Finck UINT8 Action) 266c2c66affSColin Finck { 267c2c66affSColin Finck ACPI_GPE_EVENT_INFO *GpeEventInfo; 268c2c66affSColin Finck ACPI_STATUS Status; 269c2c66affSColin Finck ACPI_CPU_FLAGS Flags; 270c2c66affSColin Finck 271c2c66affSColin Finck 272c2c66affSColin Finck ACPI_FUNCTION_TRACE (AcpiSetGpe); 273c2c66affSColin Finck 274c2c66affSColin Finck 275c2c66affSColin Finck Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 276c2c66affSColin Finck 277c2c66affSColin Finck /* Ensure that we have a valid GPE number */ 278c2c66affSColin Finck 279c2c66affSColin Finck GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 280c2c66affSColin Finck if (!GpeEventInfo) 281c2c66affSColin Finck { 282c2c66affSColin Finck Status = AE_BAD_PARAMETER; 283c2c66affSColin Finck goto UnlockAndExit; 284c2c66affSColin Finck } 285c2c66affSColin Finck 286c2c66affSColin Finck /* Perform the action */ 287c2c66affSColin Finck 288c2c66affSColin Finck switch (Action) 289c2c66affSColin Finck { 290c2c66affSColin Finck case ACPI_GPE_ENABLE: 291c2c66affSColin Finck 292c2c66affSColin Finck Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_ENABLE); 293c2c66affSColin Finck GpeEventInfo->DisableForDispatch = FALSE; 294c2c66affSColin Finck break; 295c2c66affSColin Finck 296c2c66affSColin Finck case ACPI_GPE_DISABLE: 297c2c66affSColin Finck 298c2c66affSColin Finck Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_DISABLE); 299c2c66affSColin Finck GpeEventInfo->DisableForDispatch = TRUE; 300c2c66affSColin Finck break; 301c2c66affSColin Finck 302c2c66affSColin Finck default: 303c2c66affSColin Finck 304c2c66affSColin Finck Status = AE_BAD_PARAMETER; 305c2c66affSColin Finck break; 306c2c66affSColin Finck } 307c2c66affSColin Finck 308c2c66affSColin Finck UnlockAndExit: 309c2c66affSColin Finck AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 310c2c66affSColin Finck return_ACPI_STATUS (Status); 311c2c66affSColin Finck } 312c2c66affSColin Finck 313c2c66affSColin Finck ACPI_EXPORT_SYMBOL (AcpiSetGpe) 314c2c66affSColin Finck 315c2c66affSColin Finck 316c2c66affSColin Finck /******************************************************************************* 317c2c66affSColin Finck * 318c2c66affSColin Finck * FUNCTION: AcpiMaskGpe 319c2c66affSColin Finck * 320c2c66affSColin Finck * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1 321c2c66affSColin Finck * GpeNumber - GPE level within the GPE block 322c2c66affSColin Finck * IsMasked - Whether the GPE is masked or not 323c2c66affSColin Finck * 324c2c66affSColin Finck * RETURN: Status 325c2c66affSColin Finck * 326c2c66affSColin Finck * DESCRIPTION: Unconditionally mask/unmask the an individual GPE, ex., to 327c2c66affSColin Finck * prevent a GPE flooding. 328c2c66affSColin Finck * 329c2c66affSColin Finck ******************************************************************************/ 330c2c66affSColin Finck 331c2c66affSColin Finck ACPI_STATUS 332c2c66affSColin Finck AcpiMaskGpe ( 333c2c66affSColin Finck ACPI_HANDLE GpeDevice, 334c2c66affSColin Finck UINT32 GpeNumber, 335c2c66affSColin Finck BOOLEAN IsMasked) 336c2c66affSColin Finck { 337c2c66affSColin Finck ACPI_GPE_EVENT_INFO *GpeEventInfo; 338c2c66affSColin Finck ACPI_STATUS Status; 339c2c66affSColin Finck ACPI_CPU_FLAGS Flags; 340c2c66affSColin Finck 341c2c66affSColin Finck 342c2c66affSColin Finck ACPI_FUNCTION_TRACE (AcpiMaskGpe); 343c2c66affSColin Finck 344c2c66affSColin Finck 345c2c66affSColin Finck Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 346c2c66affSColin Finck 347c2c66affSColin Finck /* Ensure that we have a valid GPE number */ 348c2c66affSColin Finck 349c2c66affSColin Finck GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 350c2c66affSColin Finck if (!GpeEventInfo) 351c2c66affSColin Finck { 352c2c66affSColin Finck Status = AE_BAD_PARAMETER; 353c2c66affSColin Finck goto UnlockAndExit; 354c2c66affSColin Finck } 355c2c66affSColin Finck 356c2c66affSColin Finck Status = AcpiEvMaskGpe (GpeEventInfo, IsMasked); 357c2c66affSColin Finck 358c2c66affSColin Finck UnlockAndExit: 359c2c66affSColin Finck AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 360c2c66affSColin Finck return_ACPI_STATUS (Status); 361c2c66affSColin Finck } 362c2c66affSColin Finck 363c2c66affSColin Finck ACPI_EXPORT_SYMBOL (AcpiMaskGpe) 364c2c66affSColin Finck 365c2c66affSColin Finck 366c2c66affSColin Finck /******************************************************************************* 367c2c66affSColin Finck * 368c2c66affSColin Finck * FUNCTION: AcpiMarkGpeForWake 369c2c66affSColin Finck * 370c2c66affSColin Finck * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1 371c2c66affSColin Finck * GpeNumber - GPE level within the GPE block 372c2c66affSColin Finck * 373c2c66affSColin Finck * RETURN: Status 374c2c66affSColin Finck * 375c2c66affSColin Finck * DESCRIPTION: Mark a GPE as having the ability to wake the system. Simply 376c2c66affSColin Finck * sets the ACPI_GPE_CAN_WAKE flag. 377c2c66affSColin Finck * 378c2c66affSColin Finck * Some potential callers of AcpiSetupGpeForWake may know in advance that 379c2c66affSColin Finck * there won't be any notify handlers installed for device wake notifications 380c2c66affSColin Finck * from the given GPE (one example is a button GPE in Linux). For these cases, 381c2c66affSColin Finck * AcpiMarkGpeForWake should be used instead of AcpiSetupGpeForWake. 382c2c66affSColin Finck * This will set the ACPI_GPE_CAN_WAKE flag for the GPE without trying to 383c2c66affSColin Finck * setup implicit wake notification for it (since there's no handler method). 384c2c66affSColin Finck * 385c2c66affSColin Finck ******************************************************************************/ 386c2c66affSColin Finck 387c2c66affSColin Finck ACPI_STATUS 388c2c66affSColin Finck AcpiMarkGpeForWake ( 389c2c66affSColin Finck ACPI_HANDLE GpeDevice, 390c2c66affSColin Finck UINT32 GpeNumber) 391c2c66affSColin Finck { 392c2c66affSColin Finck ACPI_GPE_EVENT_INFO *GpeEventInfo; 393c2c66affSColin Finck ACPI_STATUS Status = AE_BAD_PARAMETER; 394c2c66affSColin Finck ACPI_CPU_FLAGS Flags; 395c2c66affSColin Finck 396c2c66affSColin Finck 397c2c66affSColin Finck ACPI_FUNCTION_TRACE (AcpiMarkGpeForWake); 398c2c66affSColin Finck 399c2c66affSColin Finck 400c2c66affSColin Finck Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 401c2c66affSColin Finck 402c2c66affSColin Finck /* Ensure that we have a valid GPE number */ 403c2c66affSColin Finck 404c2c66affSColin Finck GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 405c2c66affSColin Finck if (GpeEventInfo) 406c2c66affSColin Finck { 407c2c66affSColin Finck /* Mark the GPE as a possible wake event */ 408c2c66affSColin Finck 409c2c66affSColin Finck GpeEventInfo->Flags |= ACPI_GPE_CAN_WAKE; 410c2c66affSColin Finck Status = AE_OK; 411c2c66affSColin Finck } 412c2c66affSColin Finck 413c2c66affSColin Finck AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 414c2c66affSColin Finck return_ACPI_STATUS (Status); 415c2c66affSColin Finck } 416c2c66affSColin Finck 417c2c66affSColin Finck ACPI_EXPORT_SYMBOL (AcpiMarkGpeForWake) 418c2c66affSColin Finck 419c2c66affSColin Finck 420c2c66affSColin Finck /******************************************************************************* 421c2c66affSColin Finck * 422c2c66affSColin Finck * FUNCTION: AcpiSetupGpeForWake 423c2c66affSColin Finck * 424c2c66affSColin Finck * PARAMETERS: WakeDevice - Device associated with the GPE (via _PRW) 425c2c66affSColin Finck * GpeDevice - Parent GPE Device. NULL for GPE0/GPE1 426c2c66affSColin Finck * GpeNumber - GPE level within the GPE block 427c2c66affSColin Finck * 428c2c66affSColin Finck * RETURN: Status 429c2c66affSColin Finck * 430c2c66affSColin Finck * DESCRIPTION: Mark a GPE as having the ability to wake the system. This 431c2c66affSColin Finck * interface is intended to be used as the host executes the 432c2c66affSColin Finck * _PRW methods (Power Resources for Wake) in the system tables. 433c2c66affSColin Finck * Each _PRW appears under a Device Object (The WakeDevice), and 434c2c66affSColin Finck * contains the info for the wake GPE associated with the 435c2c66affSColin Finck * WakeDevice. 436c2c66affSColin Finck * 437c2c66affSColin Finck ******************************************************************************/ 438c2c66affSColin Finck 439c2c66affSColin Finck ACPI_STATUS 440c2c66affSColin Finck AcpiSetupGpeForWake ( 441c2c66affSColin Finck ACPI_HANDLE WakeDevice, 442c2c66affSColin Finck ACPI_HANDLE GpeDevice, 443c2c66affSColin Finck UINT32 GpeNumber) 444c2c66affSColin Finck { 445c2c66affSColin Finck ACPI_STATUS Status; 446c2c66affSColin Finck ACPI_GPE_EVENT_INFO *GpeEventInfo; 447c2c66affSColin Finck ACPI_NAMESPACE_NODE *DeviceNode; 448c2c66affSColin Finck ACPI_GPE_NOTIFY_INFO *Notify; 449c2c66affSColin Finck ACPI_GPE_NOTIFY_INFO *NewNotify; 450c2c66affSColin Finck ACPI_CPU_FLAGS Flags; 451c2c66affSColin Finck 452c2c66affSColin Finck 453c2c66affSColin Finck ACPI_FUNCTION_TRACE (AcpiSetupGpeForWake); 454c2c66affSColin Finck 455c2c66affSColin Finck 456c2c66affSColin Finck /* Parameter Validation */ 457c2c66affSColin Finck 458c2c66affSColin Finck if (!WakeDevice) 459c2c66affSColin Finck { 460c2c66affSColin Finck /* 461c2c66affSColin Finck * By forcing WakeDevice to be valid, we automatically enable the 462c2c66affSColin Finck * implicit notify feature on all hosts. 463c2c66affSColin Finck */ 464c2c66affSColin Finck return_ACPI_STATUS (AE_BAD_PARAMETER); 465c2c66affSColin Finck } 466c2c66affSColin Finck 467c2c66affSColin Finck /* Handle root object case */ 468c2c66affSColin Finck 469c2c66affSColin Finck if (WakeDevice == ACPI_ROOT_OBJECT) 470c2c66affSColin Finck { 471c2c66affSColin Finck DeviceNode = AcpiGbl_RootNode; 472c2c66affSColin Finck } 473c2c66affSColin Finck else 474c2c66affSColin Finck { 475c2c66affSColin Finck DeviceNode = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, WakeDevice); 476c2c66affSColin Finck } 477c2c66affSColin Finck 478c2c66affSColin Finck /* Validate WakeDevice is of type Device */ 479c2c66affSColin Finck 480c2c66affSColin Finck if (DeviceNode->Type != ACPI_TYPE_DEVICE) 481c2c66affSColin Finck { 482c2c66affSColin Finck return_ACPI_STATUS (AE_BAD_PARAMETER); 483c2c66affSColin Finck } 484c2c66affSColin Finck 485c2c66affSColin Finck /* 486c2c66affSColin Finck * Allocate a new notify object up front, in case it is needed. 487c2c66affSColin Finck * Memory allocation while holding a spinlock is a big no-no 488c2c66affSColin Finck * on some hosts. 489c2c66affSColin Finck */ 490c2c66affSColin Finck NewNotify = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_GPE_NOTIFY_INFO)); 491c2c66affSColin Finck if (!NewNotify) 492c2c66affSColin Finck { 493c2c66affSColin Finck return_ACPI_STATUS (AE_NO_MEMORY); 494c2c66affSColin Finck } 495c2c66affSColin Finck 496c2c66affSColin Finck Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 497c2c66affSColin Finck 498c2c66affSColin Finck /* Ensure that we have a valid GPE number */ 499c2c66affSColin Finck 500c2c66affSColin Finck GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 501c2c66affSColin Finck if (!GpeEventInfo) 502c2c66affSColin Finck { 503c2c66affSColin Finck Status = AE_BAD_PARAMETER; 504c2c66affSColin Finck goto UnlockAndExit; 505c2c66affSColin Finck } 506c2c66affSColin Finck 507c2c66affSColin Finck /* 508c2c66affSColin Finck * If there is no method or handler for this GPE, then the 509c2c66affSColin Finck * WakeDevice will be notified whenever this GPE fires. This is 510c2c66affSColin Finck * known as an "implicit notify". Note: The GPE is assumed to be 511c2c66affSColin Finck * level-triggered (for windows compatibility). 512c2c66affSColin Finck */ 513c2c66affSColin Finck if (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) == 514c2c66affSColin Finck ACPI_GPE_DISPATCH_NONE) 515c2c66affSColin Finck { 516c2c66affSColin Finck /* 517c2c66affSColin Finck * This is the first device for implicit notify on this GPE. 518c2c66affSColin Finck * Just set the flags here, and enter the NOTIFY block below. 519c2c66affSColin Finck */ 520c2c66affSColin Finck GpeEventInfo->Flags = 521c2c66affSColin Finck (ACPI_GPE_DISPATCH_NOTIFY | ACPI_GPE_LEVEL_TRIGGERED); 522c2c66affSColin Finck } 5236847cc3aSThomas Faber else if (GpeEventInfo->Flags & ACPI_GPE_AUTO_ENABLED) 5246847cc3aSThomas Faber { 5256847cc3aSThomas Faber /* 5266847cc3aSThomas Faber * A reference to this GPE has been added during the GPE block 5276847cc3aSThomas Faber * initialization, so drop it now to prevent the GPE from being 5286847cc3aSThomas Faber * permanently enabled and clear its ACPI_GPE_AUTO_ENABLED flag. 5296847cc3aSThomas Faber */ 5306847cc3aSThomas Faber (void) AcpiEvRemoveGpeReference (GpeEventInfo); 5316847cc3aSThomas Faber GpeEventInfo->Flags &= ~~ACPI_GPE_AUTO_ENABLED; 5326847cc3aSThomas Faber } 533c2c66affSColin Finck 534c2c66affSColin Finck /* 535c2c66affSColin Finck * If we already have an implicit notify on this GPE, add 536c2c66affSColin Finck * this device to the notify list. 537c2c66affSColin Finck */ 538c2c66affSColin Finck if (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) == 539c2c66affSColin Finck ACPI_GPE_DISPATCH_NOTIFY) 540c2c66affSColin Finck { 541c2c66affSColin Finck /* Ensure that the device is not already in the list */ 542c2c66affSColin Finck 543c2c66affSColin Finck Notify = GpeEventInfo->Dispatch.NotifyList; 544c2c66affSColin Finck while (Notify) 545c2c66affSColin Finck { 546c2c66affSColin Finck if (Notify->DeviceNode == DeviceNode) 547c2c66affSColin Finck { 548c2c66affSColin Finck Status = AE_ALREADY_EXISTS; 549c2c66affSColin Finck goto UnlockAndExit; 550c2c66affSColin Finck } 551c2c66affSColin Finck Notify = Notify->Next; 552c2c66affSColin Finck } 553c2c66affSColin Finck 554c2c66affSColin Finck /* Add this device to the notify list for this GPE */ 555c2c66affSColin Finck 556c2c66affSColin Finck NewNotify->DeviceNode = DeviceNode; 557c2c66affSColin Finck NewNotify->Next = GpeEventInfo->Dispatch.NotifyList; 558c2c66affSColin Finck GpeEventInfo->Dispatch.NotifyList = NewNotify; 559c2c66affSColin Finck NewNotify = NULL; 560c2c66affSColin Finck } 561c2c66affSColin Finck 562c2c66affSColin Finck /* Mark the GPE as a possible wake event */ 563c2c66affSColin Finck 564c2c66affSColin Finck GpeEventInfo->Flags |= ACPI_GPE_CAN_WAKE; 565c2c66affSColin Finck Status = AE_OK; 566c2c66affSColin Finck 567c2c66affSColin Finck 568c2c66affSColin Finck UnlockAndExit: 569c2c66affSColin Finck AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 570c2c66affSColin Finck 571c2c66affSColin Finck /* Delete the notify object if it was not used above */ 572c2c66affSColin Finck 573c2c66affSColin Finck if (NewNotify) 574c2c66affSColin Finck { 575c2c66affSColin Finck ACPI_FREE (NewNotify); 576c2c66affSColin Finck } 577c2c66affSColin Finck return_ACPI_STATUS (Status); 578c2c66affSColin Finck } 579c2c66affSColin Finck 580c2c66affSColin Finck ACPI_EXPORT_SYMBOL (AcpiSetupGpeForWake) 581c2c66affSColin Finck 582c2c66affSColin Finck 583c2c66affSColin Finck /******************************************************************************* 584c2c66affSColin Finck * 585c2c66affSColin Finck * FUNCTION: AcpiSetGpeWakeMask 586c2c66affSColin Finck * 587c2c66affSColin Finck * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1 588c2c66affSColin Finck * GpeNumber - GPE level within the GPE block 589c2c66affSColin Finck * Action - Enable or Disable 590c2c66affSColin Finck * 591c2c66affSColin Finck * RETURN: Status 592c2c66affSColin Finck * 593c2c66affSColin Finck * DESCRIPTION: Set or clear the GPE's wakeup enable mask bit. The GPE must 594c2c66affSColin Finck * already be marked as a WAKE GPE. 595c2c66affSColin Finck * 596c2c66affSColin Finck ******************************************************************************/ 597c2c66affSColin Finck 598c2c66affSColin Finck ACPI_STATUS 599c2c66affSColin Finck AcpiSetGpeWakeMask ( 600c2c66affSColin Finck ACPI_HANDLE GpeDevice, 601c2c66affSColin Finck UINT32 GpeNumber, 602c2c66affSColin Finck UINT8 Action) 603c2c66affSColin Finck { 604c2c66affSColin Finck ACPI_STATUS Status = AE_OK; 605c2c66affSColin Finck ACPI_GPE_EVENT_INFO *GpeEventInfo; 606c2c66affSColin Finck ACPI_GPE_REGISTER_INFO *GpeRegisterInfo; 607c2c66affSColin Finck ACPI_CPU_FLAGS Flags; 608c2c66affSColin Finck UINT32 RegisterBit; 609c2c66affSColin Finck 610c2c66affSColin Finck 611c2c66affSColin Finck ACPI_FUNCTION_TRACE (AcpiSetGpeWakeMask); 612c2c66affSColin Finck 613c2c66affSColin Finck 614c2c66affSColin Finck Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 615c2c66affSColin Finck 616c2c66affSColin Finck /* 617c2c66affSColin Finck * Ensure that we have a valid GPE number and that this GPE is in 618c2c66affSColin Finck * fact a wake GPE 619c2c66affSColin Finck */ 620c2c66affSColin Finck GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 621c2c66affSColin Finck if (!GpeEventInfo) 622c2c66affSColin Finck { 623c2c66affSColin Finck Status = AE_BAD_PARAMETER; 624c2c66affSColin Finck goto UnlockAndExit; 625c2c66affSColin Finck } 626c2c66affSColin Finck 627c2c66affSColin Finck if (!(GpeEventInfo->Flags & ACPI_GPE_CAN_WAKE)) 628c2c66affSColin Finck { 629c2c66affSColin Finck Status = AE_TYPE; 630c2c66affSColin Finck goto UnlockAndExit; 631c2c66affSColin Finck } 632c2c66affSColin Finck 633c2c66affSColin Finck GpeRegisterInfo = GpeEventInfo->RegisterInfo; 634c2c66affSColin Finck if (!GpeRegisterInfo) 635c2c66affSColin Finck { 636c2c66affSColin Finck Status = AE_NOT_EXIST; 637c2c66affSColin Finck goto UnlockAndExit; 638c2c66affSColin Finck } 639c2c66affSColin Finck 640c2c66affSColin Finck RegisterBit = AcpiHwGetGpeRegisterBit (GpeEventInfo); 641c2c66affSColin Finck 642c2c66affSColin Finck /* Perform the action */ 643c2c66affSColin Finck 644c2c66affSColin Finck switch (Action) 645c2c66affSColin Finck { 646c2c66affSColin Finck case ACPI_GPE_ENABLE: 647c2c66affSColin Finck 648c2c66affSColin Finck ACPI_SET_BIT (GpeRegisterInfo->EnableForWake, (UINT8) RegisterBit); 649c2c66affSColin Finck break; 650c2c66affSColin Finck 651c2c66affSColin Finck case ACPI_GPE_DISABLE: 652c2c66affSColin Finck 653c2c66affSColin Finck ACPI_CLEAR_BIT (GpeRegisterInfo->EnableForWake, (UINT8) RegisterBit); 654c2c66affSColin Finck break; 655c2c66affSColin Finck 656c2c66affSColin Finck default: 657c2c66affSColin Finck 658c2c66affSColin Finck ACPI_ERROR ((AE_INFO, "%u, Invalid action", Action)); 659c2c66affSColin Finck Status = AE_BAD_PARAMETER; 660c2c66affSColin Finck break; 661c2c66affSColin Finck } 662c2c66affSColin Finck 663c2c66affSColin Finck UnlockAndExit: 664c2c66affSColin Finck AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 665c2c66affSColin Finck return_ACPI_STATUS (Status); 666c2c66affSColin Finck } 667c2c66affSColin Finck 668c2c66affSColin Finck ACPI_EXPORT_SYMBOL (AcpiSetGpeWakeMask) 669c2c66affSColin Finck 670c2c66affSColin Finck 671c2c66affSColin Finck /******************************************************************************* 672c2c66affSColin Finck * 673c2c66affSColin Finck * FUNCTION: AcpiClearGpe 674c2c66affSColin Finck * 675c2c66affSColin Finck * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1 676c2c66affSColin Finck * GpeNumber - GPE level within the GPE block 677c2c66affSColin Finck * 678c2c66affSColin Finck * RETURN: Status 679c2c66affSColin Finck * 680c2c66affSColin Finck * DESCRIPTION: Clear an ACPI event (general purpose) 681c2c66affSColin Finck * 682c2c66affSColin Finck ******************************************************************************/ 683c2c66affSColin Finck 684c2c66affSColin Finck ACPI_STATUS 685c2c66affSColin Finck AcpiClearGpe ( 686c2c66affSColin Finck ACPI_HANDLE GpeDevice, 687c2c66affSColin Finck UINT32 GpeNumber) 688c2c66affSColin Finck { 689c2c66affSColin Finck ACPI_STATUS Status = AE_OK; 690c2c66affSColin Finck ACPI_GPE_EVENT_INFO *GpeEventInfo; 691c2c66affSColin Finck ACPI_CPU_FLAGS Flags; 692c2c66affSColin Finck 693c2c66affSColin Finck 694c2c66affSColin Finck ACPI_FUNCTION_TRACE (AcpiClearGpe); 695c2c66affSColin Finck 696c2c66affSColin Finck 697c2c66affSColin Finck Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 698c2c66affSColin Finck 699c2c66affSColin Finck /* Ensure that we have a valid GPE number */ 700c2c66affSColin Finck 701c2c66affSColin Finck GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 702c2c66affSColin Finck if (!GpeEventInfo) 703c2c66affSColin Finck { 704c2c66affSColin Finck Status = AE_BAD_PARAMETER; 705c2c66affSColin Finck goto UnlockAndExit; 706c2c66affSColin Finck } 707c2c66affSColin Finck 708c2c66affSColin Finck Status = AcpiHwClearGpe (GpeEventInfo); 709c2c66affSColin Finck 710c2c66affSColin Finck UnlockAndExit: 711c2c66affSColin Finck AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 712c2c66affSColin Finck return_ACPI_STATUS (Status); 713c2c66affSColin Finck } 714c2c66affSColin Finck 715c2c66affSColin Finck ACPI_EXPORT_SYMBOL (AcpiClearGpe) 716c2c66affSColin Finck 717c2c66affSColin Finck 718c2c66affSColin Finck /******************************************************************************* 719c2c66affSColin Finck * 720c2c66affSColin Finck * FUNCTION: AcpiGetGpeStatus 721c2c66affSColin Finck * 722c2c66affSColin Finck * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1 723c2c66affSColin Finck * GpeNumber - GPE level within the GPE block 724c2c66affSColin Finck * EventStatus - Where the current status of the event 725c2c66affSColin Finck * will be returned 726c2c66affSColin Finck * 727c2c66affSColin Finck * RETURN: Status 728c2c66affSColin Finck * 729c2c66affSColin Finck * DESCRIPTION: Get the current status of a GPE (signalled/not_signalled) 730c2c66affSColin Finck * 731c2c66affSColin Finck ******************************************************************************/ 732c2c66affSColin Finck 733c2c66affSColin Finck ACPI_STATUS 734c2c66affSColin Finck AcpiGetGpeStatus ( 735c2c66affSColin Finck ACPI_HANDLE GpeDevice, 736c2c66affSColin Finck UINT32 GpeNumber, 737c2c66affSColin Finck ACPI_EVENT_STATUS *EventStatus) 738c2c66affSColin Finck { 739c2c66affSColin Finck ACPI_STATUS Status = AE_OK; 740c2c66affSColin Finck ACPI_GPE_EVENT_INFO *GpeEventInfo; 741c2c66affSColin Finck ACPI_CPU_FLAGS Flags; 742c2c66affSColin Finck 743c2c66affSColin Finck 744c2c66affSColin Finck ACPI_FUNCTION_TRACE (AcpiGetGpeStatus); 745c2c66affSColin Finck 746c2c66affSColin Finck 747c2c66affSColin Finck Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 748c2c66affSColin Finck 749c2c66affSColin Finck /* Ensure that we have a valid GPE number */ 750c2c66affSColin Finck 751c2c66affSColin Finck GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 752c2c66affSColin Finck if (!GpeEventInfo) 753c2c66affSColin Finck { 754c2c66affSColin Finck Status = AE_BAD_PARAMETER; 755c2c66affSColin Finck goto UnlockAndExit; 756c2c66affSColin Finck } 757c2c66affSColin Finck 758c2c66affSColin Finck /* Obtain status on the requested GPE number */ 759c2c66affSColin Finck 760c2c66affSColin Finck Status = AcpiHwGetGpeStatus (GpeEventInfo, EventStatus); 761c2c66affSColin Finck 762c2c66affSColin Finck UnlockAndExit: 763c2c66affSColin Finck AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 764c2c66affSColin Finck return_ACPI_STATUS (Status); 765c2c66affSColin Finck } 766c2c66affSColin Finck 767c2c66affSColin Finck ACPI_EXPORT_SYMBOL (AcpiGetGpeStatus) 768c2c66affSColin Finck 769c2c66affSColin Finck 770c2c66affSColin Finck /******************************************************************************* 771c2c66affSColin Finck * 772c2c66affSColin Finck * FUNCTION: AcpiFinishGpe 773c2c66affSColin Finck * 774c2c66affSColin Finck * PARAMETERS: GpeDevice - Namespace node for the GPE Block 775c2c66affSColin Finck * (NULL for FADT defined GPEs) 776c2c66affSColin Finck * GpeNumber - GPE level within the GPE block 777c2c66affSColin Finck * 778c2c66affSColin Finck * RETURN: Status 779c2c66affSColin Finck * 780*9d53c935SThomas Faber * DESCRIPTION: Clear and conditionally re-enable a GPE. This completes the GPE 781c2c66affSColin Finck * processing. Intended for use by asynchronous host-installed 782*9d53c935SThomas Faber * GPE handlers. The GPE is only re-enabled if the EnableForRun bit 783c2c66affSColin Finck * is set in the GPE info. 784c2c66affSColin Finck * 785c2c66affSColin Finck ******************************************************************************/ 786c2c66affSColin Finck 787c2c66affSColin Finck ACPI_STATUS 788c2c66affSColin Finck AcpiFinishGpe ( 789c2c66affSColin Finck ACPI_HANDLE GpeDevice, 790c2c66affSColin Finck UINT32 GpeNumber) 791c2c66affSColin Finck { 792c2c66affSColin Finck ACPI_GPE_EVENT_INFO *GpeEventInfo; 793c2c66affSColin Finck ACPI_STATUS Status; 794c2c66affSColin Finck ACPI_CPU_FLAGS Flags; 795c2c66affSColin Finck 796c2c66affSColin Finck 797c2c66affSColin Finck ACPI_FUNCTION_TRACE (AcpiFinishGpe); 798c2c66affSColin Finck 799c2c66affSColin Finck 800c2c66affSColin Finck Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 801c2c66affSColin Finck 802c2c66affSColin Finck /* Ensure that we have a valid GPE number */ 803c2c66affSColin Finck 804c2c66affSColin Finck GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 805c2c66affSColin Finck if (!GpeEventInfo) 806c2c66affSColin Finck { 807c2c66affSColin Finck Status = AE_BAD_PARAMETER; 808c2c66affSColin Finck goto UnlockAndExit; 809c2c66affSColin Finck } 810c2c66affSColin Finck 811c2c66affSColin Finck Status = AcpiEvFinishGpe (GpeEventInfo); 812c2c66affSColin Finck 813c2c66affSColin Finck UnlockAndExit: 814c2c66affSColin Finck AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 815c2c66affSColin Finck return_ACPI_STATUS (Status); 816c2c66affSColin Finck } 817c2c66affSColin Finck 818c2c66affSColin Finck ACPI_EXPORT_SYMBOL (AcpiFinishGpe) 819c2c66affSColin Finck 820c2c66affSColin Finck 821c2c66affSColin Finck /****************************************************************************** 822c2c66affSColin Finck * 823c2c66affSColin Finck * FUNCTION: AcpiDisableAllGpes 824c2c66affSColin Finck * 825c2c66affSColin Finck * PARAMETERS: None 826c2c66affSColin Finck * 827c2c66affSColin Finck * RETURN: Status 828c2c66affSColin Finck * 829c2c66affSColin Finck * DESCRIPTION: Disable and clear all GPEs in all GPE blocks 830c2c66affSColin Finck * 831c2c66affSColin Finck ******************************************************************************/ 832c2c66affSColin Finck 833c2c66affSColin Finck ACPI_STATUS 834c2c66affSColin Finck AcpiDisableAllGpes ( 835c2c66affSColin Finck void) 836c2c66affSColin Finck { 837c2c66affSColin Finck ACPI_STATUS Status; 838c2c66affSColin Finck 839c2c66affSColin Finck 840c2c66affSColin Finck ACPI_FUNCTION_TRACE (AcpiDisableAllGpes); 841c2c66affSColin Finck 842c2c66affSColin Finck 843c2c66affSColin Finck Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 844c2c66affSColin Finck if (ACPI_FAILURE (Status)) 845c2c66affSColin Finck { 846c2c66affSColin Finck return_ACPI_STATUS (Status); 847c2c66affSColin Finck } 848c2c66affSColin Finck 849c2c66affSColin Finck Status = AcpiHwDisableAllGpes (); 850c2c66affSColin Finck (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 851c2c66affSColin Finck 852c2c66affSColin Finck return_ACPI_STATUS (Status); 853c2c66affSColin Finck } 854c2c66affSColin Finck 855c2c66affSColin Finck ACPI_EXPORT_SYMBOL (AcpiDisableAllGpes) 856c2c66affSColin Finck 857c2c66affSColin Finck 858c2c66affSColin Finck /****************************************************************************** 859c2c66affSColin Finck * 860c2c66affSColin Finck * FUNCTION: AcpiEnableAllRuntimeGpes 861c2c66affSColin Finck * 862c2c66affSColin Finck * PARAMETERS: None 863c2c66affSColin Finck * 864c2c66affSColin Finck * RETURN: Status 865c2c66affSColin Finck * 866c2c66affSColin Finck * DESCRIPTION: Enable all "runtime" GPEs, in all GPE blocks 867c2c66affSColin Finck * 868c2c66affSColin Finck ******************************************************************************/ 869c2c66affSColin Finck 870c2c66affSColin Finck ACPI_STATUS 871c2c66affSColin Finck AcpiEnableAllRuntimeGpes ( 872c2c66affSColin Finck void) 873c2c66affSColin Finck { 874c2c66affSColin Finck ACPI_STATUS Status; 875c2c66affSColin Finck 876c2c66affSColin Finck 877c2c66affSColin Finck ACPI_FUNCTION_TRACE (AcpiEnableAllRuntimeGpes); 878c2c66affSColin Finck 879c2c66affSColin Finck 880c2c66affSColin Finck Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 881c2c66affSColin Finck if (ACPI_FAILURE (Status)) 882c2c66affSColin Finck { 883c2c66affSColin Finck return_ACPI_STATUS (Status); 884c2c66affSColin Finck } 885c2c66affSColin Finck 886c2c66affSColin Finck Status = AcpiHwEnableAllRuntimeGpes (); 887c2c66affSColin Finck (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 888c2c66affSColin Finck 889c2c66affSColin Finck return_ACPI_STATUS (Status); 890c2c66affSColin Finck } 891c2c66affSColin Finck 892c2c66affSColin Finck ACPI_EXPORT_SYMBOL (AcpiEnableAllRuntimeGpes) 893c2c66affSColin Finck 894c2c66affSColin Finck 895c2c66affSColin Finck /****************************************************************************** 896c2c66affSColin Finck * 897c2c66affSColin Finck * FUNCTION: AcpiEnableAllWakeupGpes 898c2c66affSColin Finck * 899c2c66affSColin Finck * PARAMETERS: None 900c2c66affSColin Finck * 901c2c66affSColin Finck * RETURN: Status 902c2c66affSColin Finck * 903c2c66affSColin Finck * DESCRIPTION: Enable all "wakeup" GPEs and disable all of the other GPEs, in 904c2c66affSColin Finck * all GPE blocks. 905c2c66affSColin Finck * 906c2c66affSColin Finck ******************************************************************************/ 907c2c66affSColin Finck 908c2c66affSColin Finck ACPI_STATUS 909c2c66affSColin Finck AcpiEnableAllWakeupGpes ( 910c2c66affSColin Finck void) 911c2c66affSColin Finck { 912c2c66affSColin Finck ACPI_STATUS Status; 913c2c66affSColin Finck 914c2c66affSColin Finck 915c2c66affSColin Finck ACPI_FUNCTION_TRACE (AcpiEnableAllWakeupGpes); 916c2c66affSColin Finck 917c2c66affSColin Finck 918c2c66affSColin Finck Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 919c2c66affSColin Finck if (ACPI_FAILURE (Status)) 920c2c66affSColin Finck { 921c2c66affSColin Finck return_ACPI_STATUS (Status); 922c2c66affSColin Finck } 923c2c66affSColin Finck 924c2c66affSColin Finck Status = AcpiHwEnableAllWakeupGpes (); 925c2c66affSColin Finck (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 926c2c66affSColin Finck 927c2c66affSColin Finck return_ACPI_STATUS (Status); 928c2c66affSColin Finck } 929c2c66affSColin Finck 930c2c66affSColin Finck ACPI_EXPORT_SYMBOL (AcpiEnableAllWakeupGpes) 931c2c66affSColin Finck 932c2c66affSColin Finck 933c2c66affSColin Finck /******************************************************************************* 934c2c66affSColin Finck * 935c2c66affSColin Finck * FUNCTION: AcpiInstallGpeBlock 936c2c66affSColin Finck * 937c2c66affSColin Finck * PARAMETERS: GpeDevice - Handle to the parent GPE Block Device 938c2c66affSColin Finck * GpeBlockAddress - Address and SpaceID 939c2c66affSColin Finck * RegisterCount - Number of GPE register pairs in the block 940c2c66affSColin Finck * InterruptNumber - H/W interrupt for the block 941c2c66affSColin Finck * 942c2c66affSColin Finck * RETURN: Status 943c2c66affSColin Finck * 944c2c66affSColin Finck * DESCRIPTION: Create and Install a block of GPE registers. The GPEs are not 945c2c66affSColin Finck * enabled here. 946c2c66affSColin Finck * 947c2c66affSColin Finck ******************************************************************************/ 948c2c66affSColin Finck 949c2c66affSColin Finck ACPI_STATUS 950c2c66affSColin Finck AcpiInstallGpeBlock ( 951c2c66affSColin Finck ACPI_HANDLE GpeDevice, 952c2c66affSColin Finck ACPI_GENERIC_ADDRESS *GpeBlockAddress, 953c2c66affSColin Finck UINT32 RegisterCount, 954c2c66affSColin Finck UINT32 InterruptNumber) 955c2c66affSColin Finck { 956c2c66affSColin Finck ACPI_STATUS Status; 957c2c66affSColin Finck ACPI_OPERAND_OBJECT *ObjDesc; 958c2c66affSColin Finck ACPI_NAMESPACE_NODE *Node; 959c2c66affSColin Finck ACPI_GPE_BLOCK_INFO *GpeBlock; 960c2c66affSColin Finck 961c2c66affSColin Finck 962c2c66affSColin Finck ACPI_FUNCTION_TRACE (AcpiInstallGpeBlock); 963c2c66affSColin Finck 964c2c66affSColin Finck 965c2c66affSColin Finck if ((!GpeDevice) || 966c2c66affSColin Finck (!GpeBlockAddress) || 967c2c66affSColin Finck (!RegisterCount)) 968c2c66affSColin Finck { 969c2c66affSColin Finck return_ACPI_STATUS (AE_BAD_PARAMETER); 970c2c66affSColin Finck } 971c2c66affSColin Finck 972c2c66affSColin Finck Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 973c2c66affSColin Finck if (ACPI_FAILURE (Status)) 974c2c66affSColin Finck { 975c2c66affSColin Finck return_ACPI_STATUS (Status); 976c2c66affSColin Finck } 977c2c66affSColin Finck 978c2c66affSColin Finck Node = AcpiNsValidateHandle (GpeDevice); 979c2c66affSColin Finck if (!Node) 980c2c66affSColin Finck { 981c2c66affSColin Finck Status = AE_BAD_PARAMETER; 982c2c66affSColin Finck goto UnlockAndExit; 983c2c66affSColin Finck } 984c2c66affSColin Finck 985c2c66affSColin Finck /* Validate the parent device */ 986c2c66affSColin Finck 987c2c66affSColin Finck if (Node->Type != ACPI_TYPE_DEVICE) 988c2c66affSColin Finck { 989c2c66affSColin Finck Status = AE_TYPE; 990c2c66affSColin Finck goto UnlockAndExit; 991c2c66affSColin Finck } 992c2c66affSColin Finck 993c2c66affSColin Finck if (Node->Object) 994c2c66affSColin Finck { 995c2c66affSColin Finck Status = AE_ALREADY_EXISTS; 996c2c66affSColin Finck goto UnlockAndExit; 997c2c66affSColin Finck } 998c2c66affSColin Finck 999c2c66affSColin Finck /* 1000c2c66affSColin Finck * For user-installed GPE Block Devices, the GpeBlockBaseNumber 1001c2c66affSColin Finck * is always zero 1002c2c66affSColin Finck */ 1003c2c66affSColin Finck Status = AcpiEvCreateGpeBlock (Node, GpeBlockAddress->Address, 1004c2c66affSColin Finck GpeBlockAddress->SpaceId, RegisterCount, 1005c2c66affSColin Finck 0, InterruptNumber, &GpeBlock); 1006c2c66affSColin Finck if (ACPI_FAILURE (Status)) 1007c2c66affSColin Finck { 1008c2c66affSColin Finck goto UnlockAndExit; 1009c2c66affSColin Finck } 1010c2c66affSColin Finck 1011c2c66affSColin Finck /* Install block in the DeviceObject attached to the node */ 1012c2c66affSColin Finck 1013c2c66affSColin Finck ObjDesc = AcpiNsGetAttachedObject (Node); 1014c2c66affSColin Finck if (!ObjDesc) 1015c2c66affSColin Finck { 1016c2c66affSColin Finck /* 1017c2c66affSColin Finck * No object, create a new one (Device nodes do not always have 1018c2c66affSColin Finck * an attached object) 1019c2c66affSColin Finck */ 1020c2c66affSColin Finck ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_DEVICE); 1021c2c66affSColin Finck if (!ObjDesc) 1022c2c66affSColin Finck { 1023c2c66affSColin Finck Status = AE_NO_MEMORY; 1024c2c66affSColin Finck goto UnlockAndExit; 1025c2c66affSColin Finck } 1026c2c66affSColin Finck 1027c2c66affSColin Finck Status = AcpiNsAttachObject (Node, ObjDesc, ACPI_TYPE_DEVICE); 1028c2c66affSColin Finck 1029c2c66affSColin Finck /* Remove local reference to the object */ 1030c2c66affSColin Finck 1031c2c66affSColin Finck AcpiUtRemoveReference (ObjDesc); 1032c2c66affSColin Finck if (ACPI_FAILURE (Status)) 1033c2c66affSColin Finck { 1034c2c66affSColin Finck goto UnlockAndExit; 1035c2c66affSColin Finck } 1036c2c66affSColin Finck } 1037c2c66affSColin Finck 1038c2c66affSColin Finck /* Now install the GPE block in the DeviceObject */ 1039c2c66affSColin Finck 1040c2c66affSColin Finck ObjDesc->Device.GpeBlock = GpeBlock; 1041c2c66affSColin Finck 1042c2c66affSColin Finck 1043c2c66affSColin Finck UnlockAndExit: 1044c2c66affSColin Finck (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 1045c2c66affSColin Finck return_ACPI_STATUS (Status); 1046c2c66affSColin Finck } 1047c2c66affSColin Finck 1048c2c66affSColin Finck ACPI_EXPORT_SYMBOL (AcpiInstallGpeBlock) 1049c2c66affSColin Finck 1050c2c66affSColin Finck 1051c2c66affSColin Finck /******************************************************************************* 1052c2c66affSColin Finck * 1053c2c66affSColin Finck * FUNCTION: AcpiRemoveGpeBlock 1054c2c66affSColin Finck * 1055c2c66affSColin Finck * PARAMETERS: GpeDevice - Handle to the parent GPE Block Device 1056c2c66affSColin Finck * 1057c2c66affSColin Finck * RETURN: Status 1058c2c66affSColin Finck * 1059c2c66affSColin Finck * DESCRIPTION: Remove a previously installed block of GPE registers 1060c2c66affSColin Finck * 1061c2c66affSColin Finck ******************************************************************************/ 1062c2c66affSColin Finck 1063c2c66affSColin Finck ACPI_STATUS 1064c2c66affSColin Finck AcpiRemoveGpeBlock ( 1065c2c66affSColin Finck ACPI_HANDLE GpeDevice) 1066c2c66affSColin Finck { 1067c2c66affSColin Finck ACPI_OPERAND_OBJECT *ObjDesc; 1068c2c66affSColin Finck ACPI_STATUS Status; 1069c2c66affSColin Finck ACPI_NAMESPACE_NODE *Node; 1070c2c66affSColin Finck 1071c2c66affSColin Finck 1072c2c66affSColin Finck ACPI_FUNCTION_TRACE (AcpiRemoveGpeBlock); 1073c2c66affSColin Finck 1074c2c66affSColin Finck 1075c2c66affSColin Finck if (!GpeDevice) 1076c2c66affSColin Finck { 1077c2c66affSColin Finck return_ACPI_STATUS (AE_BAD_PARAMETER); 1078c2c66affSColin Finck } 1079c2c66affSColin Finck 1080c2c66affSColin Finck Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 1081c2c66affSColin Finck if (ACPI_FAILURE (Status)) 1082c2c66affSColin Finck { 1083c2c66affSColin Finck return_ACPI_STATUS (Status); 1084c2c66affSColin Finck } 1085c2c66affSColin Finck 1086c2c66affSColin Finck Node = AcpiNsValidateHandle (GpeDevice); 1087c2c66affSColin Finck if (!Node) 1088c2c66affSColin Finck { 1089c2c66affSColin Finck Status = AE_BAD_PARAMETER; 1090c2c66affSColin Finck goto UnlockAndExit; 1091c2c66affSColin Finck } 1092c2c66affSColin Finck 1093c2c66affSColin Finck /* Validate the parent device */ 1094c2c66affSColin Finck 1095c2c66affSColin Finck if (Node->Type != ACPI_TYPE_DEVICE) 1096c2c66affSColin Finck { 1097c2c66affSColin Finck Status = AE_TYPE; 1098c2c66affSColin Finck goto UnlockAndExit; 1099c2c66affSColin Finck } 1100c2c66affSColin Finck 1101c2c66affSColin Finck /* Get the DeviceObject attached to the node */ 1102c2c66affSColin Finck 1103c2c66affSColin Finck ObjDesc = AcpiNsGetAttachedObject (Node); 1104c2c66affSColin Finck if (!ObjDesc || 1105c2c66affSColin Finck !ObjDesc->Device.GpeBlock) 1106c2c66affSColin Finck { 1107c2c66affSColin Finck return_ACPI_STATUS (AE_NULL_OBJECT); 1108c2c66affSColin Finck } 1109c2c66affSColin Finck 1110c2c66affSColin Finck /* Delete the GPE block (but not the DeviceObject) */ 1111c2c66affSColin Finck 1112c2c66affSColin Finck Status = AcpiEvDeleteGpeBlock (ObjDesc->Device.GpeBlock); 1113c2c66affSColin Finck if (ACPI_SUCCESS (Status)) 1114c2c66affSColin Finck { 1115c2c66affSColin Finck ObjDesc->Device.GpeBlock = NULL; 1116c2c66affSColin Finck } 1117c2c66affSColin Finck 1118c2c66affSColin Finck UnlockAndExit: 1119c2c66affSColin Finck (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 1120c2c66affSColin Finck return_ACPI_STATUS (Status); 1121c2c66affSColin Finck } 1122c2c66affSColin Finck 1123c2c66affSColin Finck ACPI_EXPORT_SYMBOL (AcpiRemoveGpeBlock) 1124c2c66affSColin Finck 1125c2c66affSColin Finck 1126c2c66affSColin Finck /******************************************************************************* 1127c2c66affSColin Finck * 1128c2c66affSColin Finck * FUNCTION: AcpiGetGpeDevice 1129c2c66affSColin Finck * 1130c2c66affSColin Finck * PARAMETERS: Index - System GPE index (0-CurrentGpeCount) 1131c2c66affSColin Finck * GpeDevice - Where the parent GPE Device is returned 1132c2c66affSColin Finck * 1133c2c66affSColin Finck * RETURN: Status 1134c2c66affSColin Finck * 1135c2c66affSColin Finck * DESCRIPTION: Obtain the GPE device associated with the input index. A NULL 1136c2c66affSColin Finck * gpe device indicates that the gpe number is contained in one of 1137c2c66affSColin Finck * the FADT-defined gpe blocks. Otherwise, the GPE block device. 1138c2c66affSColin Finck * 1139c2c66affSColin Finck ******************************************************************************/ 1140c2c66affSColin Finck 1141c2c66affSColin Finck ACPI_STATUS 1142c2c66affSColin Finck AcpiGetGpeDevice ( 1143c2c66affSColin Finck UINT32 Index, 1144c2c66affSColin Finck ACPI_HANDLE *GpeDevice) 1145c2c66affSColin Finck { 1146c2c66affSColin Finck ACPI_GPE_DEVICE_INFO Info; 1147c2c66affSColin Finck ACPI_STATUS Status; 1148c2c66affSColin Finck 1149c2c66affSColin Finck 1150c2c66affSColin Finck ACPI_FUNCTION_TRACE (AcpiGetGpeDevice); 1151c2c66affSColin Finck 1152c2c66affSColin Finck 1153c2c66affSColin Finck if (!GpeDevice) 1154c2c66affSColin Finck { 1155c2c66affSColin Finck return_ACPI_STATUS (AE_BAD_PARAMETER); 1156c2c66affSColin Finck } 1157c2c66affSColin Finck 1158c2c66affSColin Finck if (Index >= AcpiCurrentGpeCount) 1159c2c66affSColin Finck { 1160c2c66affSColin Finck return_ACPI_STATUS (AE_NOT_EXIST); 1161c2c66affSColin Finck } 1162c2c66affSColin Finck 1163c2c66affSColin Finck /* Setup and walk the GPE list */ 1164c2c66affSColin Finck 1165c2c66affSColin Finck Info.Index = Index; 1166c2c66affSColin Finck Info.Status = AE_NOT_EXIST; 1167c2c66affSColin Finck Info.GpeDevice = NULL; 1168c2c66affSColin Finck Info.NextBlockBaseIndex = 0; 1169c2c66affSColin Finck 1170c2c66affSColin Finck Status = AcpiEvWalkGpeList (AcpiEvGetGpeDevice, &Info); 1171c2c66affSColin Finck if (ACPI_FAILURE (Status)) 1172c2c66affSColin Finck { 1173c2c66affSColin Finck return_ACPI_STATUS (Status); 1174c2c66affSColin Finck } 1175c2c66affSColin Finck 1176c2c66affSColin Finck *GpeDevice = ACPI_CAST_PTR (ACPI_HANDLE, Info.GpeDevice); 1177c2c66affSColin Finck return_ACPI_STATUS (Info.Status); 1178c2c66affSColin Finck } 1179c2c66affSColin Finck 1180c2c66affSColin Finck ACPI_EXPORT_SYMBOL (AcpiGetGpeDevice) 1181c2c66affSColin Finck 1182c2c66affSColin Finck #endif /* !ACPI_REDUCED_HARDWARE */ 1183