evxfgpe.c revision 272444
1216331Sjkim/****************************************************************************** 2216331Sjkim * 3216331Sjkim * Module Name: evxfgpe - External Interfaces for General Purpose Events (GPEs) 4216331Sjkim * 5216331Sjkim *****************************************************************************/ 6216331Sjkim 7217365Sjkim/* 8272444Sjkim * Copyright (C) 2000 - 2014, 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 44216331Sjkim#define __EVXFGPE_C__ 45272444Sjkim#define EXPORT_ACPI_INTERFACES 46216331Sjkim 47216471Sjkim#include <contrib/dev/acpica/include/acpi.h> 48216471Sjkim#include <contrib/dev/acpica/include/accommon.h> 49216471Sjkim#include <contrib/dev/acpica/include/acevents.h> 50216471Sjkim#include <contrib/dev/acpica/include/acnamesp.h> 51216331Sjkim 52216331Sjkim#define _COMPONENT ACPI_EVENTS 53216331Sjkim ACPI_MODULE_NAME ("evxfgpe") 54216331Sjkim 55216331Sjkim 56231844Sjkim#if (!ACPI_REDUCED_HARDWARE) /* Entire module */ 57216331Sjkim/******************************************************************************* 58216331Sjkim * 59216331Sjkim * FUNCTION: AcpiUpdateAllGpes 60216331Sjkim * 61216331Sjkim * PARAMETERS: None 62216331Sjkim * 63216331Sjkim * RETURN: Status 64216331Sjkim * 65216331Sjkim * DESCRIPTION: Complete GPE initialization and enable all GPEs that have 66216331Sjkim * associated _Lxx or _Exx methods and are not pointed to by any 67216331Sjkim * device _PRW methods (this indicates that these GPEs are 68216331Sjkim * generally intended for system or device wakeup. Such GPEs 69216331Sjkim * have to be enabled directly when the devices whose _PRW 70216331Sjkim * methods point to them are set up for wakeup signaling.) 71216331Sjkim * 72216331Sjkim * NOTE: Should be called after any GPEs are added to the system. Primarily, 73216331Sjkim * after the system _PRW methods have been run, but also after a GPE Block 74216331Sjkim * Device has been added or if any new GPE methods have been added via a 75216331Sjkim * dynamic table load. 76216331Sjkim * 77216331Sjkim ******************************************************************************/ 78216331Sjkim 79216331SjkimACPI_STATUS 80216331SjkimAcpiUpdateAllGpes ( 81216331Sjkim void) 82216331Sjkim{ 83216331Sjkim ACPI_STATUS Status; 84216331Sjkim 85216331Sjkim 86238381Sjkim ACPI_FUNCTION_TRACE (AcpiUpdateAllGpes); 87216331Sjkim 88216331Sjkim 89216331Sjkim Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 90216331Sjkim if (ACPI_FAILURE (Status)) 91216331Sjkim { 92216331Sjkim return_ACPI_STATUS (Status); 93216331Sjkim } 94216331Sjkim 95216331Sjkim if (AcpiGbl_AllGpesInitialized) 96216331Sjkim { 97216331Sjkim goto UnlockAndExit; 98216331Sjkim } 99216331Sjkim 100216331Sjkim Status = AcpiEvWalkGpeList (AcpiEvInitializeGpeBlock, NULL); 101216331Sjkim if (ACPI_SUCCESS (Status)) 102216331Sjkim { 103216331Sjkim AcpiGbl_AllGpesInitialized = TRUE; 104216331Sjkim } 105216331Sjkim 106216331SjkimUnlockAndExit: 107216331Sjkim (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 108216331Sjkim return_ACPI_STATUS (Status); 109216331Sjkim} 110216331Sjkim 111216331SjkimACPI_EXPORT_SYMBOL (AcpiUpdateAllGpes) 112216331Sjkim 113216331Sjkim 114216331Sjkim/******************************************************************************* 115216331Sjkim * 116216331Sjkim * FUNCTION: AcpiEnableGpe 117216331Sjkim * 118216331Sjkim * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1 119216331Sjkim * GpeNumber - GPE level within the GPE block 120216331Sjkim * 121216331Sjkim * RETURN: Status 122216331Sjkim * 123216331Sjkim * DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is 124216331Sjkim * hardware-enabled. 125216331Sjkim * 126216331Sjkim ******************************************************************************/ 127216331Sjkim 128216331SjkimACPI_STATUS 129216331SjkimAcpiEnableGpe ( 130216331Sjkim ACPI_HANDLE GpeDevice, 131216331Sjkim UINT32 GpeNumber) 132216331Sjkim{ 133216331Sjkim ACPI_STATUS Status = AE_BAD_PARAMETER; 134216331Sjkim ACPI_GPE_EVENT_INFO *GpeEventInfo; 135216331Sjkim ACPI_CPU_FLAGS Flags; 136216331Sjkim 137216331Sjkim 138216331Sjkim ACPI_FUNCTION_TRACE (AcpiEnableGpe); 139216331Sjkim 140216331Sjkim 141216331Sjkim Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 142216331Sjkim 143272444Sjkim /* 144272444Sjkim * Ensure that we have a valid GPE number and that there is some way 145272444Sjkim * of handling the GPE (handler or a GPE method). In other words, we 146272444Sjkim * won't allow a valid GPE to be enabled if there is no way to handle it. 147272444Sjkim */ 148216331Sjkim GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 149216331Sjkim if (GpeEventInfo) 150216331Sjkim { 151272444Sjkim if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) != 152272444Sjkim ACPI_GPE_DISPATCH_NONE) 153272444Sjkim { 154272444Sjkim Status = AcpiEvAddGpeReference (GpeEventInfo); 155272444Sjkim } 156272444Sjkim else 157272444Sjkim { 158272444Sjkim Status = AE_NO_HANDLER; 159272444Sjkim } 160216331Sjkim } 161216331Sjkim 162216331Sjkim AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 163216331Sjkim return_ACPI_STATUS (Status); 164216331Sjkim} 165216331Sjkim 166216331SjkimACPI_EXPORT_SYMBOL (AcpiEnableGpe) 167216331Sjkim 168216331Sjkim 169216331Sjkim/******************************************************************************* 170216331Sjkim * 171216331Sjkim * FUNCTION: AcpiDisableGpe 172216331Sjkim * 173216331Sjkim * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1 174216331Sjkim * GpeNumber - GPE level within the GPE block 175216331Sjkim * 176216331Sjkim * RETURN: Status 177216331Sjkim * 178216331Sjkim * DESCRIPTION: Remove a reference to a GPE. When the last reference is 179216331Sjkim * removed, only then is the GPE disabled (for runtime GPEs), or 180216331Sjkim * the GPE mask bit disabled (for wake GPEs) 181216331Sjkim * 182216331Sjkim ******************************************************************************/ 183216331Sjkim 184216331SjkimACPI_STATUS 185216331SjkimAcpiDisableGpe ( 186216331Sjkim ACPI_HANDLE GpeDevice, 187216331Sjkim UINT32 GpeNumber) 188216331Sjkim{ 189216331Sjkim ACPI_STATUS Status = AE_BAD_PARAMETER; 190216331Sjkim ACPI_GPE_EVENT_INFO *GpeEventInfo; 191216331Sjkim ACPI_CPU_FLAGS Flags; 192216331Sjkim 193216331Sjkim 194216331Sjkim ACPI_FUNCTION_TRACE (AcpiDisableGpe); 195216331Sjkim 196216331Sjkim 197216331Sjkim Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 198216331Sjkim 199216331Sjkim /* Ensure that we have a valid GPE number */ 200216331Sjkim 201216331Sjkim GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 202216331Sjkim if (GpeEventInfo) 203216331Sjkim { 204216331Sjkim Status = AcpiEvRemoveGpeReference (GpeEventInfo); 205216331Sjkim } 206216331Sjkim 207216331Sjkim AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 208216331Sjkim return_ACPI_STATUS (Status); 209216331Sjkim} 210216331Sjkim 211216331SjkimACPI_EXPORT_SYMBOL (AcpiDisableGpe) 212216331Sjkim 213216331Sjkim 214216331Sjkim/******************************************************************************* 215216331Sjkim * 216216331Sjkim * FUNCTION: AcpiSetGpe 217216331Sjkim * 218216331Sjkim * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1 219216331Sjkim * GpeNumber - GPE level within the GPE block 220216331Sjkim * Action - ACPI_GPE_ENABLE or ACPI_GPE_DISABLE 221216331Sjkim * 222216331Sjkim * RETURN: Status 223216331Sjkim * 224216331Sjkim * DESCRIPTION: Enable or disable an individual GPE. This function bypasses 225216331Sjkim * the reference count mechanism used in the AcpiEnableGpe and 226216331Sjkim * AcpiDisableGpe interfaces -- and should be used with care. 227216331Sjkim * 228216331Sjkim * Note: Typically used to disable a runtime GPE for short period of time, 229216331Sjkim * then re-enable it, without disturbing the existing reference counts. This 230216331Sjkim * is useful, for example, in the Embedded Controller (EC) driver. 231216331Sjkim * 232216331Sjkim ******************************************************************************/ 233216331Sjkim 234216331SjkimACPI_STATUS 235216331SjkimAcpiSetGpe ( 236216331Sjkim ACPI_HANDLE GpeDevice, 237216331Sjkim UINT32 GpeNumber, 238216331Sjkim UINT8 Action) 239216331Sjkim{ 240216331Sjkim ACPI_GPE_EVENT_INFO *GpeEventInfo; 241216331Sjkim ACPI_STATUS Status; 242216331Sjkim ACPI_CPU_FLAGS Flags; 243216331Sjkim 244216331Sjkim 245216331Sjkim ACPI_FUNCTION_TRACE (AcpiSetGpe); 246216331Sjkim 247216331Sjkim 248216331Sjkim Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 249216331Sjkim 250216331Sjkim /* Ensure that we have a valid GPE number */ 251216331Sjkim 252216331Sjkim GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 253216331Sjkim if (!GpeEventInfo) 254216331Sjkim { 255216331Sjkim Status = AE_BAD_PARAMETER; 256216331Sjkim goto UnlockAndExit; 257216331Sjkim } 258216331Sjkim 259216331Sjkim /* Perform the action */ 260216331Sjkim 261216331Sjkim switch (Action) 262216331Sjkim { 263216331Sjkim case ACPI_GPE_ENABLE: 264250838Sjkim 265216331Sjkim Status = AcpiEvEnableGpe (GpeEventInfo); 266216331Sjkim break; 267216331Sjkim 268216331Sjkim case ACPI_GPE_DISABLE: 269250838Sjkim 270216331Sjkim Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_DISABLE); 271216331Sjkim break; 272216331Sjkim 273216331Sjkim default: 274250838Sjkim 275216331Sjkim Status = AE_BAD_PARAMETER; 276216331Sjkim break; 277216331Sjkim } 278216331Sjkim 279216331SjkimUnlockAndExit: 280216331Sjkim AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 281216331Sjkim return_ACPI_STATUS (Status); 282216331Sjkim} 283216331Sjkim 284216331SjkimACPI_EXPORT_SYMBOL (AcpiSetGpe) 285216331Sjkim 286216331Sjkim 287216331Sjkim/******************************************************************************* 288216331Sjkim * 289272444Sjkim * FUNCTION: AcpiMarkGpeForWake 290272444Sjkim * 291272444Sjkim * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1 292272444Sjkim * GpeNumber - GPE level within the GPE block 293272444Sjkim * 294272444Sjkim * RETURN: Status 295272444Sjkim * 296272444Sjkim * DESCRIPTION: Mark a GPE as having the ability to wake the system. Simply 297272444Sjkim * sets the ACPI_GPE_CAN_WAKE flag. 298272444Sjkim * 299272444Sjkim * Some potential callers of AcpiSetupGpeForWake may know in advance that 300272444Sjkim * there won't be any notify handlers installed for device wake notifications 301272444Sjkim * from the given GPE (one example is a button GPE in Linux). For these cases, 302272444Sjkim * AcpiMarkGpeForWake should be used instead of AcpiSetupGpeForWake. 303272444Sjkim * This will set the ACPI_GPE_CAN_WAKE flag for the GPE without trying to 304272444Sjkim * setup implicit wake notification for it (since there's no handler method). 305272444Sjkim * 306272444Sjkim ******************************************************************************/ 307272444Sjkim 308272444SjkimACPI_STATUS 309272444SjkimAcpiMarkGpeForWake ( 310272444Sjkim ACPI_HANDLE GpeDevice, 311272444Sjkim UINT32 GpeNumber) 312272444Sjkim{ 313272444Sjkim ACPI_GPE_EVENT_INFO *GpeEventInfo; 314272444Sjkim ACPI_STATUS Status = AE_BAD_PARAMETER; 315272444Sjkim ACPI_CPU_FLAGS Flags; 316272444Sjkim 317272444Sjkim 318272444Sjkim ACPI_FUNCTION_TRACE (AcpiMarkGpeForWake); 319272444Sjkim 320272444Sjkim 321272444Sjkim Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 322272444Sjkim 323272444Sjkim /* Ensure that we have a valid GPE number */ 324272444Sjkim 325272444Sjkim GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 326272444Sjkim if (GpeEventInfo) 327272444Sjkim { 328272444Sjkim /* Mark the GPE as a possible wake event */ 329272444Sjkim 330272444Sjkim GpeEventInfo->Flags |= ACPI_GPE_CAN_WAKE; 331272444Sjkim Status = AE_OK; 332272444Sjkim } 333272444Sjkim 334272444Sjkim AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 335272444Sjkim return_ACPI_STATUS (Status); 336272444Sjkim} 337272444Sjkim 338272444SjkimACPI_EXPORT_SYMBOL (AcpiMarkGpeForWake) 339272444Sjkim 340272444Sjkim 341272444Sjkim/******************************************************************************* 342272444Sjkim * 343216331Sjkim * FUNCTION: AcpiSetupGpeForWake 344216331Sjkim * 345216331Sjkim * PARAMETERS: WakeDevice - Device associated with the GPE (via _PRW) 346216331Sjkim * GpeDevice - Parent GPE Device. NULL for GPE0/GPE1 347216331Sjkim * GpeNumber - GPE level within the GPE block 348216331Sjkim * 349216331Sjkim * RETURN: Status 350216331Sjkim * 351216331Sjkim * DESCRIPTION: Mark a GPE as having the ability to wake the system. This 352216331Sjkim * interface is intended to be used as the host executes the 353216331Sjkim * _PRW methods (Power Resources for Wake) in the system tables. 354216331Sjkim * Each _PRW appears under a Device Object (The WakeDevice), and 355216331Sjkim * contains the info for the wake GPE associated with the 356216331Sjkim * WakeDevice. 357216331Sjkim * 358216331Sjkim ******************************************************************************/ 359216331Sjkim 360216331SjkimACPI_STATUS 361216331SjkimAcpiSetupGpeForWake ( 362216331Sjkim ACPI_HANDLE WakeDevice, 363216331Sjkim ACPI_HANDLE GpeDevice, 364216331Sjkim UINT32 GpeNumber) 365216331Sjkim{ 366237412Sjkim ACPI_STATUS Status; 367216331Sjkim ACPI_GPE_EVENT_INFO *GpeEventInfo; 368216331Sjkim ACPI_NAMESPACE_NODE *DeviceNode; 369238381Sjkim ACPI_GPE_NOTIFY_INFO *Notify; 370238381Sjkim ACPI_GPE_NOTIFY_INFO *NewNotify; 371216331Sjkim ACPI_CPU_FLAGS Flags; 372216331Sjkim 373216331Sjkim 374216331Sjkim ACPI_FUNCTION_TRACE (AcpiSetupGpeForWake); 375216331Sjkim 376216331Sjkim 377216331Sjkim /* Parameter Validation */ 378216331Sjkim 379216331Sjkim if (!WakeDevice) 380216331Sjkim { 381216331Sjkim /* 382216331Sjkim * By forcing WakeDevice to be valid, we automatically enable the 383216331Sjkim * implicit notify feature on all hosts. 384216331Sjkim */ 385216331Sjkim return_ACPI_STATUS (AE_BAD_PARAMETER); 386216331Sjkim } 387216331Sjkim 388219707Sjkim /* Handle root object case */ 389219707Sjkim 390219707Sjkim if (WakeDevice == ACPI_ROOT_OBJECT) 391219707Sjkim { 392219707Sjkim DeviceNode = AcpiGbl_RootNode; 393219707Sjkim } 394219707Sjkim else 395219707Sjkim { 396219707Sjkim DeviceNode = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, WakeDevice); 397219707Sjkim } 398219707Sjkim 399216331Sjkim /* Validate WakeDevice is of type Device */ 400216331Sjkim 401216331Sjkim if (DeviceNode->Type != ACPI_TYPE_DEVICE) 402216331Sjkim { 403216331Sjkim return_ACPI_STATUS (AE_BAD_PARAMETER); 404216331Sjkim } 405216331Sjkim 406238381Sjkim /* 407238381Sjkim * Allocate a new notify object up front, in case it is needed. 408238381Sjkim * Memory allocation while holding a spinlock is a big no-no 409238381Sjkim * on some hosts. 410238381Sjkim */ 411237652Sjkim NewNotify = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_GPE_NOTIFY_INFO)); 412237652Sjkim if (!NewNotify) 413237652Sjkim { 414237652Sjkim return_ACPI_STATUS (AE_NO_MEMORY); 415237652Sjkim } 416237652Sjkim 417216331Sjkim Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 418216331Sjkim 419216331Sjkim /* Ensure that we have a valid GPE number */ 420216331Sjkim 421216331Sjkim GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 422237412Sjkim if (!GpeEventInfo) 423216331Sjkim { 424237412Sjkim Status = AE_BAD_PARAMETER; 425237412Sjkim goto UnlockAndExit; 426237412Sjkim } 427237412Sjkim 428237412Sjkim /* 429237412Sjkim * If there is no method or handler for this GPE, then the 430237412Sjkim * WakeDevice will be notified whenever this GPE fires. This is 431237412Sjkim * known as an "implicit notify". Note: The GPE is assumed to be 432237412Sjkim * level-triggered (for windows compatibility). 433237412Sjkim */ 434237412Sjkim if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) == 435237412Sjkim ACPI_GPE_DISPATCH_NONE) 436237412Sjkim { 437216331Sjkim /* 438237412Sjkim * This is the first device for implicit notify on this GPE. 439237412Sjkim * Just set the flags here, and enter the NOTIFY block below. 440216331Sjkim */ 441237412Sjkim GpeEventInfo->Flags = 442237412Sjkim (ACPI_GPE_DISPATCH_NOTIFY | ACPI_GPE_LEVEL_TRIGGERED); 443237412Sjkim } 444237412Sjkim 445237412Sjkim /* 446237412Sjkim * If we already have an implicit notify on this GPE, add 447237412Sjkim * this device to the notify list. 448237412Sjkim */ 449237412Sjkim if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) == 450237412Sjkim ACPI_GPE_DISPATCH_NOTIFY) 451237412Sjkim { 452237412Sjkim /* Ensure that the device is not already in the list */ 453237412Sjkim 454237412Sjkim Notify = GpeEventInfo->Dispatch.NotifyList; 455237412Sjkim while (Notify) 456216331Sjkim { 457237412Sjkim if (Notify->DeviceNode == DeviceNode) 458237412Sjkim { 459237412Sjkim Status = AE_ALREADY_EXISTS; 460237412Sjkim goto UnlockAndExit; 461237412Sjkim } 462237412Sjkim Notify = Notify->Next; 463216331Sjkim } 464216331Sjkim 465237412Sjkim /* Add this device to the notify list for this GPE */ 466237412Sjkim 467237652Sjkim NewNotify->DeviceNode = DeviceNode; 468237652Sjkim NewNotify->Next = GpeEventInfo->Dispatch.NotifyList; 469237652Sjkim GpeEventInfo->Dispatch.NotifyList = NewNotify; 470237652Sjkim NewNotify = NULL; 471216331Sjkim } 472216331Sjkim 473237412Sjkim /* Mark the GPE as a possible wake event */ 474237412Sjkim 475237412Sjkim GpeEventInfo->Flags |= ACPI_GPE_CAN_WAKE; 476237412Sjkim Status = AE_OK; 477237412Sjkim 478238381Sjkim 479237412SjkimUnlockAndExit: 480216331Sjkim AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 481238381Sjkim 482238381Sjkim /* Delete the notify object if it was not used above */ 483238381Sjkim 484237652Sjkim if (NewNotify) 485237652Sjkim { 486237652Sjkim ACPI_FREE (NewNotify); 487237652Sjkim } 488216331Sjkim return_ACPI_STATUS (Status); 489216331Sjkim} 490216331Sjkim 491216331SjkimACPI_EXPORT_SYMBOL (AcpiSetupGpeForWake) 492216331Sjkim 493216331Sjkim 494216331Sjkim/******************************************************************************* 495216331Sjkim * 496216331Sjkim * FUNCTION: AcpiSetGpeWakeMask 497216331Sjkim * 498216331Sjkim * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1 499216331Sjkim * GpeNumber - GPE level within the GPE block 500216331Sjkim * Action - Enable or Disable 501216331Sjkim * 502216331Sjkim * RETURN: Status 503216331Sjkim * 504216331Sjkim * DESCRIPTION: Set or clear the GPE's wakeup enable mask bit. The GPE must 505216331Sjkim * already be marked as a WAKE GPE. 506216331Sjkim * 507216331Sjkim ******************************************************************************/ 508216331Sjkim 509216331SjkimACPI_STATUS 510216331SjkimAcpiSetGpeWakeMask ( 511216331Sjkim ACPI_HANDLE GpeDevice, 512216331Sjkim UINT32 GpeNumber, 513216331Sjkim UINT8 Action) 514216331Sjkim{ 515216331Sjkim ACPI_STATUS Status = AE_OK; 516216331Sjkim ACPI_GPE_EVENT_INFO *GpeEventInfo; 517216331Sjkim ACPI_GPE_REGISTER_INFO *GpeRegisterInfo; 518216331Sjkim ACPI_CPU_FLAGS Flags; 519216331Sjkim UINT32 RegisterBit; 520216331Sjkim 521216331Sjkim 522216331Sjkim ACPI_FUNCTION_TRACE (AcpiSetGpeWakeMask); 523216331Sjkim 524216331Sjkim 525216331Sjkim Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 526216331Sjkim 527216331Sjkim /* 528216331Sjkim * Ensure that we have a valid GPE number and that this GPE is in 529216331Sjkim * fact a wake GPE 530216331Sjkim */ 531216331Sjkim GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 532216331Sjkim if (!GpeEventInfo) 533216331Sjkim { 534216331Sjkim Status = AE_BAD_PARAMETER; 535216331Sjkim goto UnlockAndExit; 536216331Sjkim } 537216331Sjkim 538216331Sjkim if (!(GpeEventInfo->Flags & ACPI_GPE_CAN_WAKE)) 539216331Sjkim { 540216331Sjkim Status = AE_TYPE; 541216331Sjkim goto UnlockAndExit; 542216331Sjkim } 543216331Sjkim 544216331Sjkim GpeRegisterInfo = GpeEventInfo->RegisterInfo; 545216331Sjkim if (!GpeRegisterInfo) 546216331Sjkim { 547216331Sjkim Status = AE_NOT_EXIST; 548216331Sjkim goto UnlockAndExit; 549216331Sjkim } 550216331Sjkim 551239340Sjkim RegisterBit = AcpiHwGetGpeRegisterBit (GpeEventInfo); 552216331Sjkim 553216331Sjkim /* Perform the action */ 554216331Sjkim 555216331Sjkim switch (Action) 556216331Sjkim { 557216331Sjkim case ACPI_GPE_ENABLE: 558250838Sjkim 559216331Sjkim ACPI_SET_BIT (GpeRegisterInfo->EnableForWake, (UINT8) RegisterBit); 560216331Sjkim break; 561216331Sjkim 562216331Sjkim case ACPI_GPE_DISABLE: 563250838Sjkim 564216331Sjkim ACPI_CLEAR_BIT (GpeRegisterInfo->EnableForWake, (UINT8) RegisterBit); 565216331Sjkim break; 566216331Sjkim 567216331Sjkim default: 568250838Sjkim 569216331Sjkim ACPI_ERROR ((AE_INFO, "%u, Invalid action", Action)); 570216331Sjkim Status = AE_BAD_PARAMETER; 571216331Sjkim break; 572216331Sjkim } 573216331Sjkim 574216331SjkimUnlockAndExit: 575216331Sjkim AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 576216331Sjkim return_ACPI_STATUS (Status); 577216331Sjkim} 578216331Sjkim 579216331SjkimACPI_EXPORT_SYMBOL (AcpiSetGpeWakeMask) 580216331Sjkim 581216331Sjkim 582216331Sjkim/******************************************************************************* 583216331Sjkim * 584216331Sjkim * FUNCTION: AcpiClearGpe 585216331Sjkim * 586216331Sjkim * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1 587216331Sjkim * GpeNumber - GPE level within the GPE block 588216331Sjkim * 589216331Sjkim * RETURN: Status 590216331Sjkim * 591216331Sjkim * DESCRIPTION: Clear an ACPI event (general purpose) 592216331Sjkim * 593216331Sjkim ******************************************************************************/ 594216331Sjkim 595216331SjkimACPI_STATUS 596216331SjkimAcpiClearGpe ( 597216331Sjkim ACPI_HANDLE GpeDevice, 598216331Sjkim UINT32 GpeNumber) 599216331Sjkim{ 600216331Sjkim ACPI_STATUS Status = AE_OK; 601216331Sjkim ACPI_GPE_EVENT_INFO *GpeEventInfo; 602216331Sjkim ACPI_CPU_FLAGS Flags; 603216331Sjkim 604216331Sjkim 605216331Sjkim ACPI_FUNCTION_TRACE (AcpiClearGpe); 606216331Sjkim 607216331Sjkim 608216331Sjkim Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 609216331Sjkim 610216331Sjkim /* Ensure that we have a valid GPE number */ 611216331Sjkim 612216331Sjkim GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 613216331Sjkim if (!GpeEventInfo) 614216331Sjkim { 615216331Sjkim Status = AE_BAD_PARAMETER; 616216331Sjkim goto UnlockAndExit; 617216331Sjkim } 618216331Sjkim 619216331Sjkim Status = AcpiHwClearGpe (GpeEventInfo); 620216331Sjkim 621216331SjkimUnlockAndExit: 622216331Sjkim AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 623216331Sjkim return_ACPI_STATUS (Status); 624216331Sjkim} 625216331Sjkim 626216331SjkimACPI_EXPORT_SYMBOL (AcpiClearGpe) 627216331Sjkim 628216331Sjkim 629216331Sjkim/******************************************************************************* 630216331Sjkim * 631216331Sjkim * FUNCTION: AcpiGetGpeStatus 632216331Sjkim * 633216331Sjkim * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1 634216331Sjkim * GpeNumber - GPE level within the GPE block 635216331Sjkim * EventStatus - Where the current status of the event 636216331Sjkim * will be returned 637216331Sjkim * 638216331Sjkim * RETURN: Status 639216331Sjkim * 640216331Sjkim * DESCRIPTION: Get the current status of a GPE (signalled/not_signalled) 641216331Sjkim * 642216331Sjkim ******************************************************************************/ 643216331Sjkim 644216331SjkimACPI_STATUS 645216331SjkimAcpiGetGpeStatus ( 646216331Sjkim ACPI_HANDLE GpeDevice, 647216331Sjkim UINT32 GpeNumber, 648216331Sjkim ACPI_EVENT_STATUS *EventStatus) 649216331Sjkim{ 650216331Sjkim ACPI_STATUS Status = AE_OK; 651216331Sjkim ACPI_GPE_EVENT_INFO *GpeEventInfo; 652216331Sjkim ACPI_CPU_FLAGS Flags; 653216331Sjkim 654216331Sjkim 655216331Sjkim ACPI_FUNCTION_TRACE (AcpiGetGpeStatus); 656216331Sjkim 657216331Sjkim 658216331Sjkim Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 659216331Sjkim 660216331Sjkim /* Ensure that we have a valid GPE number */ 661216331Sjkim 662216331Sjkim GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 663216331Sjkim if (!GpeEventInfo) 664216331Sjkim { 665216331Sjkim Status = AE_BAD_PARAMETER; 666216331Sjkim goto UnlockAndExit; 667216331Sjkim } 668216331Sjkim 669216331Sjkim /* Obtain status on the requested GPE number */ 670216331Sjkim 671216331Sjkim Status = AcpiHwGetGpeStatus (GpeEventInfo, EventStatus); 672216331Sjkim 673216331SjkimUnlockAndExit: 674216331Sjkim AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 675216331Sjkim return_ACPI_STATUS (Status); 676216331Sjkim} 677216331Sjkim 678216331SjkimACPI_EXPORT_SYMBOL (AcpiGetGpeStatus) 679216331Sjkim 680216331Sjkim 681216331Sjkim/******************************************************************************* 682216331Sjkim * 683216331Sjkim * FUNCTION: AcpiFinishGpe 684216331Sjkim * 685216331Sjkim * PARAMETERS: GpeDevice - Namespace node for the GPE Block 686216331Sjkim * (NULL for FADT defined GPEs) 687216331Sjkim * GpeNumber - GPE level within the GPE block 688216331Sjkim * 689216331Sjkim * RETURN: Status 690216331Sjkim * 691216331Sjkim * DESCRIPTION: Clear and conditionally reenable a GPE. This completes the GPE 692216331Sjkim * processing. Intended for use by asynchronous host-installed 693216331Sjkim * GPE handlers. The GPE is only reenabled if the EnableForRun bit 694216331Sjkim * is set in the GPE info. 695216331Sjkim * 696216331Sjkim ******************************************************************************/ 697216331Sjkim 698216331SjkimACPI_STATUS 699216331SjkimAcpiFinishGpe ( 700216331Sjkim ACPI_HANDLE GpeDevice, 701216331Sjkim UINT32 GpeNumber) 702216331Sjkim{ 703216331Sjkim ACPI_GPE_EVENT_INFO *GpeEventInfo; 704216331Sjkim ACPI_STATUS Status; 705216331Sjkim ACPI_CPU_FLAGS Flags; 706216331Sjkim 707216331Sjkim 708216331Sjkim ACPI_FUNCTION_TRACE (AcpiFinishGpe); 709216331Sjkim 710216331Sjkim 711216331Sjkim Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 712216331Sjkim 713216331Sjkim /* Ensure that we have a valid GPE number */ 714216331Sjkim 715216331Sjkim GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 716216331Sjkim if (!GpeEventInfo) 717216331Sjkim { 718216331Sjkim Status = AE_BAD_PARAMETER; 719216331Sjkim goto UnlockAndExit; 720216331Sjkim } 721216331Sjkim 722216331Sjkim Status = AcpiEvFinishGpe (GpeEventInfo); 723216331Sjkim 724216331SjkimUnlockAndExit: 725216331Sjkim AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 726216331Sjkim return_ACPI_STATUS (Status); 727216331Sjkim} 728216331Sjkim 729216331SjkimACPI_EXPORT_SYMBOL (AcpiFinishGpe) 730216331Sjkim 731216331Sjkim 732216331Sjkim/****************************************************************************** 733216331Sjkim * 734216331Sjkim * FUNCTION: AcpiDisableAllGpes 735216331Sjkim * 736216331Sjkim * PARAMETERS: None 737216331Sjkim * 738216331Sjkim * RETURN: Status 739216331Sjkim * 740216331Sjkim * DESCRIPTION: Disable and clear all GPEs in all GPE blocks 741216331Sjkim * 742216331Sjkim ******************************************************************************/ 743216331Sjkim 744216331SjkimACPI_STATUS 745216331SjkimAcpiDisableAllGpes ( 746216331Sjkim void) 747216331Sjkim{ 748216331Sjkim ACPI_STATUS Status; 749216331Sjkim 750216331Sjkim 751216331Sjkim ACPI_FUNCTION_TRACE (AcpiDisableAllGpes); 752216331Sjkim 753216331Sjkim 754216331Sjkim Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 755216331Sjkim if (ACPI_FAILURE (Status)) 756216331Sjkim { 757216331Sjkim return_ACPI_STATUS (Status); 758216331Sjkim } 759216331Sjkim 760216331Sjkim Status = AcpiHwDisableAllGpes (); 761216331Sjkim (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 762216331Sjkim 763216331Sjkim return_ACPI_STATUS (Status); 764216331Sjkim} 765216331Sjkim 766216331SjkimACPI_EXPORT_SYMBOL (AcpiDisableAllGpes) 767216331Sjkim 768216331Sjkim 769216331Sjkim/****************************************************************************** 770216331Sjkim * 771216331Sjkim * FUNCTION: AcpiEnableAllRuntimeGpes 772216331Sjkim * 773216331Sjkim * PARAMETERS: None 774216331Sjkim * 775216331Sjkim * RETURN: Status 776216331Sjkim * 777216331Sjkim * DESCRIPTION: Enable all "runtime" GPEs, in all GPE blocks 778216331Sjkim * 779216331Sjkim ******************************************************************************/ 780216331Sjkim 781216331SjkimACPI_STATUS 782216331SjkimAcpiEnableAllRuntimeGpes ( 783216331Sjkim void) 784216331Sjkim{ 785216331Sjkim ACPI_STATUS Status; 786216331Sjkim 787216331Sjkim 788216331Sjkim ACPI_FUNCTION_TRACE (AcpiEnableAllRuntimeGpes); 789216331Sjkim 790216331Sjkim 791216331Sjkim Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 792216331Sjkim if (ACPI_FAILURE (Status)) 793216331Sjkim { 794216331Sjkim return_ACPI_STATUS (Status); 795216331Sjkim } 796216331Sjkim 797216331Sjkim Status = AcpiHwEnableAllRuntimeGpes (); 798216331Sjkim (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 799216331Sjkim 800216331Sjkim return_ACPI_STATUS (Status); 801216331Sjkim} 802216331Sjkim 803216331SjkimACPI_EXPORT_SYMBOL (AcpiEnableAllRuntimeGpes) 804216331Sjkim 805216331Sjkim 806216331Sjkim/******************************************************************************* 807216331Sjkim * 808216331Sjkim * FUNCTION: AcpiInstallGpeBlock 809216331Sjkim * 810216331Sjkim * PARAMETERS: GpeDevice - Handle to the parent GPE Block Device 811216331Sjkim * GpeBlockAddress - Address and SpaceID 812216331Sjkim * RegisterCount - Number of GPE register pairs in the block 813216331Sjkim * InterruptNumber - H/W interrupt for the block 814216331Sjkim * 815216331Sjkim * RETURN: Status 816216331Sjkim * 817216331Sjkim * DESCRIPTION: Create and Install a block of GPE registers. The GPEs are not 818216331Sjkim * enabled here. 819216331Sjkim * 820216331Sjkim ******************************************************************************/ 821216331Sjkim 822216331SjkimACPI_STATUS 823216331SjkimAcpiInstallGpeBlock ( 824216331Sjkim ACPI_HANDLE GpeDevice, 825216331Sjkim ACPI_GENERIC_ADDRESS *GpeBlockAddress, 826216331Sjkim UINT32 RegisterCount, 827216331Sjkim UINT32 InterruptNumber) 828216331Sjkim{ 829216331Sjkim ACPI_STATUS Status; 830216331Sjkim ACPI_OPERAND_OBJECT *ObjDesc; 831216331Sjkim ACPI_NAMESPACE_NODE *Node; 832216331Sjkim ACPI_GPE_BLOCK_INFO *GpeBlock; 833216331Sjkim 834216331Sjkim 835216331Sjkim ACPI_FUNCTION_TRACE (AcpiInstallGpeBlock); 836216331Sjkim 837216331Sjkim 838216331Sjkim if ((!GpeDevice) || 839216331Sjkim (!GpeBlockAddress) || 840216331Sjkim (!RegisterCount)) 841216331Sjkim { 842216331Sjkim return_ACPI_STATUS (AE_BAD_PARAMETER); 843216331Sjkim } 844216331Sjkim 845216331Sjkim Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 846216331Sjkim if (ACPI_FAILURE (Status)) 847216331Sjkim { 848241973Sjkim return_ACPI_STATUS (Status); 849216331Sjkim } 850216331Sjkim 851216331Sjkim Node = AcpiNsValidateHandle (GpeDevice); 852216331Sjkim if (!Node) 853216331Sjkim { 854216331Sjkim Status = AE_BAD_PARAMETER; 855216331Sjkim goto UnlockAndExit; 856216331Sjkim } 857216331Sjkim 858272444Sjkim /* Validate the parent device */ 859272444Sjkim 860272444Sjkim if (Node->Type != ACPI_TYPE_DEVICE) 861272444Sjkim { 862272444Sjkim Status = AE_TYPE; 863272444Sjkim goto UnlockAndExit; 864272444Sjkim } 865272444Sjkim 866272444Sjkim if (Node->Object) 867272444Sjkim { 868272444Sjkim Status = AE_ALREADY_EXISTS; 869272444Sjkim goto UnlockAndExit; 870272444Sjkim } 871272444Sjkim 872216331Sjkim /* 873216331Sjkim * For user-installed GPE Block Devices, the GpeBlockBaseNumber 874216331Sjkim * is always zero 875216331Sjkim */ 876272444Sjkim Status = AcpiEvCreateGpeBlock (Node, GpeBlockAddress->Address, 877272444Sjkim GpeBlockAddress->SpaceId, RegisterCount, 878216331Sjkim 0, InterruptNumber, &GpeBlock); 879216331Sjkim if (ACPI_FAILURE (Status)) 880216331Sjkim { 881216331Sjkim goto UnlockAndExit; 882216331Sjkim } 883216331Sjkim 884216331Sjkim /* Install block in the DeviceObject attached to the node */ 885216331Sjkim 886216331Sjkim ObjDesc = AcpiNsGetAttachedObject (Node); 887216331Sjkim if (!ObjDesc) 888216331Sjkim { 889216331Sjkim /* 890216331Sjkim * No object, create a new one (Device nodes do not always have 891216331Sjkim * an attached object) 892216331Sjkim */ 893216331Sjkim ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_DEVICE); 894216331Sjkim if (!ObjDesc) 895216331Sjkim { 896216331Sjkim Status = AE_NO_MEMORY; 897216331Sjkim goto UnlockAndExit; 898216331Sjkim } 899216331Sjkim 900216331Sjkim Status = AcpiNsAttachObject (Node, ObjDesc, ACPI_TYPE_DEVICE); 901216331Sjkim 902216331Sjkim /* Remove local reference to the object */ 903216331Sjkim 904216331Sjkim AcpiUtRemoveReference (ObjDesc); 905216331Sjkim if (ACPI_FAILURE (Status)) 906216331Sjkim { 907216331Sjkim goto UnlockAndExit; 908216331Sjkim } 909216331Sjkim } 910216331Sjkim 911216331Sjkim /* Now install the GPE block in the DeviceObject */ 912216331Sjkim 913216331Sjkim ObjDesc->Device.GpeBlock = GpeBlock; 914216331Sjkim 915216331Sjkim 916216331SjkimUnlockAndExit: 917216331Sjkim (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 918216331Sjkim return_ACPI_STATUS (Status); 919216331Sjkim} 920216331Sjkim 921216331SjkimACPI_EXPORT_SYMBOL (AcpiInstallGpeBlock) 922216331Sjkim 923216331Sjkim 924216331Sjkim/******************************************************************************* 925216331Sjkim * 926216331Sjkim * FUNCTION: AcpiRemoveGpeBlock 927216331Sjkim * 928216331Sjkim * PARAMETERS: GpeDevice - Handle to the parent GPE Block Device 929216331Sjkim * 930216331Sjkim * RETURN: Status 931216331Sjkim * 932216331Sjkim * DESCRIPTION: Remove a previously installed block of GPE registers 933216331Sjkim * 934216331Sjkim ******************************************************************************/ 935216331Sjkim 936216331SjkimACPI_STATUS 937216331SjkimAcpiRemoveGpeBlock ( 938216331Sjkim ACPI_HANDLE GpeDevice) 939216331Sjkim{ 940216331Sjkim ACPI_OPERAND_OBJECT *ObjDesc; 941216331Sjkim ACPI_STATUS Status; 942216331Sjkim ACPI_NAMESPACE_NODE *Node; 943216331Sjkim 944216331Sjkim 945216331Sjkim ACPI_FUNCTION_TRACE (AcpiRemoveGpeBlock); 946216331Sjkim 947216331Sjkim 948216331Sjkim if (!GpeDevice) 949216331Sjkim { 950216331Sjkim return_ACPI_STATUS (AE_BAD_PARAMETER); 951216331Sjkim } 952216331Sjkim 953216331Sjkim Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 954216331Sjkim if (ACPI_FAILURE (Status)) 955216331Sjkim { 956241973Sjkim return_ACPI_STATUS (Status); 957216331Sjkim } 958216331Sjkim 959216331Sjkim Node = AcpiNsValidateHandle (GpeDevice); 960216331Sjkim if (!Node) 961216331Sjkim { 962216331Sjkim Status = AE_BAD_PARAMETER; 963216331Sjkim goto UnlockAndExit; 964216331Sjkim } 965216331Sjkim 966272444Sjkim /* Validate the parent device */ 967272444Sjkim 968272444Sjkim if (Node->Type != ACPI_TYPE_DEVICE) 969272444Sjkim { 970272444Sjkim Status = AE_TYPE; 971272444Sjkim goto UnlockAndExit; 972272444Sjkim } 973272444Sjkim 974216331Sjkim /* Get the DeviceObject attached to the node */ 975216331Sjkim 976216331Sjkim ObjDesc = AcpiNsGetAttachedObject (Node); 977216331Sjkim if (!ObjDesc || 978216331Sjkim !ObjDesc->Device.GpeBlock) 979216331Sjkim { 980216331Sjkim return_ACPI_STATUS (AE_NULL_OBJECT); 981216331Sjkim } 982216331Sjkim 983216331Sjkim /* Delete the GPE block (but not the DeviceObject) */ 984216331Sjkim 985216331Sjkim Status = AcpiEvDeleteGpeBlock (ObjDesc->Device.GpeBlock); 986216331Sjkim if (ACPI_SUCCESS (Status)) 987216331Sjkim { 988216331Sjkim ObjDesc->Device.GpeBlock = NULL; 989216331Sjkim } 990216331Sjkim 991216331SjkimUnlockAndExit: 992216331Sjkim (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 993216331Sjkim return_ACPI_STATUS (Status); 994216331Sjkim} 995216331Sjkim 996216331SjkimACPI_EXPORT_SYMBOL (AcpiRemoveGpeBlock) 997216331Sjkim 998216331Sjkim 999216331Sjkim/******************************************************************************* 1000216331Sjkim * 1001216331Sjkim * FUNCTION: AcpiGetGpeDevice 1002216331Sjkim * 1003216331Sjkim * PARAMETERS: Index - System GPE index (0-CurrentGpeCount) 1004216331Sjkim * GpeDevice - Where the parent GPE Device is returned 1005216331Sjkim * 1006216331Sjkim * RETURN: Status 1007216331Sjkim * 1008216331Sjkim * DESCRIPTION: Obtain the GPE device associated with the input index. A NULL 1009216331Sjkim * gpe device indicates that the gpe number is contained in one of 1010216331Sjkim * the FADT-defined gpe blocks. Otherwise, the GPE block device. 1011216331Sjkim * 1012216331Sjkim ******************************************************************************/ 1013216331Sjkim 1014216331SjkimACPI_STATUS 1015216331SjkimAcpiGetGpeDevice ( 1016216331Sjkim UINT32 Index, 1017216331Sjkim ACPI_HANDLE *GpeDevice) 1018216331Sjkim{ 1019216331Sjkim ACPI_GPE_DEVICE_INFO Info; 1020216331Sjkim ACPI_STATUS Status; 1021216331Sjkim 1022216331Sjkim 1023216331Sjkim ACPI_FUNCTION_TRACE (AcpiGetGpeDevice); 1024216331Sjkim 1025216331Sjkim 1026216331Sjkim if (!GpeDevice) 1027216331Sjkim { 1028216331Sjkim return_ACPI_STATUS (AE_BAD_PARAMETER); 1029216331Sjkim } 1030216331Sjkim 1031216331Sjkim if (Index >= AcpiCurrentGpeCount) 1032216331Sjkim { 1033216331Sjkim return_ACPI_STATUS (AE_NOT_EXIST); 1034216331Sjkim } 1035216331Sjkim 1036216331Sjkim /* Setup and walk the GPE list */ 1037216331Sjkim 1038216331Sjkim Info.Index = Index; 1039216331Sjkim Info.Status = AE_NOT_EXIST; 1040216331Sjkim Info.GpeDevice = NULL; 1041216331Sjkim Info.NextBlockBaseIndex = 0; 1042216331Sjkim 1043216331Sjkim Status = AcpiEvWalkGpeList (AcpiEvGetGpeDevice, &Info); 1044216331Sjkim if (ACPI_FAILURE (Status)) 1045216331Sjkim { 1046216331Sjkim return_ACPI_STATUS (Status); 1047216331Sjkim } 1048216331Sjkim 1049216331Sjkim *GpeDevice = ACPI_CAST_PTR (ACPI_HANDLE, Info.GpeDevice); 1050216331Sjkim return_ACPI_STATUS (Info.Status); 1051216331Sjkim} 1052216331Sjkim 1053216331SjkimACPI_EXPORT_SYMBOL (AcpiGetGpeDevice) 1054231844Sjkim 1055231844Sjkim#endif /* !ACPI_REDUCED_HARDWARE */ 1056