1216331Sjkim/****************************************************************************** 2216331Sjkim * 3216331Sjkim * Module Name: evxfgpe - External Interfaces for General Purpose Events (GPEs) 4216331Sjkim * 5216331Sjkim *****************************************************************************/ 6216331Sjkim 7217365Sjkim/* 8298714Sjkim * Copyright (C) 2000 - 2016, Intel Corp. 9216331Sjkim * All rights reserved. 10216331Sjkim * 11217365Sjkim * Redistribution and use in source and binary forms, with or without 12217365Sjkim * modification, are permitted provided that the following conditions 13217365Sjkim * are met: 14217365Sjkim * 1. Redistributions of source code must retain the above copyright 15217365Sjkim * notice, this list of conditions, and the following disclaimer, 16217365Sjkim * without modification. 17217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18217365Sjkim * substantially similar to the "NO WARRANTY" disclaimer below 19217365Sjkim * ("Disclaimer") and any redistribution must be conditioned upon 20217365Sjkim * including a substantially similar Disclaimer requirement for further 21217365Sjkim * binary redistribution. 22217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names 23217365Sjkim * of any contributors may be used to endorse or promote products derived 24217365Sjkim * from this software without specific prior written permission. 25216331Sjkim * 26217365Sjkim * Alternatively, this software may be distributed under the terms of the 27217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free 28217365Sjkim * Software Foundation. 29216331Sjkim * 30217365Sjkim * NO WARRANTY 31217365Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32217365Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33217365Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34217365Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35217365Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36217365Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37217365Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38217365Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39217365Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40217365Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41217365Sjkim * POSSIBILITY OF SUCH DAMAGES. 42217365Sjkim */ 43216331Sjkim 44272444Sjkim#define EXPORT_ACPI_INTERFACES 45216331Sjkim 46216471Sjkim#include <contrib/dev/acpica/include/acpi.h> 47216471Sjkim#include <contrib/dev/acpica/include/accommon.h> 48216471Sjkim#include <contrib/dev/acpica/include/acevents.h> 49216471Sjkim#include <contrib/dev/acpica/include/acnamesp.h> 50216331Sjkim 51216331Sjkim#define _COMPONENT ACPI_EVENTS 52216331Sjkim ACPI_MODULE_NAME ("evxfgpe") 53216331Sjkim 54216331Sjkim 55231844Sjkim#if (!ACPI_REDUCED_HARDWARE) /* Entire module */ 56216331Sjkim/******************************************************************************* 57216331Sjkim * 58216331Sjkim * FUNCTION: AcpiUpdateAllGpes 59216331Sjkim * 60216331Sjkim * PARAMETERS: None 61216331Sjkim * 62216331Sjkim * RETURN: Status 63216331Sjkim * 64216331Sjkim * DESCRIPTION: Complete GPE initialization and enable all GPEs that have 65216331Sjkim * associated _Lxx or _Exx methods and are not pointed to by any 66216331Sjkim * device _PRW methods (this indicates that these GPEs are 67216331Sjkim * generally intended for system or device wakeup. Such GPEs 68216331Sjkim * have to be enabled directly when the devices whose _PRW 69216331Sjkim * methods point to them are set up for wakeup signaling.) 70216331Sjkim * 71216331Sjkim * NOTE: Should be called after any GPEs are added to the system. Primarily, 72216331Sjkim * after the system _PRW methods have been run, but also after a GPE Block 73216331Sjkim * Device has been added or if any new GPE methods have been added via a 74216331Sjkim * dynamic table load. 75216331Sjkim * 76216331Sjkim ******************************************************************************/ 77216331Sjkim 78216331SjkimACPI_STATUS 79216331SjkimAcpiUpdateAllGpes ( 80216331Sjkim void) 81216331Sjkim{ 82216331Sjkim ACPI_STATUS Status; 83216331Sjkim 84216331Sjkim 85238381Sjkim ACPI_FUNCTION_TRACE (AcpiUpdateAllGpes); 86216331Sjkim 87216331Sjkim 88216331Sjkim Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 89216331Sjkim if (ACPI_FAILURE (Status)) 90216331Sjkim { 91216331Sjkim return_ACPI_STATUS (Status); 92216331Sjkim } 93216331Sjkim 94216331Sjkim if (AcpiGbl_AllGpesInitialized) 95216331Sjkim { 96216331Sjkim goto UnlockAndExit; 97216331Sjkim } 98216331Sjkim 99216331Sjkim Status = AcpiEvWalkGpeList (AcpiEvInitializeGpeBlock, NULL); 100216331Sjkim if (ACPI_SUCCESS (Status)) 101216331Sjkim { 102216331Sjkim AcpiGbl_AllGpesInitialized = TRUE; 103216331Sjkim } 104216331Sjkim 105216331SjkimUnlockAndExit: 106216331Sjkim (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 107216331Sjkim return_ACPI_STATUS (Status); 108216331Sjkim} 109216331Sjkim 110216331SjkimACPI_EXPORT_SYMBOL (AcpiUpdateAllGpes) 111216331Sjkim 112216331Sjkim 113216331Sjkim/******************************************************************************* 114216331Sjkim * 115216331Sjkim * FUNCTION: AcpiEnableGpe 116216331Sjkim * 117216331Sjkim * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1 118216331Sjkim * GpeNumber - GPE level within the GPE block 119216331Sjkim * 120216331Sjkim * RETURN: Status 121216331Sjkim * 122216331Sjkim * DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is 123216331Sjkim * hardware-enabled. 124216331Sjkim * 125216331Sjkim ******************************************************************************/ 126216331Sjkim 127216331SjkimACPI_STATUS 128216331SjkimAcpiEnableGpe ( 129216331Sjkim ACPI_HANDLE GpeDevice, 130216331Sjkim UINT32 GpeNumber) 131216331Sjkim{ 132216331Sjkim ACPI_STATUS Status = AE_BAD_PARAMETER; 133216331Sjkim ACPI_GPE_EVENT_INFO *GpeEventInfo; 134216331Sjkim ACPI_CPU_FLAGS Flags; 135216331Sjkim 136216331Sjkim 137216331Sjkim ACPI_FUNCTION_TRACE (AcpiEnableGpe); 138216331Sjkim 139216331Sjkim 140216331Sjkim Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 141216331Sjkim 142272444Sjkim /* 143272444Sjkim * Ensure that we have a valid GPE number and that there is some way 144272444Sjkim * of handling the GPE (handler or a GPE method). In other words, we 145272444Sjkim * won't allow a valid GPE to be enabled if there is no way to handle it. 146272444Sjkim */ 147216331Sjkim GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 148216331Sjkim if (GpeEventInfo) 149216331Sjkim { 150278970Sjkim if (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) != 151272444Sjkim ACPI_GPE_DISPATCH_NONE) 152272444Sjkim { 153272444Sjkim Status = AcpiEvAddGpeReference (GpeEventInfo); 154272444Sjkim } 155272444Sjkim else 156272444Sjkim { 157272444Sjkim Status = AE_NO_HANDLER; 158272444Sjkim } 159216331Sjkim } 160216331Sjkim 161216331Sjkim AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 162216331Sjkim return_ACPI_STATUS (Status); 163216331Sjkim} 164216331Sjkim 165216331SjkimACPI_EXPORT_SYMBOL (AcpiEnableGpe) 166216331Sjkim 167216331Sjkim 168216331Sjkim/******************************************************************************* 169216331Sjkim * 170216331Sjkim * FUNCTION: AcpiDisableGpe 171216331Sjkim * 172216331Sjkim * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1 173216331Sjkim * GpeNumber - GPE level within the GPE block 174216331Sjkim * 175216331Sjkim * RETURN: Status 176216331Sjkim * 177216331Sjkim * DESCRIPTION: Remove a reference to a GPE. When the last reference is 178216331Sjkim * removed, only then is the GPE disabled (for runtime GPEs), or 179216331Sjkim * the GPE mask bit disabled (for wake GPEs) 180216331Sjkim * 181216331Sjkim ******************************************************************************/ 182216331Sjkim 183216331SjkimACPI_STATUS 184216331SjkimAcpiDisableGpe ( 185216331Sjkim ACPI_HANDLE GpeDevice, 186216331Sjkim UINT32 GpeNumber) 187216331Sjkim{ 188216331Sjkim ACPI_STATUS Status = AE_BAD_PARAMETER; 189216331Sjkim ACPI_GPE_EVENT_INFO *GpeEventInfo; 190216331Sjkim ACPI_CPU_FLAGS Flags; 191216331Sjkim 192216331Sjkim 193216331Sjkim ACPI_FUNCTION_TRACE (AcpiDisableGpe); 194216331Sjkim 195216331Sjkim 196216331Sjkim Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 197216331Sjkim 198216331Sjkim /* Ensure that we have a valid GPE number */ 199216331Sjkim 200216331Sjkim GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 201216331Sjkim if (GpeEventInfo) 202216331Sjkim { 203216331Sjkim Status = AcpiEvRemoveGpeReference (GpeEventInfo); 204216331Sjkim } 205216331Sjkim 206216331Sjkim AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 207216331Sjkim return_ACPI_STATUS (Status); 208216331Sjkim} 209216331Sjkim 210216331SjkimACPI_EXPORT_SYMBOL (AcpiDisableGpe) 211216331Sjkim 212216331Sjkim 213216331Sjkim/******************************************************************************* 214216331Sjkim * 215216331Sjkim * FUNCTION: AcpiSetGpe 216216331Sjkim * 217216331Sjkim * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1 218216331Sjkim * GpeNumber - GPE level within the GPE block 219216331Sjkim * Action - ACPI_GPE_ENABLE or ACPI_GPE_DISABLE 220216331Sjkim * 221216331Sjkim * RETURN: Status 222216331Sjkim * 223216331Sjkim * DESCRIPTION: Enable or disable an individual GPE. This function bypasses 224278970Sjkim * the reference count mechanism used in the AcpiEnableGpe(), 225278970Sjkim * AcpiDisableGpe() interfaces. 226278970Sjkim * This API is typically used by the GPE raw handler mode driver 227278970Sjkim * to switch between the polling mode and the interrupt mode after 228278970Sjkim * the driver has enabled the GPE. 229278970Sjkim * The APIs should be invoked in this order: 230278970Sjkim * AcpiEnableGpe() <- Ensure the reference count > 0 231278970Sjkim * AcpiSetGpe(ACPI_GPE_DISABLE) <- Enter polling mode 232278970Sjkim * AcpiSetGpe(ACPI_GPE_ENABLE) <- Leave polling mode 233278970Sjkim * AcpiDisableGpe() <- Decrease the reference count 234216331Sjkim * 235278970Sjkim * Note: If a GPE is shared by 2 silicon components, then both the drivers 236278970Sjkim * should support GPE polling mode or disabling the GPE for long period 237278970Sjkim * for one driver may break the other. So use it with care since all 238278970Sjkim * firmware _Lxx/_Exx handlers currently rely on the GPE interrupt mode. 239216331Sjkim * 240216331Sjkim ******************************************************************************/ 241216331Sjkim 242216331SjkimACPI_STATUS 243216331SjkimAcpiSetGpe ( 244216331Sjkim ACPI_HANDLE GpeDevice, 245216331Sjkim UINT32 GpeNumber, 246216331Sjkim UINT8 Action) 247216331Sjkim{ 248216331Sjkim ACPI_GPE_EVENT_INFO *GpeEventInfo; 249216331Sjkim ACPI_STATUS Status; 250216331Sjkim ACPI_CPU_FLAGS Flags; 251216331Sjkim 252216331Sjkim 253216331Sjkim ACPI_FUNCTION_TRACE (AcpiSetGpe); 254216331Sjkim 255216331Sjkim 256216331Sjkim Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 257216331Sjkim 258216331Sjkim /* Ensure that we have a valid GPE number */ 259216331Sjkim 260216331Sjkim GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 261216331Sjkim if (!GpeEventInfo) 262216331Sjkim { 263216331Sjkim Status = AE_BAD_PARAMETER; 264216331Sjkim goto UnlockAndExit; 265216331Sjkim } 266216331Sjkim 267216331Sjkim /* Perform the action */ 268216331Sjkim 269216331Sjkim switch (Action) 270216331Sjkim { 271216331Sjkim case ACPI_GPE_ENABLE: 272250838Sjkim 273278970Sjkim Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_ENABLE); 274216331Sjkim break; 275216331Sjkim 276216331Sjkim case ACPI_GPE_DISABLE: 277250838Sjkim 278216331Sjkim Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_DISABLE); 279216331Sjkim break; 280216331Sjkim 281216331Sjkim default: 282250838Sjkim 283216331Sjkim Status = AE_BAD_PARAMETER; 284216331Sjkim break; 285216331Sjkim } 286216331Sjkim 287216331SjkimUnlockAndExit: 288216331Sjkim AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 289216331Sjkim return_ACPI_STATUS (Status); 290216331Sjkim} 291216331Sjkim 292216331SjkimACPI_EXPORT_SYMBOL (AcpiSetGpe) 293216331Sjkim 294216331Sjkim 295216331Sjkim/******************************************************************************* 296216331Sjkim * 297272444Sjkim * FUNCTION: AcpiMarkGpeForWake 298272444Sjkim * 299272444Sjkim * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1 300272444Sjkim * GpeNumber - GPE level within the GPE block 301272444Sjkim * 302272444Sjkim * RETURN: Status 303272444Sjkim * 304272444Sjkim * DESCRIPTION: Mark a GPE as having the ability to wake the system. Simply 305272444Sjkim * sets the ACPI_GPE_CAN_WAKE flag. 306272444Sjkim * 307272444Sjkim * Some potential callers of AcpiSetupGpeForWake may know in advance that 308272444Sjkim * there won't be any notify handlers installed for device wake notifications 309272444Sjkim * from the given GPE (one example is a button GPE in Linux). For these cases, 310272444Sjkim * AcpiMarkGpeForWake should be used instead of AcpiSetupGpeForWake. 311272444Sjkim * This will set the ACPI_GPE_CAN_WAKE flag for the GPE without trying to 312272444Sjkim * setup implicit wake notification for it (since there's no handler method). 313272444Sjkim * 314272444Sjkim ******************************************************************************/ 315272444Sjkim 316272444SjkimACPI_STATUS 317272444SjkimAcpiMarkGpeForWake ( 318272444Sjkim ACPI_HANDLE GpeDevice, 319272444Sjkim UINT32 GpeNumber) 320272444Sjkim{ 321272444Sjkim ACPI_GPE_EVENT_INFO *GpeEventInfo; 322272444Sjkim ACPI_STATUS Status = AE_BAD_PARAMETER; 323272444Sjkim ACPI_CPU_FLAGS Flags; 324272444Sjkim 325272444Sjkim 326272444Sjkim ACPI_FUNCTION_TRACE (AcpiMarkGpeForWake); 327272444Sjkim 328272444Sjkim 329272444Sjkim Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 330272444Sjkim 331272444Sjkim /* Ensure that we have a valid GPE number */ 332272444Sjkim 333272444Sjkim GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 334272444Sjkim if (GpeEventInfo) 335272444Sjkim { 336272444Sjkim /* Mark the GPE as a possible wake event */ 337272444Sjkim 338272444Sjkim GpeEventInfo->Flags |= ACPI_GPE_CAN_WAKE; 339272444Sjkim Status = AE_OK; 340272444Sjkim } 341272444Sjkim 342272444Sjkim AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 343272444Sjkim return_ACPI_STATUS (Status); 344272444Sjkim} 345272444Sjkim 346272444SjkimACPI_EXPORT_SYMBOL (AcpiMarkGpeForWake) 347272444Sjkim 348272444Sjkim 349272444Sjkim/******************************************************************************* 350272444Sjkim * 351216331Sjkim * FUNCTION: AcpiSetupGpeForWake 352216331Sjkim * 353216331Sjkim * PARAMETERS: WakeDevice - Device associated with the GPE (via _PRW) 354216331Sjkim * GpeDevice - Parent GPE Device. NULL for GPE0/GPE1 355216331Sjkim * GpeNumber - GPE level within the GPE block 356216331Sjkim * 357216331Sjkim * RETURN: Status 358216331Sjkim * 359216331Sjkim * DESCRIPTION: Mark a GPE as having the ability to wake the system. This 360216331Sjkim * interface is intended to be used as the host executes the 361216331Sjkim * _PRW methods (Power Resources for Wake) in the system tables. 362216331Sjkim * Each _PRW appears under a Device Object (The WakeDevice), and 363216331Sjkim * contains the info for the wake GPE associated with the 364216331Sjkim * WakeDevice. 365216331Sjkim * 366216331Sjkim ******************************************************************************/ 367216331Sjkim 368216331SjkimACPI_STATUS 369216331SjkimAcpiSetupGpeForWake ( 370216331Sjkim ACPI_HANDLE WakeDevice, 371216331Sjkim ACPI_HANDLE GpeDevice, 372216331Sjkim UINT32 GpeNumber) 373216331Sjkim{ 374237412Sjkim ACPI_STATUS Status; 375216331Sjkim ACPI_GPE_EVENT_INFO *GpeEventInfo; 376216331Sjkim ACPI_NAMESPACE_NODE *DeviceNode; 377238381Sjkim ACPI_GPE_NOTIFY_INFO *Notify; 378238381Sjkim ACPI_GPE_NOTIFY_INFO *NewNotify; 379216331Sjkim ACPI_CPU_FLAGS Flags; 380216331Sjkim 381216331Sjkim 382216331Sjkim ACPI_FUNCTION_TRACE (AcpiSetupGpeForWake); 383216331Sjkim 384216331Sjkim 385216331Sjkim /* Parameter Validation */ 386216331Sjkim 387216331Sjkim if (!WakeDevice) 388216331Sjkim { 389216331Sjkim /* 390216331Sjkim * By forcing WakeDevice to be valid, we automatically enable the 391216331Sjkim * implicit notify feature on all hosts. 392216331Sjkim */ 393216331Sjkim return_ACPI_STATUS (AE_BAD_PARAMETER); 394216331Sjkim } 395216331Sjkim 396219707Sjkim /* Handle root object case */ 397219707Sjkim 398219707Sjkim if (WakeDevice == ACPI_ROOT_OBJECT) 399219707Sjkim { 400219707Sjkim DeviceNode = AcpiGbl_RootNode; 401219707Sjkim } 402219707Sjkim else 403219707Sjkim { 404219707Sjkim DeviceNode = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, WakeDevice); 405219707Sjkim } 406219707Sjkim 407216331Sjkim /* Validate WakeDevice is of type Device */ 408216331Sjkim 409216331Sjkim if (DeviceNode->Type != ACPI_TYPE_DEVICE) 410216331Sjkim { 411216331Sjkim return_ACPI_STATUS (AE_BAD_PARAMETER); 412216331Sjkim } 413216331Sjkim 414238381Sjkim /* 415238381Sjkim * Allocate a new notify object up front, in case it is needed. 416238381Sjkim * Memory allocation while holding a spinlock is a big no-no 417238381Sjkim * on some hosts. 418238381Sjkim */ 419237652Sjkim NewNotify = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_GPE_NOTIFY_INFO)); 420237652Sjkim if (!NewNotify) 421237652Sjkim { 422237652Sjkim return_ACPI_STATUS (AE_NO_MEMORY); 423237652Sjkim } 424237652Sjkim 425216331Sjkim Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 426216331Sjkim 427216331Sjkim /* Ensure that we have a valid GPE number */ 428216331Sjkim 429216331Sjkim GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 430237412Sjkim if (!GpeEventInfo) 431216331Sjkim { 432237412Sjkim Status = AE_BAD_PARAMETER; 433237412Sjkim goto UnlockAndExit; 434237412Sjkim } 435237412Sjkim 436237412Sjkim /* 437237412Sjkim * If there is no method or handler for this GPE, then the 438237412Sjkim * WakeDevice will be notified whenever this GPE fires. This is 439237412Sjkim * known as an "implicit notify". Note: The GPE is assumed to be 440237412Sjkim * level-triggered (for windows compatibility). 441237412Sjkim */ 442278970Sjkim if (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) == 443298714Sjkim ACPI_GPE_DISPATCH_NONE) 444237412Sjkim { 445216331Sjkim /* 446237412Sjkim * This is the first device for implicit notify on this GPE. 447237412Sjkim * Just set the flags here, and enter the NOTIFY block below. 448216331Sjkim */ 449237412Sjkim GpeEventInfo->Flags = 450237412Sjkim (ACPI_GPE_DISPATCH_NOTIFY | ACPI_GPE_LEVEL_TRIGGERED); 451237412Sjkim } 452237412Sjkim 453237412Sjkim /* 454237412Sjkim * If we already have an implicit notify on this GPE, add 455237412Sjkim * this device to the notify list. 456237412Sjkim */ 457278970Sjkim if (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) == 458298714Sjkim ACPI_GPE_DISPATCH_NOTIFY) 459237412Sjkim { 460237412Sjkim /* Ensure that the device is not already in the list */ 461237412Sjkim 462237412Sjkim Notify = GpeEventInfo->Dispatch.NotifyList; 463237412Sjkim while (Notify) 464216331Sjkim { 465237412Sjkim if (Notify->DeviceNode == DeviceNode) 466237412Sjkim { 467237412Sjkim Status = AE_ALREADY_EXISTS; 468237412Sjkim goto UnlockAndExit; 469237412Sjkim } 470237412Sjkim Notify = Notify->Next; 471216331Sjkim } 472216331Sjkim 473237412Sjkim /* Add this device to the notify list for this GPE */ 474237412Sjkim 475237652Sjkim NewNotify->DeviceNode = DeviceNode; 476237652Sjkim NewNotify->Next = GpeEventInfo->Dispatch.NotifyList; 477237652Sjkim GpeEventInfo->Dispatch.NotifyList = NewNotify; 478237652Sjkim NewNotify = NULL; 479216331Sjkim } 480216331Sjkim 481237412Sjkim /* Mark the GPE as a possible wake event */ 482237412Sjkim 483237412Sjkim GpeEventInfo->Flags |= ACPI_GPE_CAN_WAKE; 484237412Sjkim Status = AE_OK; 485237412Sjkim 486238381Sjkim 487237412SjkimUnlockAndExit: 488216331Sjkim AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 489238381Sjkim 490238381Sjkim /* Delete the notify object if it was not used above */ 491238381Sjkim 492237652Sjkim if (NewNotify) 493237652Sjkim { 494237652Sjkim ACPI_FREE (NewNotify); 495237652Sjkim } 496216331Sjkim return_ACPI_STATUS (Status); 497216331Sjkim} 498216331Sjkim 499216331SjkimACPI_EXPORT_SYMBOL (AcpiSetupGpeForWake) 500216331Sjkim 501216331Sjkim 502216331Sjkim/******************************************************************************* 503216331Sjkim * 504216331Sjkim * FUNCTION: AcpiSetGpeWakeMask 505216331Sjkim * 506216331Sjkim * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1 507216331Sjkim * GpeNumber - GPE level within the GPE block 508216331Sjkim * Action - Enable or Disable 509216331Sjkim * 510216331Sjkim * RETURN: Status 511216331Sjkim * 512216331Sjkim * DESCRIPTION: Set or clear the GPE's wakeup enable mask bit. The GPE must 513216331Sjkim * already be marked as a WAKE GPE. 514216331Sjkim * 515216331Sjkim ******************************************************************************/ 516216331Sjkim 517216331SjkimACPI_STATUS 518216331SjkimAcpiSetGpeWakeMask ( 519216331Sjkim ACPI_HANDLE GpeDevice, 520216331Sjkim UINT32 GpeNumber, 521216331Sjkim UINT8 Action) 522216331Sjkim{ 523216331Sjkim ACPI_STATUS Status = AE_OK; 524216331Sjkim ACPI_GPE_EVENT_INFO *GpeEventInfo; 525216331Sjkim ACPI_GPE_REGISTER_INFO *GpeRegisterInfo; 526216331Sjkim ACPI_CPU_FLAGS Flags; 527216331Sjkim UINT32 RegisterBit; 528216331Sjkim 529216331Sjkim 530216331Sjkim ACPI_FUNCTION_TRACE (AcpiSetGpeWakeMask); 531216331Sjkim 532216331Sjkim 533216331Sjkim Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 534216331Sjkim 535216331Sjkim /* 536216331Sjkim * Ensure that we have a valid GPE number and that this GPE is in 537216331Sjkim * fact a wake GPE 538216331Sjkim */ 539216331Sjkim GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 540216331Sjkim if (!GpeEventInfo) 541216331Sjkim { 542216331Sjkim Status = AE_BAD_PARAMETER; 543216331Sjkim goto UnlockAndExit; 544216331Sjkim } 545216331Sjkim 546216331Sjkim if (!(GpeEventInfo->Flags & ACPI_GPE_CAN_WAKE)) 547216331Sjkim { 548216331Sjkim Status = AE_TYPE; 549216331Sjkim goto UnlockAndExit; 550216331Sjkim } 551216331Sjkim 552216331Sjkim GpeRegisterInfo = GpeEventInfo->RegisterInfo; 553216331Sjkim if (!GpeRegisterInfo) 554216331Sjkim { 555216331Sjkim Status = AE_NOT_EXIST; 556216331Sjkim goto UnlockAndExit; 557216331Sjkim } 558216331Sjkim 559239340Sjkim RegisterBit = AcpiHwGetGpeRegisterBit (GpeEventInfo); 560216331Sjkim 561216331Sjkim /* Perform the action */ 562216331Sjkim 563216331Sjkim switch (Action) 564216331Sjkim { 565216331Sjkim case ACPI_GPE_ENABLE: 566250838Sjkim 567216331Sjkim ACPI_SET_BIT (GpeRegisterInfo->EnableForWake, (UINT8) RegisterBit); 568216331Sjkim break; 569216331Sjkim 570216331Sjkim case ACPI_GPE_DISABLE: 571250838Sjkim 572216331Sjkim ACPI_CLEAR_BIT (GpeRegisterInfo->EnableForWake, (UINT8) RegisterBit); 573216331Sjkim break; 574216331Sjkim 575216331Sjkim default: 576250838Sjkim 577216331Sjkim ACPI_ERROR ((AE_INFO, "%u, Invalid action", Action)); 578216331Sjkim Status = AE_BAD_PARAMETER; 579216331Sjkim break; 580216331Sjkim } 581216331Sjkim 582216331SjkimUnlockAndExit: 583216331Sjkim AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 584216331Sjkim return_ACPI_STATUS (Status); 585216331Sjkim} 586216331Sjkim 587216331SjkimACPI_EXPORT_SYMBOL (AcpiSetGpeWakeMask) 588216331Sjkim 589216331Sjkim 590216331Sjkim/******************************************************************************* 591216331Sjkim * 592216331Sjkim * FUNCTION: AcpiClearGpe 593216331Sjkim * 594216331Sjkim * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1 595216331Sjkim * GpeNumber - GPE level within the GPE block 596216331Sjkim * 597216331Sjkim * RETURN: Status 598216331Sjkim * 599216331Sjkim * DESCRIPTION: Clear an ACPI event (general purpose) 600216331Sjkim * 601216331Sjkim ******************************************************************************/ 602216331Sjkim 603216331SjkimACPI_STATUS 604216331SjkimAcpiClearGpe ( 605216331Sjkim ACPI_HANDLE GpeDevice, 606216331Sjkim UINT32 GpeNumber) 607216331Sjkim{ 608216331Sjkim ACPI_STATUS Status = AE_OK; 609216331Sjkim ACPI_GPE_EVENT_INFO *GpeEventInfo; 610216331Sjkim ACPI_CPU_FLAGS Flags; 611216331Sjkim 612216331Sjkim 613216331Sjkim ACPI_FUNCTION_TRACE (AcpiClearGpe); 614216331Sjkim 615216331Sjkim 616216331Sjkim Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 617216331Sjkim 618216331Sjkim /* Ensure that we have a valid GPE number */ 619216331Sjkim 620216331Sjkim GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 621216331Sjkim if (!GpeEventInfo) 622216331Sjkim { 623216331Sjkim Status = AE_BAD_PARAMETER; 624216331Sjkim goto UnlockAndExit; 625216331Sjkim } 626216331Sjkim 627216331Sjkim Status = AcpiHwClearGpe (GpeEventInfo); 628216331Sjkim 629216331SjkimUnlockAndExit: 630216331Sjkim AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 631216331Sjkim return_ACPI_STATUS (Status); 632216331Sjkim} 633216331Sjkim 634216331SjkimACPI_EXPORT_SYMBOL (AcpiClearGpe) 635216331Sjkim 636216331Sjkim 637216331Sjkim/******************************************************************************* 638216331Sjkim * 639216331Sjkim * FUNCTION: AcpiGetGpeStatus 640216331Sjkim * 641216331Sjkim * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1 642216331Sjkim * GpeNumber - GPE level within the GPE block 643216331Sjkim * EventStatus - Where the current status of the event 644216331Sjkim * will be returned 645216331Sjkim * 646216331Sjkim * RETURN: Status 647216331Sjkim * 648216331Sjkim * DESCRIPTION: Get the current status of a GPE (signalled/not_signalled) 649216331Sjkim * 650216331Sjkim ******************************************************************************/ 651216331Sjkim 652216331SjkimACPI_STATUS 653216331SjkimAcpiGetGpeStatus ( 654216331Sjkim ACPI_HANDLE GpeDevice, 655216331Sjkim UINT32 GpeNumber, 656216331Sjkim ACPI_EVENT_STATUS *EventStatus) 657216331Sjkim{ 658216331Sjkim ACPI_STATUS Status = AE_OK; 659216331Sjkim ACPI_GPE_EVENT_INFO *GpeEventInfo; 660216331Sjkim ACPI_CPU_FLAGS Flags; 661216331Sjkim 662216331Sjkim 663216331Sjkim ACPI_FUNCTION_TRACE (AcpiGetGpeStatus); 664216331Sjkim 665216331Sjkim 666216331Sjkim Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 667216331Sjkim 668216331Sjkim /* Ensure that we have a valid GPE number */ 669216331Sjkim 670216331Sjkim GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 671216331Sjkim if (!GpeEventInfo) 672216331Sjkim { 673216331Sjkim Status = AE_BAD_PARAMETER; 674216331Sjkim goto UnlockAndExit; 675216331Sjkim } 676216331Sjkim 677216331Sjkim /* Obtain status on the requested GPE number */ 678216331Sjkim 679216331Sjkim Status = AcpiHwGetGpeStatus (GpeEventInfo, EventStatus); 680216331Sjkim 681216331SjkimUnlockAndExit: 682216331Sjkim AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 683216331Sjkim return_ACPI_STATUS (Status); 684216331Sjkim} 685216331Sjkim 686216331SjkimACPI_EXPORT_SYMBOL (AcpiGetGpeStatus) 687216331Sjkim 688216331Sjkim 689216331Sjkim/******************************************************************************* 690216331Sjkim * 691216331Sjkim * FUNCTION: AcpiFinishGpe 692216331Sjkim * 693216331Sjkim * PARAMETERS: GpeDevice - Namespace node for the GPE Block 694216331Sjkim * (NULL for FADT defined GPEs) 695216331Sjkim * GpeNumber - GPE level within the GPE block 696216331Sjkim * 697216331Sjkim * RETURN: Status 698216331Sjkim * 699216331Sjkim * DESCRIPTION: Clear and conditionally reenable a GPE. This completes the GPE 700216331Sjkim * processing. Intended for use by asynchronous host-installed 701216331Sjkim * GPE handlers. The GPE is only reenabled if the EnableForRun bit 702216331Sjkim * is set in the GPE info. 703216331Sjkim * 704216331Sjkim ******************************************************************************/ 705216331Sjkim 706216331SjkimACPI_STATUS 707216331SjkimAcpiFinishGpe ( 708216331Sjkim ACPI_HANDLE GpeDevice, 709216331Sjkim UINT32 GpeNumber) 710216331Sjkim{ 711216331Sjkim ACPI_GPE_EVENT_INFO *GpeEventInfo; 712216331Sjkim ACPI_STATUS Status; 713216331Sjkim ACPI_CPU_FLAGS Flags; 714216331Sjkim 715216331Sjkim 716216331Sjkim ACPI_FUNCTION_TRACE (AcpiFinishGpe); 717216331Sjkim 718216331Sjkim 719216331Sjkim Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 720216331Sjkim 721216331Sjkim /* Ensure that we have a valid GPE number */ 722216331Sjkim 723216331Sjkim GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 724216331Sjkim if (!GpeEventInfo) 725216331Sjkim { 726216331Sjkim Status = AE_BAD_PARAMETER; 727216331Sjkim goto UnlockAndExit; 728216331Sjkim } 729216331Sjkim 730216331Sjkim Status = AcpiEvFinishGpe (GpeEventInfo); 731216331Sjkim 732216331SjkimUnlockAndExit: 733216331Sjkim AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 734216331Sjkim return_ACPI_STATUS (Status); 735216331Sjkim} 736216331Sjkim 737216331SjkimACPI_EXPORT_SYMBOL (AcpiFinishGpe) 738216331Sjkim 739216331Sjkim 740216331Sjkim/****************************************************************************** 741216331Sjkim * 742216331Sjkim * FUNCTION: AcpiDisableAllGpes 743216331Sjkim * 744216331Sjkim * PARAMETERS: None 745216331Sjkim * 746216331Sjkim * RETURN: Status 747216331Sjkim * 748216331Sjkim * DESCRIPTION: Disable and clear all GPEs in all GPE blocks 749216331Sjkim * 750216331Sjkim ******************************************************************************/ 751216331Sjkim 752216331SjkimACPI_STATUS 753216331SjkimAcpiDisableAllGpes ( 754216331Sjkim void) 755216331Sjkim{ 756216331Sjkim ACPI_STATUS Status; 757216331Sjkim 758216331Sjkim 759216331Sjkim ACPI_FUNCTION_TRACE (AcpiDisableAllGpes); 760216331Sjkim 761216331Sjkim 762216331Sjkim Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 763216331Sjkim if (ACPI_FAILURE (Status)) 764216331Sjkim { 765216331Sjkim return_ACPI_STATUS (Status); 766216331Sjkim } 767216331Sjkim 768216331Sjkim Status = AcpiHwDisableAllGpes (); 769216331Sjkim (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 770216331Sjkim 771216331Sjkim return_ACPI_STATUS (Status); 772216331Sjkim} 773216331Sjkim 774216331SjkimACPI_EXPORT_SYMBOL (AcpiDisableAllGpes) 775216331Sjkim 776216331Sjkim 777216331Sjkim/****************************************************************************** 778216331Sjkim * 779216331Sjkim * FUNCTION: AcpiEnableAllRuntimeGpes 780216331Sjkim * 781216331Sjkim * PARAMETERS: None 782216331Sjkim * 783216331Sjkim * RETURN: Status 784216331Sjkim * 785216331Sjkim * DESCRIPTION: Enable all "runtime" GPEs, in all GPE blocks 786216331Sjkim * 787216331Sjkim ******************************************************************************/ 788216331Sjkim 789216331SjkimACPI_STATUS 790216331SjkimAcpiEnableAllRuntimeGpes ( 791216331Sjkim void) 792216331Sjkim{ 793216331Sjkim ACPI_STATUS Status; 794216331Sjkim 795216331Sjkim 796216331Sjkim ACPI_FUNCTION_TRACE (AcpiEnableAllRuntimeGpes); 797216331Sjkim 798216331Sjkim 799216331Sjkim Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 800216331Sjkim if (ACPI_FAILURE (Status)) 801216331Sjkim { 802216331Sjkim return_ACPI_STATUS (Status); 803216331Sjkim } 804216331Sjkim 805216331Sjkim Status = AcpiHwEnableAllRuntimeGpes (); 806216331Sjkim (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 807216331Sjkim 808216331Sjkim return_ACPI_STATUS (Status); 809216331Sjkim} 810216331Sjkim 811216331SjkimACPI_EXPORT_SYMBOL (AcpiEnableAllRuntimeGpes) 812216331Sjkim 813216331Sjkim 814278970Sjkim/****************************************************************************** 815278970Sjkim * 816278970Sjkim * FUNCTION: AcpiEnableAllWakeupGpes 817278970Sjkim * 818278970Sjkim * PARAMETERS: None 819278970Sjkim * 820278970Sjkim * RETURN: Status 821278970Sjkim * 822278970Sjkim * DESCRIPTION: Enable all "wakeup" GPEs and disable all of the other GPEs, in 823278970Sjkim * all GPE blocks. 824278970Sjkim * 825278970Sjkim ******************************************************************************/ 826278970Sjkim 827278970SjkimACPI_STATUS 828278970SjkimAcpiEnableAllWakeupGpes ( 829278970Sjkim void) 830278970Sjkim{ 831278970Sjkim ACPI_STATUS Status; 832278970Sjkim 833278970Sjkim 834278970Sjkim ACPI_FUNCTION_TRACE (AcpiEnableAllWakeupGpes); 835278970Sjkim 836278970Sjkim 837278970Sjkim Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 838278970Sjkim if (ACPI_FAILURE (Status)) 839278970Sjkim { 840278970Sjkim return_ACPI_STATUS (Status); 841278970Sjkim } 842278970Sjkim 843278970Sjkim Status = AcpiHwEnableAllWakeupGpes (); 844278970Sjkim (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 845278970Sjkim 846278970Sjkim return_ACPI_STATUS (Status); 847278970Sjkim} 848278970Sjkim 849278970SjkimACPI_EXPORT_SYMBOL (AcpiEnableAllWakeupGpes) 850278970Sjkim 851278970Sjkim 852216331Sjkim/******************************************************************************* 853216331Sjkim * 854216331Sjkim * FUNCTION: AcpiInstallGpeBlock 855216331Sjkim * 856216331Sjkim * PARAMETERS: GpeDevice - Handle to the parent GPE Block Device 857216331Sjkim * GpeBlockAddress - Address and SpaceID 858216331Sjkim * RegisterCount - Number of GPE register pairs in the block 859216331Sjkim * InterruptNumber - H/W interrupt for the block 860216331Sjkim * 861216331Sjkim * RETURN: Status 862216331Sjkim * 863216331Sjkim * DESCRIPTION: Create and Install a block of GPE registers. The GPEs are not 864216331Sjkim * enabled here. 865216331Sjkim * 866216331Sjkim ******************************************************************************/ 867216331Sjkim 868216331SjkimACPI_STATUS 869216331SjkimAcpiInstallGpeBlock ( 870216331Sjkim ACPI_HANDLE GpeDevice, 871216331Sjkim ACPI_GENERIC_ADDRESS *GpeBlockAddress, 872216331Sjkim UINT32 RegisterCount, 873216331Sjkim UINT32 InterruptNumber) 874216331Sjkim{ 875216331Sjkim ACPI_STATUS Status; 876216331Sjkim ACPI_OPERAND_OBJECT *ObjDesc; 877216331Sjkim ACPI_NAMESPACE_NODE *Node; 878216331Sjkim ACPI_GPE_BLOCK_INFO *GpeBlock; 879216331Sjkim 880216331Sjkim 881216331Sjkim ACPI_FUNCTION_TRACE (AcpiInstallGpeBlock); 882216331Sjkim 883216331Sjkim 884216331Sjkim if ((!GpeDevice) || 885216331Sjkim (!GpeBlockAddress) || 886216331Sjkim (!RegisterCount)) 887216331Sjkim { 888216331Sjkim return_ACPI_STATUS (AE_BAD_PARAMETER); 889216331Sjkim } 890216331Sjkim 891216331Sjkim Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 892216331Sjkim if (ACPI_FAILURE (Status)) 893216331Sjkim { 894241973Sjkim return_ACPI_STATUS (Status); 895216331Sjkim } 896216331Sjkim 897216331Sjkim Node = AcpiNsValidateHandle (GpeDevice); 898216331Sjkim if (!Node) 899216331Sjkim { 900216331Sjkim Status = AE_BAD_PARAMETER; 901216331Sjkim goto UnlockAndExit; 902216331Sjkim } 903216331Sjkim 904272444Sjkim /* Validate the parent device */ 905272444Sjkim 906272444Sjkim if (Node->Type != ACPI_TYPE_DEVICE) 907272444Sjkim { 908272444Sjkim Status = AE_TYPE; 909272444Sjkim goto UnlockAndExit; 910272444Sjkim } 911272444Sjkim 912272444Sjkim if (Node->Object) 913272444Sjkim { 914272444Sjkim Status = AE_ALREADY_EXISTS; 915272444Sjkim goto UnlockAndExit; 916272444Sjkim } 917272444Sjkim 918216331Sjkim /* 919216331Sjkim * For user-installed GPE Block Devices, the GpeBlockBaseNumber 920216331Sjkim * is always zero 921216331Sjkim */ 922272444Sjkim Status = AcpiEvCreateGpeBlock (Node, GpeBlockAddress->Address, 923298714Sjkim GpeBlockAddress->SpaceId, RegisterCount, 924298714Sjkim 0, InterruptNumber, &GpeBlock); 925216331Sjkim if (ACPI_FAILURE (Status)) 926216331Sjkim { 927216331Sjkim goto UnlockAndExit; 928216331Sjkim } 929216331Sjkim 930216331Sjkim /* Install block in the DeviceObject attached to the node */ 931216331Sjkim 932216331Sjkim ObjDesc = AcpiNsGetAttachedObject (Node); 933216331Sjkim if (!ObjDesc) 934216331Sjkim { 935216331Sjkim /* 936216331Sjkim * No object, create a new one (Device nodes do not always have 937216331Sjkim * an attached object) 938216331Sjkim */ 939216331Sjkim ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_DEVICE); 940216331Sjkim if (!ObjDesc) 941216331Sjkim { 942216331Sjkim Status = AE_NO_MEMORY; 943216331Sjkim goto UnlockAndExit; 944216331Sjkim } 945216331Sjkim 946216331Sjkim Status = AcpiNsAttachObject (Node, ObjDesc, ACPI_TYPE_DEVICE); 947216331Sjkim 948216331Sjkim /* Remove local reference to the object */ 949216331Sjkim 950216331Sjkim AcpiUtRemoveReference (ObjDesc); 951216331Sjkim if (ACPI_FAILURE (Status)) 952216331Sjkim { 953216331Sjkim goto UnlockAndExit; 954216331Sjkim } 955216331Sjkim } 956216331Sjkim 957216331Sjkim /* Now install the GPE block in the DeviceObject */ 958216331Sjkim 959216331Sjkim ObjDesc->Device.GpeBlock = GpeBlock; 960216331Sjkim 961216331Sjkim 962216331SjkimUnlockAndExit: 963216331Sjkim (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 964216331Sjkim return_ACPI_STATUS (Status); 965216331Sjkim} 966216331Sjkim 967216331SjkimACPI_EXPORT_SYMBOL (AcpiInstallGpeBlock) 968216331Sjkim 969216331Sjkim 970216331Sjkim/******************************************************************************* 971216331Sjkim * 972216331Sjkim * FUNCTION: AcpiRemoveGpeBlock 973216331Sjkim * 974216331Sjkim * PARAMETERS: GpeDevice - Handle to the parent GPE Block Device 975216331Sjkim * 976216331Sjkim * RETURN: Status 977216331Sjkim * 978216331Sjkim * DESCRIPTION: Remove a previously installed block of GPE registers 979216331Sjkim * 980216331Sjkim ******************************************************************************/ 981216331Sjkim 982216331SjkimACPI_STATUS 983216331SjkimAcpiRemoveGpeBlock ( 984216331Sjkim ACPI_HANDLE GpeDevice) 985216331Sjkim{ 986216331Sjkim ACPI_OPERAND_OBJECT *ObjDesc; 987216331Sjkim ACPI_STATUS Status; 988216331Sjkim ACPI_NAMESPACE_NODE *Node; 989216331Sjkim 990216331Sjkim 991216331Sjkim ACPI_FUNCTION_TRACE (AcpiRemoveGpeBlock); 992216331Sjkim 993216331Sjkim 994216331Sjkim if (!GpeDevice) 995216331Sjkim { 996216331Sjkim return_ACPI_STATUS (AE_BAD_PARAMETER); 997216331Sjkim } 998216331Sjkim 999216331Sjkim Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 1000216331Sjkim if (ACPI_FAILURE (Status)) 1001216331Sjkim { 1002241973Sjkim return_ACPI_STATUS (Status); 1003216331Sjkim } 1004216331Sjkim 1005216331Sjkim Node = AcpiNsValidateHandle (GpeDevice); 1006216331Sjkim if (!Node) 1007216331Sjkim { 1008216331Sjkim Status = AE_BAD_PARAMETER; 1009216331Sjkim goto UnlockAndExit; 1010216331Sjkim } 1011216331Sjkim 1012272444Sjkim /* Validate the parent device */ 1013272444Sjkim 1014272444Sjkim if (Node->Type != ACPI_TYPE_DEVICE) 1015272444Sjkim { 1016272444Sjkim Status = AE_TYPE; 1017272444Sjkim goto UnlockAndExit; 1018272444Sjkim } 1019272444Sjkim 1020216331Sjkim /* Get the DeviceObject attached to the node */ 1021216331Sjkim 1022216331Sjkim ObjDesc = AcpiNsGetAttachedObject (Node); 1023216331Sjkim if (!ObjDesc || 1024216331Sjkim !ObjDesc->Device.GpeBlock) 1025216331Sjkim { 1026216331Sjkim return_ACPI_STATUS (AE_NULL_OBJECT); 1027216331Sjkim } 1028216331Sjkim 1029216331Sjkim /* Delete the GPE block (but not the DeviceObject) */ 1030216331Sjkim 1031216331Sjkim Status = AcpiEvDeleteGpeBlock (ObjDesc->Device.GpeBlock); 1032216331Sjkim if (ACPI_SUCCESS (Status)) 1033216331Sjkim { 1034216331Sjkim ObjDesc->Device.GpeBlock = NULL; 1035216331Sjkim } 1036216331Sjkim 1037216331SjkimUnlockAndExit: 1038216331Sjkim (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 1039216331Sjkim return_ACPI_STATUS (Status); 1040216331Sjkim} 1041216331Sjkim 1042216331SjkimACPI_EXPORT_SYMBOL (AcpiRemoveGpeBlock) 1043216331Sjkim 1044216331Sjkim 1045216331Sjkim/******************************************************************************* 1046216331Sjkim * 1047216331Sjkim * FUNCTION: AcpiGetGpeDevice 1048216331Sjkim * 1049216331Sjkim * PARAMETERS: Index - System GPE index (0-CurrentGpeCount) 1050216331Sjkim * GpeDevice - Where the parent GPE Device is returned 1051216331Sjkim * 1052216331Sjkim * RETURN: Status 1053216331Sjkim * 1054216331Sjkim * DESCRIPTION: Obtain the GPE device associated with the input index. A NULL 1055216331Sjkim * gpe device indicates that the gpe number is contained in one of 1056216331Sjkim * the FADT-defined gpe blocks. Otherwise, the GPE block device. 1057216331Sjkim * 1058216331Sjkim ******************************************************************************/ 1059216331Sjkim 1060216331SjkimACPI_STATUS 1061216331SjkimAcpiGetGpeDevice ( 1062216331Sjkim UINT32 Index, 1063216331Sjkim ACPI_HANDLE *GpeDevice) 1064216331Sjkim{ 1065216331Sjkim ACPI_GPE_DEVICE_INFO Info; 1066216331Sjkim ACPI_STATUS Status; 1067216331Sjkim 1068216331Sjkim 1069216331Sjkim ACPI_FUNCTION_TRACE (AcpiGetGpeDevice); 1070216331Sjkim 1071216331Sjkim 1072216331Sjkim if (!GpeDevice) 1073216331Sjkim { 1074216331Sjkim return_ACPI_STATUS (AE_BAD_PARAMETER); 1075216331Sjkim } 1076216331Sjkim 1077216331Sjkim if (Index >= AcpiCurrentGpeCount) 1078216331Sjkim { 1079216331Sjkim return_ACPI_STATUS (AE_NOT_EXIST); 1080216331Sjkim } 1081216331Sjkim 1082216331Sjkim /* Setup and walk the GPE list */ 1083216331Sjkim 1084216331Sjkim Info.Index = Index; 1085216331Sjkim Info.Status = AE_NOT_EXIST; 1086216331Sjkim Info.GpeDevice = NULL; 1087216331Sjkim Info.NextBlockBaseIndex = 0; 1088216331Sjkim 1089216331Sjkim Status = AcpiEvWalkGpeList (AcpiEvGetGpeDevice, &Info); 1090216331Sjkim if (ACPI_FAILURE (Status)) 1091216331Sjkim { 1092216331Sjkim return_ACPI_STATUS (Status); 1093216331Sjkim } 1094216331Sjkim 1095216331Sjkim *GpeDevice = ACPI_CAST_PTR (ACPI_HANDLE, Info.GpeDevice); 1096216331Sjkim return_ACPI_STATUS (Info.Status); 1097216331Sjkim} 1098216331Sjkim 1099216331SjkimACPI_EXPORT_SYMBOL (AcpiGetGpeDevice) 1100231844Sjkim 1101231844Sjkim#endif /* !ACPI_REDUCED_HARDWARE */ 1102