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