1216331Sjkim/****************************************************************************** 2216331Sjkim * 3216331Sjkim * Module Name: evxfgpe - External Interfaces for General Purpose Events (GPEs) 4216331Sjkim * 5216331Sjkim *****************************************************************************/ 6216331Sjkim 7217365Sjkim/* 8217365Sjkim * Copyright (C) 2000 - 2011, 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 45216331Sjkim#define __EVXFGPE_C__ 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 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 85216331Sjkim ACPI_FUNCTION_TRACE (AcpiUpdateGpes); 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 142216331Sjkim /* Ensure that we have a valid GPE number */ 143216331Sjkim 144216331Sjkim GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 145216331Sjkim if (GpeEventInfo) 146216331Sjkim { 147216331Sjkim Status = AcpiEvAddGpeReference (GpeEventInfo); 148216331Sjkim } 149216331Sjkim 150216331Sjkim AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 151216331Sjkim return_ACPI_STATUS (Status); 152216331Sjkim} 153216331Sjkim 154216331SjkimACPI_EXPORT_SYMBOL (AcpiEnableGpe) 155216331Sjkim 156216331Sjkim 157216331Sjkim/******************************************************************************* 158216331Sjkim * 159216331Sjkim * FUNCTION: AcpiDisableGpe 160216331Sjkim * 161216331Sjkim * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1 162216331Sjkim * GpeNumber - GPE level within the GPE block 163216331Sjkim * 164216331Sjkim * RETURN: Status 165216331Sjkim * 166216331Sjkim * DESCRIPTION: Remove a reference to a GPE. When the last reference is 167216331Sjkim * removed, only then is the GPE disabled (for runtime GPEs), or 168216331Sjkim * the GPE mask bit disabled (for wake GPEs) 169216331Sjkim * 170216331Sjkim ******************************************************************************/ 171216331Sjkim 172216331SjkimACPI_STATUS 173216331SjkimAcpiDisableGpe ( 174216331Sjkim ACPI_HANDLE GpeDevice, 175216331Sjkim UINT32 GpeNumber) 176216331Sjkim{ 177216331Sjkim ACPI_STATUS Status = AE_BAD_PARAMETER; 178216331Sjkim ACPI_GPE_EVENT_INFO *GpeEventInfo; 179216331Sjkim ACPI_CPU_FLAGS Flags; 180216331Sjkim 181216331Sjkim 182216331Sjkim ACPI_FUNCTION_TRACE (AcpiDisableGpe); 183216331Sjkim 184216331Sjkim 185216331Sjkim Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 186216331Sjkim 187216331Sjkim /* Ensure that we have a valid GPE number */ 188216331Sjkim 189216331Sjkim GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 190216331Sjkim if (GpeEventInfo) 191216331Sjkim { 192216331Sjkim Status = AcpiEvRemoveGpeReference (GpeEventInfo); 193216331Sjkim } 194216331Sjkim 195216331Sjkim AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 196216331Sjkim return_ACPI_STATUS (Status); 197216331Sjkim} 198216331Sjkim 199216331SjkimACPI_EXPORT_SYMBOL (AcpiDisableGpe) 200216331Sjkim 201216331Sjkim 202216331Sjkim/******************************************************************************* 203216331Sjkim * 204216331Sjkim * FUNCTION: AcpiSetGpe 205216331Sjkim * 206216331Sjkim * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1 207216331Sjkim * GpeNumber - GPE level within the GPE block 208216331Sjkim * Action - ACPI_GPE_ENABLE or ACPI_GPE_DISABLE 209216331Sjkim * 210216331Sjkim * RETURN: Status 211216331Sjkim * 212216331Sjkim * DESCRIPTION: Enable or disable an individual GPE. This function bypasses 213216331Sjkim * the reference count mechanism used in the AcpiEnableGpe and 214216331Sjkim * AcpiDisableGpe interfaces -- and should be used with care. 215216331Sjkim * 216216331Sjkim * Note: Typically used to disable a runtime GPE for short period of time, 217216331Sjkim * then re-enable it, without disturbing the existing reference counts. This 218216331Sjkim * is useful, for example, in the Embedded Controller (EC) driver. 219216331Sjkim * 220216331Sjkim ******************************************************************************/ 221216331Sjkim 222216331SjkimACPI_STATUS 223216331SjkimAcpiSetGpe ( 224216331Sjkim ACPI_HANDLE GpeDevice, 225216331Sjkim UINT32 GpeNumber, 226216331Sjkim UINT8 Action) 227216331Sjkim{ 228216331Sjkim ACPI_GPE_EVENT_INFO *GpeEventInfo; 229216331Sjkim ACPI_STATUS Status; 230216331Sjkim ACPI_CPU_FLAGS Flags; 231216331Sjkim 232216331Sjkim 233216331Sjkim ACPI_FUNCTION_TRACE (AcpiSetGpe); 234216331Sjkim 235216331Sjkim 236216331Sjkim Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 237216331Sjkim 238216331Sjkim /* Ensure that we have a valid GPE number */ 239216331Sjkim 240216331Sjkim GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 241216331Sjkim if (!GpeEventInfo) 242216331Sjkim { 243216331Sjkim Status = AE_BAD_PARAMETER; 244216331Sjkim goto UnlockAndExit; 245216331Sjkim } 246216331Sjkim 247216331Sjkim /* Perform the action */ 248216331Sjkim 249216331Sjkim switch (Action) 250216331Sjkim { 251216331Sjkim case ACPI_GPE_ENABLE: 252216331Sjkim Status = AcpiEvEnableGpe (GpeEventInfo); 253216331Sjkim break; 254216331Sjkim 255216331Sjkim case ACPI_GPE_DISABLE: 256216331Sjkim Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_DISABLE); 257216331Sjkim break; 258216331Sjkim 259216331Sjkim default: 260216331Sjkim Status = AE_BAD_PARAMETER; 261216331Sjkim break; 262216331Sjkim } 263216331Sjkim 264216331SjkimUnlockAndExit: 265216331Sjkim AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 266216331Sjkim return_ACPI_STATUS (Status); 267216331Sjkim} 268216331Sjkim 269216331SjkimACPI_EXPORT_SYMBOL (AcpiSetGpe) 270216331Sjkim 271216331Sjkim 272216331Sjkim/******************************************************************************* 273216331Sjkim * 274216331Sjkim * FUNCTION: AcpiSetupGpeForWake 275216331Sjkim * 276216331Sjkim * PARAMETERS: WakeDevice - Device associated with the GPE (via _PRW) 277216331Sjkim * GpeDevice - Parent GPE Device. NULL for GPE0/GPE1 278216331Sjkim * GpeNumber - GPE level within the GPE block 279216331Sjkim * 280216331Sjkim * RETURN: Status 281216331Sjkim * 282216331Sjkim * DESCRIPTION: Mark a GPE as having the ability to wake the system. This 283216331Sjkim * interface is intended to be used as the host executes the 284216331Sjkim * _PRW methods (Power Resources for Wake) in the system tables. 285216331Sjkim * Each _PRW appears under a Device Object (The WakeDevice), and 286216331Sjkim * contains the info for the wake GPE associated with the 287216331Sjkim * WakeDevice. 288216331Sjkim * 289216331Sjkim ******************************************************************************/ 290216331Sjkim 291216331SjkimACPI_STATUS 292216331SjkimAcpiSetupGpeForWake ( 293216331Sjkim ACPI_HANDLE WakeDevice, 294216331Sjkim ACPI_HANDLE GpeDevice, 295216331Sjkim UINT32 GpeNumber) 296216331Sjkim{ 297216331Sjkim ACPI_STATUS Status = AE_BAD_PARAMETER; 298216331Sjkim ACPI_GPE_EVENT_INFO *GpeEventInfo; 299216331Sjkim ACPI_NAMESPACE_NODE *DeviceNode; 300216331Sjkim ACPI_CPU_FLAGS Flags; 301216331Sjkim 302216331Sjkim 303216331Sjkim ACPI_FUNCTION_TRACE (AcpiSetupGpeForWake); 304216331Sjkim 305216331Sjkim 306216331Sjkim /* Parameter Validation */ 307216331Sjkim 308216331Sjkim if (!WakeDevice) 309216331Sjkim { 310216331Sjkim /* 311216331Sjkim * By forcing WakeDevice to be valid, we automatically enable the 312216331Sjkim * implicit notify feature on all hosts. 313216331Sjkim */ 314216331Sjkim return_ACPI_STATUS (AE_BAD_PARAMETER); 315216331Sjkim } 316216331Sjkim 317219707Sjkim /* Handle root object case */ 318219707Sjkim 319219707Sjkim if (WakeDevice == ACPI_ROOT_OBJECT) 320219707Sjkim { 321219707Sjkim DeviceNode = AcpiGbl_RootNode; 322219707Sjkim } 323219707Sjkim else 324219707Sjkim { 325219707Sjkim DeviceNode = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, WakeDevice); 326219707Sjkim } 327219707Sjkim 328216331Sjkim /* Validate WakeDevice is of type Device */ 329216331Sjkim 330216331Sjkim if (DeviceNode->Type != ACPI_TYPE_DEVICE) 331216331Sjkim { 332216331Sjkim return_ACPI_STATUS (AE_BAD_PARAMETER); 333216331Sjkim } 334216331Sjkim 335216331Sjkim Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 336216331Sjkim 337216331Sjkim /* Ensure that we have a valid GPE number */ 338216331Sjkim 339216331Sjkim GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 340216331Sjkim if (GpeEventInfo) 341216331Sjkim { 342216331Sjkim /* 343216331Sjkim * If there is no method or handler for this GPE, then the 344216331Sjkim * WakeDevice will be notified whenever this GPE fires (aka 345216331Sjkim * "implicit notify") Note: The GPE is assumed to be 346216331Sjkim * level-triggered (for windows compatibility). 347216331Sjkim */ 348216331Sjkim if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) == 349216331Sjkim ACPI_GPE_DISPATCH_NONE) 350216331Sjkim { 351216331Sjkim GpeEventInfo->Flags = 352216331Sjkim (ACPI_GPE_DISPATCH_NOTIFY | ACPI_GPE_LEVEL_TRIGGERED); 353216331Sjkim GpeEventInfo->Dispatch.DeviceNode = DeviceNode; 354216331Sjkim } 355216331Sjkim 356216331Sjkim GpeEventInfo->Flags |= ACPI_GPE_CAN_WAKE; 357216331Sjkim Status = AE_OK; 358216331Sjkim } 359216331Sjkim 360216331Sjkim AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 361216331Sjkim return_ACPI_STATUS (Status); 362216331Sjkim} 363216331Sjkim 364216331SjkimACPI_EXPORT_SYMBOL (AcpiSetupGpeForWake) 365216331Sjkim 366216331Sjkim 367216331Sjkim/******************************************************************************* 368216331Sjkim * 369216331Sjkim * FUNCTION: AcpiSetGpeWakeMask 370216331Sjkim * 371216331Sjkim * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1 372216331Sjkim * GpeNumber - GPE level within the GPE block 373216331Sjkim * Action - Enable or Disable 374216331Sjkim * 375216331Sjkim * RETURN: Status 376216331Sjkim * 377216331Sjkim * DESCRIPTION: Set or clear the GPE's wakeup enable mask bit. The GPE must 378216331Sjkim * already be marked as a WAKE GPE. 379216331Sjkim * 380216331Sjkim ******************************************************************************/ 381216331Sjkim 382216331SjkimACPI_STATUS 383216331SjkimAcpiSetGpeWakeMask ( 384216331Sjkim ACPI_HANDLE GpeDevice, 385216331Sjkim UINT32 GpeNumber, 386216331Sjkim UINT8 Action) 387216331Sjkim{ 388216331Sjkim ACPI_STATUS Status = AE_OK; 389216331Sjkim ACPI_GPE_EVENT_INFO *GpeEventInfo; 390216331Sjkim ACPI_GPE_REGISTER_INFO *GpeRegisterInfo; 391216331Sjkim ACPI_CPU_FLAGS Flags; 392216331Sjkim UINT32 RegisterBit; 393216331Sjkim 394216331Sjkim 395216331Sjkim ACPI_FUNCTION_TRACE (AcpiSetGpeWakeMask); 396216331Sjkim 397216331Sjkim 398216331Sjkim Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 399216331Sjkim 400216331Sjkim /* 401216331Sjkim * Ensure that we have a valid GPE number and that this GPE is in 402216331Sjkim * fact a wake GPE 403216331Sjkim */ 404216331Sjkim GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 405216331Sjkim if (!GpeEventInfo) 406216331Sjkim { 407216331Sjkim Status = AE_BAD_PARAMETER; 408216331Sjkim goto UnlockAndExit; 409216331Sjkim } 410216331Sjkim 411216331Sjkim if (!(GpeEventInfo->Flags & ACPI_GPE_CAN_WAKE)) 412216331Sjkim { 413216331Sjkim Status = AE_TYPE; 414216331Sjkim goto UnlockAndExit; 415216331Sjkim } 416216331Sjkim 417216331Sjkim GpeRegisterInfo = GpeEventInfo->RegisterInfo; 418216331Sjkim if (!GpeRegisterInfo) 419216331Sjkim { 420216331Sjkim Status = AE_NOT_EXIST; 421216331Sjkim goto UnlockAndExit; 422216331Sjkim } 423216331Sjkim 424216331Sjkim RegisterBit = AcpiHwGetGpeRegisterBit (GpeEventInfo, GpeRegisterInfo); 425216331Sjkim 426216331Sjkim /* Perform the action */ 427216331Sjkim 428216331Sjkim switch (Action) 429216331Sjkim { 430216331Sjkim case ACPI_GPE_ENABLE: 431216331Sjkim ACPI_SET_BIT (GpeRegisterInfo->EnableForWake, (UINT8) RegisterBit); 432216331Sjkim break; 433216331Sjkim 434216331Sjkim case ACPI_GPE_DISABLE: 435216331Sjkim ACPI_CLEAR_BIT (GpeRegisterInfo->EnableForWake, (UINT8) RegisterBit); 436216331Sjkim break; 437216331Sjkim 438216331Sjkim default: 439216331Sjkim ACPI_ERROR ((AE_INFO, "%u, Invalid action", Action)); 440216331Sjkim Status = AE_BAD_PARAMETER; 441216331Sjkim break; 442216331Sjkim } 443216331Sjkim 444216331SjkimUnlockAndExit: 445216331Sjkim AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 446216331Sjkim return_ACPI_STATUS (Status); 447216331Sjkim} 448216331Sjkim 449216331SjkimACPI_EXPORT_SYMBOL (AcpiSetGpeWakeMask) 450216331Sjkim 451216331Sjkim 452216331Sjkim/******************************************************************************* 453216331Sjkim * 454216331Sjkim * FUNCTION: AcpiClearGpe 455216331Sjkim * 456216331Sjkim * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1 457216331Sjkim * GpeNumber - GPE level within the GPE block 458216331Sjkim * 459216331Sjkim * RETURN: Status 460216331Sjkim * 461216331Sjkim * DESCRIPTION: Clear an ACPI event (general purpose) 462216331Sjkim * 463216331Sjkim ******************************************************************************/ 464216331Sjkim 465216331SjkimACPI_STATUS 466216331SjkimAcpiClearGpe ( 467216331Sjkim ACPI_HANDLE GpeDevice, 468216331Sjkim UINT32 GpeNumber) 469216331Sjkim{ 470216331Sjkim ACPI_STATUS Status = AE_OK; 471216331Sjkim ACPI_GPE_EVENT_INFO *GpeEventInfo; 472216331Sjkim ACPI_CPU_FLAGS Flags; 473216331Sjkim 474216331Sjkim 475216331Sjkim ACPI_FUNCTION_TRACE (AcpiClearGpe); 476216331Sjkim 477216331Sjkim 478216331Sjkim Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 479216331Sjkim 480216331Sjkim /* Ensure that we have a valid GPE number */ 481216331Sjkim 482216331Sjkim GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 483216331Sjkim if (!GpeEventInfo) 484216331Sjkim { 485216331Sjkim Status = AE_BAD_PARAMETER; 486216331Sjkim goto UnlockAndExit; 487216331Sjkim } 488216331Sjkim 489216331Sjkim Status = AcpiHwClearGpe (GpeEventInfo); 490216331Sjkim 491216331SjkimUnlockAndExit: 492216331Sjkim AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 493216331Sjkim return_ACPI_STATUS (Status); 494216331Sjkim} 495216331Sjkim 496216331SjkimACPI_EXPORT_SYMBOL (AcpiClearGpe) 497216331Sjkim 498216331Sjkim 499216331Sjkim/******************************************************************************* 500216331Sjkim * 501216331Sjkim * FUNCTION: AcpiGetGpeStatus 502216331Sjkim * 503216331Sjkim * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1 504216331Sjkim * GpeNumber - GPE level within the GPE block 505216331Sjkim * EventStatus - Where the current status of the event 506216331Sjkim * will be returned 507216331Sjkim * 508216331Sjkim * RETURN: Status 509216331Sjkim * 510216331Sjkim * DESCRIPTION: Get the current status of a GPE (signalled/not_signalled) 511216331Sjkim * 512216331Sjkim ******************************************************************************/ 513216331Sjkim 514216331SjkimACPI_STATUS 515216331SjkimAcpiGetGpeStatus ( 516216331Sjkim ACPI_HANDLE GpeDevice, 517216331Sjkim UINT32 GpeNumber, 518216331Sjkim ACPI_EVENT_STATUS *EventStatus) 519216331Sjkim{ 520216331Sjkim ACPI_STATUS Status = AE_OK; 521216331Sjkim ACPI_GPE_EVENT_INFO *GpeEventInfo; 522216331Sjkim ACPI_CPU_FLAGS Flags; 523216331Sjkim 524216331Sjkim 525216331Sjkim ACPI_FUNCTION_TRACE (AcpiGetGpeStatus); 526216331Sjkim 527216331Sjkim 528216331Sjkim Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 529216331Sjkim 530216331Sjkim /* Ensure that we have a valid GPE number */ 531216331Sjkim 532216331Sjkim GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 533216331Sjkim if (!GpeEventInfo) 534216331Sjkim { 535216331Sjkim Status = AE_BAD_PARAMETER; 536216331Sjkim goto UnlockAndExit; 537216331Sjkim } 538216331Sjkim 539216331Sjkim /* Obtain status on the requested GPE number */ 540216331Sjkim 541216331Sjkim Status = AcpiHwGetGpeStatus (GpeEventInfo, EventStatus); 542216331Sjkim 543216331SjkimUnlockAndExit: 544216331Sjkim AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 545216331Sjkim return_ACPI_STATUS (Status); 546216331Sjkim} 547216331Sjkim 548216331SjkimACPI_EXPORT_SYMBOL (AcpiGetGpeStatus) 549216331Sjkim 550216331Sjkim 551216331Sjkim/******************************************************************************* 552216331Sjkim * 553216331Sjkim * FUNCTION: AcpiFinishGpe 554216331Sjkim * 555216331Sjkim * PARAMETERS: GpeDevice - Namespace node for the GPE Block 556216331Sjkim * (NULL for FADT defined GPEs) 557216331Sjkim * GpeNumber - GPE level within the GPE block 558216331Sjkim * 559216331Sjkim * RETURN: Status 560216331Sjkim * 561216331Sjkim * DESCRIPTION: Clear and conditionally reenable a GPE. This completes the GPE 562216331Sjkim * processing. Intended for use by asynchronous host-installed 563216331Sjkim * GPE handlers. The GPE is only reenabled if the EnableForRun bit 564216331Sjkim * is set in the GPE info. 565216331Sjkim * 566216331Sjkim ******************************************************************************/ 567216331Sjkim 568216331SjkimACPI_STATUS 569216331SjkimAcpiFinishGpe ( 570216331Sjkim ACPI_HANDLE GpeDevice, 571216331Sjkim UINT32 GpeNumber) 572216331Sjkim{ 573216331Sjkim ACPI_GPE_EVENT_INFO *GpeEventInfo; 574216331Sjkim ACPI_STATUS Status; 575216331Sjkim ACPI_CPU_FLAGS Flags; 576216331Sjkim 577216331Sjkim 578216331Sjkim ACPI_FUNCTION_TRACE (AcpiFinishGpe); 579216331Sjkim 580216331Sjkim 581216331Sjkim Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 582216331Sjkim 583216331Sjkim /* Ensure that we have a valid GPE number */ 584216331Sjkim 585216331Sjkim GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 586216331Sjkim if (!GpeEventInfo) 587216331Sjkim { 588216331Sjkim Status = AE_BAD_PARAMETER; 589216331Sjkim goto UnlockAndExit; 590216331Sjkim } 591216331Sjkim 592216331Sjkim Status = AcpiEvFinishGpe (GpeEventInfo); 593216331Sjkim 594216331SjkimUnlockAndExit: 595216331Sjkim AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 596216331Sjkim return_ACPI_STATUS (Status); 597216331Sjkim} 598216331Sjkim 599216331SjkimACPI_EXPORT_SYMBOL (AcpiFinishGpe) 600216331Sjkim 601216331Sjkim 602216331Sjkim/****************************************************************************** 603216331Sjkim * 604216331Sjkim * FUNCTION: AcpiDisableAllGpes 605216331Sjkim * 606216331Sjkim * PARAMETERS: None 607216331Sjkim * 608216331Sjkim * RETURN: Status 609216331Sjkim * 610216331Sjkim * DESCRIPTION: Disable and clear all GPEs in all GPE blocks 611216331Sjkim * 612216331Sjkim ******************************************************************************/ 613216331Sjkim 614216331SjkimACPI_STATUS 615216331SjkimAcpiDisableAllGpes ( 616216331Sjkim void) 617216331Sjkim{ 618216331Sjkim ACPI_STATUS Status; 619216331Sjkim 620216331Sjkim 621216331Sjkim ACPI_FUNCTION_TRACE (AcpiDisableAllGpes); 622216331Sjkim 623216331Sjkim 624216331Sjkim Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 625216331Sjkim if (ACPI_FAILURE (Status)) 626216331Sjkim { 627216331Sjkim return_ACPI_STATUS (Status); 628216331Sjkim } 629216331Sjkim 630216331Sjkim Status = AcpiHwDisableAllGpes (); 631216331Sjkim (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 632216331Sjkim 633216331Sjkim return_ACPI_STATUS (Status); 634216331Sjkim} 635216331Sjkim 636216331SjkimACPI_EXPORT_SYMBOL (AcpiDisableAllGpes) 637216331Sjkim 638216331Sjkim 639216331Sjkim/****************************************************************************** 640216331Sjkim * 641216331Sjkim * FUNCTION: AcpiEnableAllRuntimeGpes 642216331Sjkim * 643216331Sjkim * PARAMETERS: None 644216331Sjkim * 645216331Sjkim * RETURN: Status 646216331Sjkim * 647216331Sjkim * DESCRIPTION: Enable all "runtime" GPEs, in all GPE blocks 648216331Sjkim * 649216331Sjkim ******************************************************************************/ 650216331Sjkim 651216331SjkimACPI_STATUS 652216331SjkimAcpiEnableAllRuntimeGpes ( 653216331Sjkim void) 654216331Sjkim{ 655216331Sjkim ACPI_STATUS Status; 656216331Sjkim 657216331Sjkim 658216331Sjkim ACPI_FUNCTION_TRACE (AcpiEnableAllRuntimeGpes); 659216331Sjkim 660216331Sjkim 661216331Sjkim Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 662216331Sjkim if (ACPI_FAILURE (Status)) 663216331Sjkim { 664216331Sjkim return_ACPI_STATUS (Status); 665216331Sjkim } 666216331Sjkim 667216331Sjkim Status = AcpiHwEnableAllRuntimeGpes (); 668216331Sjkim (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 669216331Sjkim 670216331Sjkim return_ACPI_STATUS (Status); 671216331Sjkim} 672216331Sjkim 673216331SjkimACPI_EXPORT_SYMBOL (AcpiEnableAllRuntimeGpes) 674216331Sjkim 675216331Sjkim 676216331Sjkim/******************************************************************************* 677216331Sjkim * 678216331Sjkim * FUNCTION: AcpiInstallGpeBlock 679216331Sjkim * 680216331Sjkim * PARAMETERS: GpeDevice - Handle to the parent GPE Block Device 681216331Sjkim * GpeBlockAddress - Address and SpaceID 682216331Sjkim * RegisterCount - Number of GPE register pairs in the block 683216331Sjkim * InterruptNumber - H/W interrupt for the block 684216331Sjkim * 685216331Sjkim * RETURN: Status 686216331Sjkim * 687216331Sjkim * DESCRIPTION: Create and Install a block of GPE registers. The GPEs are not 688216331Sjkim * enabled here. 689216331Sjkim * 690216331Sjkim ******************************************************************************/ 691216331Sjkim 692216331SjkimACPI_STATUS 693216331SjkimAcpiInstallGpeBlock ( 694216331Sjkim ACPI_HANDLE GpeDevice, 695216331Sjkim ACPI_GENERIC_ADDRESS *GpeBlockAddress, 696216331Sjkim UINT32 RegisterCount, 697216331Sjkim UINT32 InterruptNumber) 698216331Sjkim{ 699216331Sjkim ACPI_STATUS Status; 700216331Sjkim ACPI_OPERAND_OBJECT *ObjDesc; 701216331Sjkim ACPI_NAMESPACE_NODE *Node; 702216331Sjkim ACPI_GPE_BLOCK_INFO *GpeBlock; 703216331Sjkim 704216331Sjkim 705216331Sjkim ACPI_FUNCTION_TRACE (AcpiInstallGpeBlock); 706216331Sjkim 707216331Sjkim 708216331Sjkim if ((!GpeDevice) || 709216331Sjkim (!GpeBlockAddress) || 710216331Sjkim (!RegisterCount)) 711216331Sjkim { 712216331Sjkim return_ACPI_STATUS (AE_BAD_PARAMETER); 713216331Sjkim } 714216331Sjkim 715216331Sjkim Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 716216331Sjkim if (ACPI_FAILURE (Status)) 717216331Sjkim { 718216331Sjkim return (Status); 719216331Sjkim } 720216331Sjkim 721216331Sjkim Node = AcpiNsValidateHandle (GpeDevice); 722216331Sjkim if (!Node) 723216331Sjkim { 724216331Sjkim Status = AE_BAD_PARAMETER; 725216331Sjkim goto UnlockAndExit; 726216331Sjkim } 727216331Sjkim 728216331Sjkim /* 729216331Sjkim * For user-installed GPE Block Devices, the GpeBlockBaseNumber 730216331Sjkim * is always zero 731216331Sjkim */ 732216331Sjkim Status = AcpiEvCreateGpeBlock (Node, GpeBlockAddress, RegisterCount, 733216331Sjkim 0, InterruptNumber, &GpeBlock); 734216331Sjkim if (ACPI_FAILURE (Status)) 735216331Sjkim { 736216331Sjkim goto UnlockAndExit; 737216331Sjkim } 738216331Sjkim 739216331Sjkim /* Install block in the DeviceObject attached to the node */ 740216331Sjkim 741216331Sjkim ObjDesc = AcpiNsGetAttachedObject (Node); 742216331Sjkim if (!ObjDesc) 743216331Sjkim { 744216331Sjkim /* 745216331Sjkim * No object, create a new one (Device nodes do not always have 746216331Sjkim * an attached object) 747216331Sjkim */ 748216331Sjkim ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_DEVICE); 749216331Sjkim if (!ObjDesc) 750216331Sjkim { 751216331Sjkim Status = AE_NO_MEMORY; 752216331Sjkim goto UnlockAndExit; 753216331Sjkim } 754216331Sjkim 755216331Sjkim Status = AcpiNsAttachObject (Node, ObjDesc, ACPI_TYPE_DEVICE); 756216331Sjkim 757216331Sjkim /* Remove local reference to the object */ 758216331Sjkim 759216331Sjkim AcpiUtRemoveReference (ObjDesc); 760216331Sjkim if (ACPI_FAILURE (Status)) 761216331Sjkim { 762216331Sjkim goto UnlockAndExit; 763216331Sjkim } 764216331Sjkim } 765216331Sjkim 766216331Sjkim /* Now install the GPE block in the DeviceObject */ 767216331Sjkim 768216331Sjkim ObjDesc->Device.GpeBlock = GpeBlock; 769216331Sjkim 770216331Sjkim 771216331SjkimUnlockAndExit: 772216331Sjkim (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 773216331Sjkim return_ACPI_STATUS (Status); 774216331Sjkim} 775216331Sjkim 776216331SjkimACPI_EXPORT_SYMBOL (AcpiInstallGpeBlock) 777216331Sjkim 778216331Sjkim 779216331Sjkim/******************************************************************************* 780216331Sjkim * 781216331Sjkim * FUNCTION: AcpiRemoveGpeBlock 782216331Sjkim * 783216331Sjkim * PARAMETERS: GpeDevice - Handle to the parent GPE Block Device 784216331Sjkim * 785216331Sjkim * RETURN: Status 786216331Sjkim * 787216331Sjkim * DESCRIPTION: Remove a previously installed block of GPE registers 788216331Sjkim * 789216331Sjkim ******************************************************************************/ 790216331Sjkim 791216331SjkimACPI_STATUS 792216331SjkimAcpiRemoveGpeBlock ( 793216331Sjkim ACPI_HANDLE GpeDevice) 794216331Sjkim{ 795216331Sjkim ACPI_OPERAND_OBJECT *ObjDesc; 796216331Sjkim ACPI_STATUS Status; 797216331Sjkim ACPI_NAMESPACE_NODE *Node; 798216331Sjkim 799216331Sjkim 800216331Sjkim ACPI_FUNCTION_TRACE (AcpiRemoveGpeBlock); 801216331Sjkim 802216331Sjkim 803216331Sjkim if (!GpeDevice) 804216331Sjkim { 805216331Sjkim return_ACPI_STATUS (AE_BAD_PARAMETER); 806216331Sjkim } 807216331Sjkim 808216331Sjkim Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 809216331Sjkim if (ACPI_FAILURE (Status)) 810216331Sjkim { 811216331Sjkim return (Status); 812216331Sjkim } 813216331Sjkim 814216331Sjkim Node = AcpiNsValidateHandle (GpeDevice); 815216331Sjkim if (!Node) 816216331Sjkim { 817216331Sjkim Status = AE_BAD_PARAMETER; 818216331Sjkim goto UnlockAndExit; 819216331Sjkim } 820216331Sjkim 821216331Sjkim /* Get the DeviceObject attached to the node */ 822216331Sjkim 823216331Sjkim ObjDesc = AcpiNsGetAttachedObject (Node); 824216331Sjkim if (!ObjDesc || 825216331Sjkim !ObjDesc->Device.GpeBlock) 826216331Sjkim { 827216331Sjkim return_ACPI_STATUS (AE_NULL_OBJECT); 828216331Sjkim } 829216331Sjkim 830216331Sjkim /* Delete the GPE block (but not the DeviceObject) */ 831216331Sjkim 832216331Sjkim Status = AcpiEvDeleteGpeBlock (ObjDesc->Device.GpeBlock); 833216331Sjkim if (ACPI_SUCCESS (Status)) 834216331Sjkim { 835216331Sjkim ObjDesc->Device.GpeBlock = NULL; 836216331Sjkim } 837216331Sjkim 838216331SjkimUnlockAndExit: 839216331Sjkim (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 840216331Sjkim return_ACPI_STATUS (Status); 841216331Sjkim} 842216331Sjkim 843216331SjkimACPI_EXPORT_SYMBOL (AcpiRemoveGpeBlock) 844216331Sjkim 845216331Sjkim 846216331Sjkim/******************************************************************************* 847216331Sjkim * 848216331Sjkim * FUNCTION: AcpiGetGpeDevice 849216331Sjkim * 850216331Sjkim * PARAMETERS: Index - System GPE index (0-CurrentGpeCount) 851216331Sjkim * GpeDevice - Where the parent GPE Device is returned 852216331Sjkim * 853216331Sjkim * RETURN: Status 854216331Sjkim * 855216331Sjkim * DESCRIPTION: Obtain the GPE device associated with the input index. A NULL 856216331Sjkim * gpe device indicates that the gpe number is contained in one of 857216331Sjkim * the FADT-defined gpe blocks. Otherwise, the GPE block device. 858216331Sjkim * 859216331Sjkim ******************************************************************************/ 860216331Sjkim 861216331SjkimACPI_STATUS 862216331SjkimAcpiGetGpeDevice ( 863216331Sjkim UINT32 Index, 864216331Sjkim ACPI_HANDLE *GpeDevice) 865216331Sjkim{ 866216331Sjkim ACPI_GPE_DEVICE_INFO Info; 867216331Sjkim ACPI_STATUS Status; 868216331Sjkim 869216331Sjkim 870216331Sjkim ACPI_FUNCTION_TRACE (AcpiGetGpeDevice); 871216331Sjkim 872216331Sjkim 873216331Sjkim if (!GpeDevice) 874216331Sjkim { 875216331Sjkim return_ACPI_STATUS (AE_BAD_PARAMETER); 876216331Sjkim } 877216331Sjkim 878216331Sjkim if (Index >= AcpiCurrentGpeCount) 879216331Sjkim { 880216331Sjkim return_ACPI_STATUS (AE_NOT_EXIST); 881216331Sjkim } 882216331Sjkim 883216331Sjkim /* Setup and walk the GPE list */ 884216331Sjkim 885216331Sjkim Info.Index = Index; 886216331Sjkim Info.Status = AE_NOT_EXIST; 887216331Sjkim Info.GpeDevice = NULL; 888216331Sjkim Info.NextBlockBaseIndex = 0; 889216331Sjkim 890216331Sjkim Status = AcpiEvWalkGpeList (AcpiEvGetGpeDevice, &Info); 891216331Sjkim if (ACPI_FAILURE (Status)) 892216331Sjkim { 893216331Sjkim return_ACPI_STATUS (Status); 894216331Sjkim } 895216331Sjkim 896216331Sjkim *GpeDevice = ACPI_CAST_PTR (ACPI_HANDLE, Info.GpeDevice); 897216331Sjkim return_ACPI_STATUS (Info.Status); 898216331Sjkim} 899216331Sjkim 900216331SjkimACPI_EXPORT_SYMBOL (AcpiGetGpeDevice) 901