evxface.c revision 254745
167754Smsmith/****************************************************************************** 267754Smsmith * 367754Smsmith * Module Name: evxface - External interfaces for ACPI events 467754Smsmith * 567754Smsmith *****************************************************************************/ 667754Smsmith 7217365Sjkim/* 8245582Sjkim * Copyright (C) 2000 - 2013, Intel Corp. 970243Smsmith * All rights reserved. 1067754Smsmith * 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. 2567754Smsmith * 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. 2967754Smsmith * 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 */ 4367754Smsmith 4467754Smsmith 4567754Smsmith#define __EVXFACE_C__ 4667754Smsmith 47193341Sjkim#include <contrib/dev/acpica/include/acpi.h> 48193341Sjkim#include <contrib/dev/acpica/include/accommon.h> 49193341Sjkim#include <contrib/dev/acpica/include/acnamesp.h> 50193341Sjkim#include <contrib/dev/acpica/include/acevents.h> 51193341Sjkim#include <contrib/dev/acpica/include/acinterp.h> 5267754Smsmith 5377424Smsmith#define _COMPONENT ACPI_EVENTS 5491116Smsmith ACPI_MODULE_NAME ("evxface") 5567754Smsmith 5667754Smsmith 5777424Smsmith/******************************************************************************* 5867754Smsmith * 5967754Smsmith * FUNCTION: AcpiInstallNotifyHandler 6067754Smsmith * 6167754Smsmith * PARAMETERS: Device - The device for which notifies will be handled 6267754Smsmith * HandlerType - The type of handler: 63234623Sjkim * ACPI_SYSTEM_NOTIFY: System Handler (00-7F) 64234623Sjkim * ACPI_DEVICE_NOTIFY: Device Handler (80-FF) 65234623Sjkim * ACPI_ALL_NOTIFY: Both System and Device 6667754Smsmith * Handler - Address of the handler 6767754Smsmith * Context - Value passed to the handler on each GPE 6867754Smsmith * 6967754Smsmith * RETURN: Status 7067754Smsmith * 71234623Sjkim * DESCRIPTION: Install a handler for notifications on an ACPI Device, 72234623Sjkim * ThermalZone, or Processor object. 7367754Smsmith * 74234623Sjkim * NOTES: The Root namespace object may have only one handler for each 75234623Sjkim * type of notify (System/Device). Device/Thermal/Processor objects 76234623Sjkim * may have one device notify handler, and multiple system notify 77234623Sjkim * handlers. 78234623Sjkim * 7967754Smsmith ******************************************************************************/ 8067754Smsmith 8167754SmsmithACPI_STATUS 8267754SmsmithAcpiInstallNotifyHandler ( 8367754Smsmith ACPI_HANDLE Device, 8467754Smsmith UINT32 HandlerType, 8577424Smsmith ACPI_NOTIFY_HANDLER Handler, 8667754Smsmith void *Context) 8767754Smsmith{ 88234623Sjkim ACPI_NAMESPACE_NODE *Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Device); 8967754Smsmith ACPI_OPERAND_OBJECT *ObjDesc; 90234623Sjkim ACPI_OPERAND_OBJECT *HandlerObj; 9191116Smsmith ACPI_STATUS Status; 92234623Sjkim UINT32 i; 9367754Smsmith 9467754Smsmith 95167802Sjkim ACPI_FUNCTION_TRACE (AcpiInstallNotifyHandler); 9667754Smsmith 9767754Smsmith 9867754Smsmith /* Parameter validation */ 9967754Smsmith 100234623Sjkim if ((!Device) || (!Handler) || (!HandlerType) || 10167754Smsmith (HandlerType > ACPI_MAX_NOTIFY_HANDLER_TYPE)) 10267754Smsmith { 10367754Smsmith return_ACPI_STATUS (AE_BAD_PARAMETER); 10467754Smsmith } 10567754Smsmith 10691116Smsmith Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 10791116Smsmith if (ACPI_FAILURE (Status)) 10891116Smsmith { 10991116Smsmith return_ACPI_STATUS (Status); 11091116Smsmith } 11171867Smsmith 11267754Smsmith /* 11371867Smsmith * Root Object: 11471867Smsmith * Registering a notify handler on the root object indicates that the 115193267Sjkim * caller wishes to receive notifications for all objects. Note that 116234623Sjkim * only one global handler can be registered per notify type. 117234623Sjkim * Ensure that a handler is not already installed. 11867754Smsmith */ 11967754Smsmith if (Device == ACPI_ROOT_OBJECT) 12067754Smsmith { 121234623Sjkim for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++) 12267754Smsmith { 123234623Sjkim if (HandlerType & (i+1)) 124234623Sjkim { 125234623Sjkim if (AcpiGbl_GlobalNotify[i].Handler) 126234623Sjkim { 127234623Sjkim Status = AE_ALREADY_EXISTS; 128234623Sjkim goto UnlockAndExit; 129234623Sjkim } 13067754Smsmith 131234623Sjkim AcpiGbl_GlobalNotify[i].Handler = Handler; 132234623Sjkim AcpiGbl_GlobalNotify[i].Context = Context; 133234623Sjkim } 13467754Smsmith } 135129684Snjl 136234623Sjkim goto UnlockAndExit; /* Global notify handler installed, all done */ 13767754Smsmith } 13867754Smsmith 13967754Smsmith /* 14085756Smsmith * All Other Objects: 141234623Sjkim * Caller will only receive notifications specific to the target 142234623Sjkim * object. Note that only certain object types are allowed to 143234623Sjkim * receive notifications. 14467754Smsmith */ 145234623Sjkim 146234623Sjkim /* Are Notifies allowed on this object? */ 147234623Sjkim 148234623Sjkim if (!AcpiEvIsNotifyObject (Node)) 14985756Smsmith { 150234623Sjkim Status = AE_TYPE; 151234623Sjkim goto UnlockAndExit; 152234623Sjkim } 15399146Siwasaki 154234623Sjkim /* Check for an existing internal object, might not exist */ 155234623Sjkim 156234623Sjkim ObjDesc = AcpiNsGetAttachedObject (Node); 157234623Sjkim if (!ObjDesc) 158234623Sjkim { 159234623Sjkim /* Create a new object */ 160234623Sjkim 161234623Sjkim ObjDesc = AcpiUtCreateInternalObject (Node->Type); 162234623Sjkim if (!ObjDesc) 16367754Smsmith { 164234623Sjkim Status = AE_NO_MEMORY; 16567754Smsmith goto UnlockAndExit; 16667754Smsmith } 16767754Smsmith 168234623Sjkim /* Attach new object to the Node, remove local reference */ 16967754Smsmith 170234623Sjkim Status = AcpiNsAttachObject (Device, ObjDesc, Node->Type); 171234623Sjkim AcpiUtRemoveReference (ObjDesc); 172234623Sjkim if (ACPI_FAILURE (Status)) 17367754Smsmith { 174234623Sjkim goto UnlockAndExit; 175234623Sjkim } 176234623Sjkim } 17771867Smsmith 178234623Sjkim /* Ensure that the handler is not already installed in the lists */ 179234623Sjkim 180234623Sjkim for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++) 181234623Sjkim { 182234623Sjkim if (HandlerType & (i+1)) 18371867Smsmith { 184234623Sjkim HandlerObj = ObjDesc->CommonNotify.NotifyList[i]; 185234623Sjkim while (HandlerObj) 18671867Smsmith { 187234623Sjkim if (HandlerObj->Notify.Handler == Handler) 188234623Sjkim { 189234623Sjkim Status = AE_ALREADY_EXISTS; 190234623Sjkim goto UnlockAndExit; 191234623Sjkim } 19267754Smsmith 193234623Sjkim HandlerObj = HandlerObj->Notify.Next[i]; 19471867Smsmith } 19571867Smsmith } 196234623Sjkim } 19771867Smsmith 198234623Sjkim /* Create and populate a new notify handler object */ 19971867Smsmith 200234623Sjkim HandlerObj = AcpiUtCreateInternalObject (ACPI_TYPE_LOCAL_NOTIFY); 201234623Sjkim if (!HandlerObj) 202234623Sjkim { 203234623Sjkim Status = AE_NO_MEMORY; 204234623Sjkim goto UnlockAndExit; 205234623Sjkim } 20667754Smsmith 207234623Sjkim HandlerObj->Notify.Node = Node; 208234623Sjkim HandlerObj->Notify.HandlerType = HandlerType; 209234623Sjkim HandlerObj->Notify.Handler = Handler; 210234623Sjkim HandlerObj->Notify.Context = Context; 21167754Smsmith 212234623Sjkim /* Install the handler at the list head(s) */ 213234623Sjkim 214234623Sjkim for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++) 215234623Sjkim { 216234623Sjkim if (HandlerType & (i+1)) 21771867Smsmith { 218234623Sjkim HandlerObj->Notify.Next[i] = 219234623Sjkim ObjDesc->CommonNotify.NotifyList[i]; 220129684Snjl 221234623Sjkim ObjDesc->CommonNotify.NotifyList[i] = HandlerObj; 22271867Smsmith } 223234623Sjkim } 224129684Snjl 225234623Sjkim /* Add an extra reference if handler was installed in both lists */ 226129684Snjl 227234623Sjkim if (HandlerType == ACPI_ALL_NOTIFY) 228234623Sjkim { 229234623Sjkim AcpiUtAddReference (HandlerObj); 23067754Smsmith } 23167754Smsmith 23285756Smsmith 23367754SmsmithUnlockAndExit: 23491116Smsmith (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 23567754Smsmith return_ACPI_STATUS (Status); 23667754Smsmith} 23767754Smsmith 238167802SjkimACPI_EXPORT_SYMBOL (AcpiInstallNotifyHandler) 23967754Smsmith 240167802Sjkim 24177424Smsmith/******************************************************************************* 24267754Smsmith * 24367754Smsmith * FUNCTION: AcpiRemoveNotifyHandler 24467754Smsmith * 245234623Sjkim * PARAMETERS: Device - The device for which the handler is installed 24667754Smsmith * HandlerType - The type of handler: 247234623Sjkim * ACPI_SYSTEM_NOTIFY: System Handler (00-7F) 248234623Sjkim * ACPI_DEVICE_NOTIFY: Device Handler (80-FF) 249234623Sjkim * ACPI_ALL_NOTIFY: Both System and Device 25067754Smsmith * Handler - Address of the handler 251138287Smarks * 25267754Smsmith * RETURN: Status 25367754Smsmith * 25467754Smsmith * DESCRIPTION: Remove a handler for notifies on an ACPI device 25567754Smsmith * 25667754Smsmith ******************************************************************************/ 25767754Smsmith 25867754SmsmithACPI_STATUS 25967754SmsmithAcpiRemoveNotifyHandler ( 26067754Smsmith ACPI_HANDLE Device, 26167754Smsmith UINT32 HandlerType, 26277424Smsmith ACPI_NOTIFY_HANDLER Handler) 26367754Smsmith{ 264234623Sjkim ACPI_NAMESPACE_NODE *Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Device); 26567754Smsmith ACPI_OPERAND_OBJECT *ObjDesc; 266234623Sjkim ACPI_OPERAND_OBJECT *HandlerObj; 267234623Sjkim ACPI_OPERAND_OBJECT *PreviousHandlerObj; 26891116Smsmith ACPI_STATUS Status; 269234623Sjkim UINT32 i; 27067754Smsmith 27177424Smsmith 272167802Sjkim ACPI_FUNCTION_TRACE (AcpiRemoveNotifyHandler); 27367754Smsmith 27477424Smsmith 27567754Smsmith /* Parameter validation */ 27667754Smsmith 277234623Sjkim if ((!Device) || (!Handler) || (!HandlerType) || 27867754Smsmith (HandlerType > ACPI_MAX_NOTIFY_HANDLER_TYPE)) 27967754Smsmith { 28067754Smsmith return_ACPI_STATUS (AE_BAD_PARAMETER); 28167754Smsmith } 28267754Smsmith 283235945Sjkim /* Make sure all deferred notify tasks are completed */ 284234623Sjkim 285235945Sjkim AcpiOsWaitEventsComplete (); 286234623Sjkim 28791116Smsmith Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 28891116Smsmith if (ACPI_FAILURE (Status)) 28991116Smsmith { 29091116Smsmith return_ACPI_STATUS (Status); 29191116Smsmith } 29267754Smsmith 293234623Sjkim /* Root Object. Global handlers are removed here */ 29467754Smsmith 29587031Smsmith if (Device == ACPI_ROOT_OBJECT) 29685756Smsmith { 297234623Sjkim for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++) 29871867Smsmith { 299234623Sjkim if (HandlerType & (i+1)) 300234623Sjkim { 301234623Sjkim if (!AcpiGbl_GlobalNotify[i].Handler || 302234623Sjkim (AcpiGbl_GlobalNotify[i].Handler != Handler)) 303234623Sjkim { 304234623Sjkim Status = AE_NOT_EXIST; 305234623Sjkim goto UnlockAndExit; 306234623Sjkim } 30767754Smsmith 308234623Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 309234623Sjkim "Removing global notify handler\n")); 310234623Sjkim 311234623Sjkim AcpiGbl_GlobalNotify[i].Handler = NULL; 312234623Sjkim AcpiGbl_GlobalNotify[i].Context = NULL; 313234623Sjkim } 31471867Smsmith } 315129684Snjl 316234623Sjkim goto UnlockAndExit; 31767754Smsmith } 31867754Smsmith 319234623Sjkim /* All other objects: Are Notifies allowed on this object? */ 320138287Smarks 321234623Sjkim if (!AcpiEvIsNotifyObject (Node)) 32285756Smsmith { 323234623Sjkim Status = AE_TYPE; 324234623Sjkim goto UnlockAndExit; 325234623Sjkim } 32699146Siwasaki 327234623Sjkim /* Must have an existing internal object */ 32867754Smsmith 329234623Sjkim ObjDesc = AcpiNsGetAttachedObject (Node); 330234623Sjkim if (!ObjDesc) 331234623Sjkim { 332234623Sjkim Status = AE_NOT_EXIST; 333234623Sjkim goto UnlockAndExit; 334234623Sjkim } 33567754Smsmith 336234623Sjkim /* Internal object exists. Find the handler and remove it */ 337234623Sjkim 338234623Sjkim for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++) 339234623Sjkim { 340234623Sjkim if (HandlerType & (i+1)) 34171867Smsmith { 342234623Sjkim HandlerObj = ObjDesc->CommonNotify.NotifyList[i]; 343234623Sjkim PreviousHandlerObj = NULL; 34467754Smsmith 345234623Sjkim /* Attempt to find the handler in the handler list */ 34671867Smsmith 347234623Sjkim while (HandlerObj && 348234623Sjkim (HandlerObj->Notify.Handler != Handler)) 349129684Snjl { 350234623Sjkim PreviousHandlerObj = HandlerObj; 351234623Sjkim HandlerObj = HandlerObj->Notify.Next[i]; 352167802Sjkim } 353167802Sjkim 354234623Sjkim if (!HandlerObj) 355167802Sjkim { 356234623Sjkim Status = AE_NOT_EXIST; 357129684Snjl goto UnlockAndExit; 358129684Snjl } 359129684Snjl 360234623Sjkim /* Remove the handler object from the list */ 361129684Snjl 362234623Sjkim if (PreviousHandlerObj) /* Handler is not at the list head */ 363129684Snjl { 364234623Sjkim PreviousHandlerObj->Notify.Next[i] = 365234623Sjkim HandlerObj->Notify.Next[i]; 366167802Sjkim } 367234623Sjkim else /* Handler is at the list head */ 368167802Sjkim { 369234623Sjkim ObjDesc->CommonNotify.NotifyList[i] = 370234623Sjkim HandlerObj->Notify.Next[i]; 371129684Snjl } 37271867Smsmith 373234623Sjkim AcpiUtRemoveReference (HandlerObj); 37471867Smsmith } 37567754Smsmith } 37667754Smsmith 37767754Smsmith 37867754SmsmithUnlockAndExit: 37991116Smsmith (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 38067754Smsmith return_ACPI_STATUS (Status); 38167754Smsmith} 38267754Smsmith 383167802SjkimACPI_EXPORT_SYMBOL (AcpiRemoveNotifyHandler) 38471867Smsmith 385167802Sjkim 38677424Smsmith/******************************************************************************* 38767754Smsmith * 388231844Sjkim * FUNCTION: AcpiInstallExceptionHandler 389231844Sjkim * 390231844Sjkim * PARAMETERS: Handler - Pointer to the handler function for the 391231844Sjkim * event 392231844Sjkim * 393231844Sjkim * RETURN: Status 394231844Sjkim * 395231844Sjkim * DESCRIPTION: Saves the pointer to the handler function 396231844Sjkim * 397231844Sjkim ******************************************************************************/ 398231844Sjkim 399231844SjkimACPI_STATUS 400231844SjkimAcpiInstallExceptionHandler ( 401231844Sjkim ACPI_EXCEPTION_HANDLER Handler) 402231844Sjkim{ 403231844Sjkim ACPI_STATUS Status; 404231844Sjkim 405231844Sjkim 406231844Sjkim ACPI_FUNCTION_TRACE (AcpiInstallExceptionHandler); 407231844Sjkim 408231844Sjkim 409231844Sjkim Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 410231844Sjkim if (ACPI_FAILURE (Status)) 411231844Sjkim { 412231844Sjkim return_ACPI_STATUS (Status); 413231844Sjkim } 414231844Sjkim 415231844Sjkim /* Don't allow two handlers. */ 416231844Sjkim 417231844Sjkim if (AcpiGbl_ExceptionHandler) 418231844Sjkim { 419231844Sjkim Status = AE_ALREADY_EXISTS; 420231844Sjkim goto Cleanup; 421231844Sjkim } 422231844Sjkim 423231844Sjkim /* Install the handler */ 424231844Sjkim 425231844Sjkim AcpiGbl_ExceptionHandler = Handler; 426231844Sjkim 427231844SjkimCleanup: 428231844Sjkim (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 429231844Sjkim return_ACPI_STATUS (Status); 430231844Sjkim} 431231844Sjkim 432231844SjkimACPI_EXPORT_SYMBOL (AcpiInstallExceptionHandler) 433231844Sjkim 434231844Sjkim 435231844Sjkim#if (!ACPI_REDUCED_HARDWARE) 436231844Sjkim/******************************************************************************* 437231844Sjkim * 438254745Sjkim * FUNCTION: AcpiInstallSciHandler 439254745Sjkim * 440254745Sjkim * PARAMETERS: Address - Address of the handler 441254745Sjkim * Context - Value passed to the handler on each SCI 442254745Sjkim * 443254745Sjkim * RETURN: Status 444254745Sjkim * 445254745Sjkim * DESCRIPTION: Install a handler for a System Control Interrupt. 446254745Sjkim * 447254745Sjkim ******************************************************************************/ 448254745Sjkim 449254745SjkimACPI_STATUS 450254745SjkimAcpiInstallSciHandler ( 451254745Sjkim ACPI_SCI_HANDLER Address, 452254745Sjkim void *Context) 453254745Sjkim{ 454254745Sjkim ACPI_SCI_HANDLER_INFO *NewSciHandler; 455254745Sjkim ACPI_SCI_HANDLER_INFO *SciHandler; 456254745Sjkim ACPI_CPU_FLAGS Flags; 457254745Sjkim ACPI_STATUS Status; 458254745Sjkim 459254745Sjkim 460254745Sjkim ACPI_FUNCTION_TRACE (AcpiInstallSciHandler); 461254745Sjkim 462254745Sjkim 463254745Sjkim if (!Address) 464254745Sjkim { 465254745Sjkim return_ACPI_STATUS (AE_BAD_PARAMETER); 466254745Sjkim } 467254745Sjkim 468254745Sjkim /* Allocate and init a handler object */ 469254745Sjkim 470254745Sjkim NewSciHandler = ACPI_ALLOCATE (sizeof (ACPI_SCI_HANDLER_INFO)); 471254745Sjkim if (!NewSciHandler) 472254745Sjkim { 473254745Sjkim return_ACPI_STATUS (AE_NO_MEMORY); 474254745Sjkim } 475254745Sjkim 476254745Sjkim NewSciHandler->Address = Address; 477254745Sjkim NewSciHandler->Context = Context; 478254745Sjkim 479254745Sjkim Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 480254745Sjkim if (ACPI_FAILURE (Status)) 481254745Sjkim { 482254745Sjkim goto Exit; 483254745Sjkim } 484254745Sjkim 485254745Sjkim /* Lock list during installation */ 486254745Sjkim 487254745Sjkim Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 488254745Sjkim SciHandler = AcpiGbl_SciHandlerList; 489254745Sjkim 490254745Sjkim /* Ensure handler does not already exist */ 491254745Sjkim 492254745Sjkim while (SciHandler) 493254745Sjkim { 494254745Sjkim if (Address == SciHandler->Address) 495254745Sjkim { 496254745Sjkim Status = AE_ALREADY_EXISTS; 497254745Sjkim goto UnlockAndExit; 498254745Sjkim } 499254745Sjkim 500254745Sjkim SciHandler = SciHandler->Next; 501254745Sjkim } 502254745Sjkim 503254745Sjkim /* Install the new handler into the global list (at head) */ 504254745Sjkim 505254745Sjkim NewSciHandler->Next = AcpiGbl_SciHandlerList; 506254745Sjkim AcpiGbl_SciHandlerList = NewSciHandler; 507254745Sjkim 508254745Sjkim 509254745SjkimUnlockAndExit: 510254745Sjkim 511254745Sjkim AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 512254745Sjkim (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 513254745Sjkim 514254745SjkimExit: 515254745Sjkim if (ACPI_FAILURE (Status)) 516254745Sjkim { 517254745Sjkim ACPI_FREE (NewSciHandler); 518254745Sjkim } 519254745Sjkim return_ACPI_STATUS (Status); 520254745Sjkim} 521254745Sjkim 522254745Sjkim 523254745Sjkim/******************************************************************************* 524254745Sjkim * 525254745Sjkim * FUNCTION: AcpiRemoveSciHandler 526254745Sjkim * 527254745Sjkim * PARAMETERS: Address - Address of the handler 528254745Sjkim * 529254745Sjkim * RETURN: Status 530254745Sjkim * 531254745Sjkim * DESCRIPTION: Remove a handler for a System Control Interrupt. 532254745Sjkim * 533254745Sjkim ******************************************************************************/ 534254745Sjkim 535254745SjkimACPI_STATUS 536254745SjkimAcpiRemoveSciHandler ( 537254745Sjkim ACPI_SCI_HANDLER Address) 538254745Sjkim{ 539254745Sjkim ACPI_SCI_HANDLER_INFO *PrevSciHandler; 540254745Sjkim ACPI_SCI_HANDLER_INFO *NextSciHandler; 541254745Sjkim ACPI_CPU_FLAGS Flags; 542254745Sjkim ACPI_STATUS Status; 543254745Sjkim 544254745Sjkim 545254745Sjkim ACPI_FUNCTION_TRACE (AcpiRemoveSciHandler); 546254745Sjkim 547254745Sjkim 548254745Sjkim if (!Address) 549254745Sjkim { 550254745Sjkim return_ACPI_STATUS (AE_BAD_PARAMETER); 551254745Sjkim } 552254745Sjkim 553254745Sjkim Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 554254745Sjkim if (ACPI_FAILURE (Status)) 555254745Sjkim { 556254745Sjkim return_ACPI_STATUS (Status); 557254745Sjkim } 558254745Sjkim 559254745Sjkim /* Remove the SCI handler with lock */ 560254745Sjkim 561254745Sjkim Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 562254745Sjkim 563254745Sjkim PrevSciHandler = NULL; 564254745Sjkim NextSciHandler = AcpiGbl_SciHandlerList; 565254745Sjkim while (NextSciHandler) 566254745Sjkim { 567254745Sjkim if (NextSciHandler->Address == Address) 568254745Sjkim { 569254745Sjkim /* Unlink and free the SCI handler info block */ 570254745Sjkim 571254745Sjkim if (PrevSciHandler) 572254745Sjkim { 573254745Sjkim PrevSciHandler->Next = NextSciHandler->Next; 574254745Sjkim } 575254745Sjkim else 576254745Sjkim { 577254745Sjkim AcpiGbl_SciHandlerList = NextSciHandler->Next; 578254745Sjkim } 579254745Sjkim 580254745Sjkim AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 581254745Sjkim ACPI_FREE (NextSciHandler); 582254745Sjkim goto UnlockAndExit; 583254745Sjkim } 584254745Sjkim 585254745Sjkim PrevSciHandler = NextSciHandler; 586254745Sjkim NextSciHandler = NextSciHandler->Next; 587254745Sjkim } 588254745Sjkim 589254745Sjkim AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 590254745Sjkim Status = AE_NOT_EXIST; 591254745Sjkim 592254745Sjkim 593254745SjkimUnlockAndExit: 594254745Sjkim (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 595254745Sjkim return_ACPI_STATUS (Status); 596254745Sjkim} 597254745Sjkim 598254745Sjkim 599254745Sjkim/******************************************************************************* 600254745Sjkim * 601231844Sjkim * FUNCTION: AcpiInstallGlobalEventHandler 602231844Sjkim * 603231844Sjkim * PARAMETERS: Handler - Pointer to the global event handler function 604231844Sjkim * Context - Value passed to the handler on each event 605231844Sjkim * 606231844Sjkim * RETURN: Status 607231844Sjkim * 608231844Sjkim * DESCRIPTION: Saves the pointer to the handler function. The global handler 609231844Sjkim * is invoked upon each incoming GPE and Fixed Event. It is 610231844Sjkim * invoked at interrupt level at the time of the event dispatch. 611231844Sjkim * Can be used to update event counters, etc. 612231844Sjkim * 613231844Sjkim ******************************************************************************/ 614231844Sjkim 615231844SjkimACPI_STATUS 616231844SjkimAcpiInstallGlobalEventHandler ( 617231844Sjkim ACPI_GBL_EVENT_HANDLER Handler, 618231844Sjkim void *Context) 619231844Sjkim{ 620231844Sjkim ACPI_STATUS Status; 621231844Sjkim 622231844Sjkim 623231844Sjkim ACPI_FUNCTION_TRACE (AcpiInstallGlobalEventHandler); 624231844Sjkim 625231844Sjkim 626231844Sjkim /* Parameter validation */ 627231844Sjkim 628231844Sjkim if (!Handler) 629231844Sjkim { 630231844Sjkim return_ACPI_STATUS (AE_BAD_PARAMETER); 631231844Sjkim } 632231844Sjkim 633231844Sjkim Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 634231844Sjkim if (ACPI_FAILURE (Status)) 635231844Sjkim { 636231844Sjkim return_ACPI_STATUS (Status); 637231844Sjkim } 638231844Sjkim 639231844Sjkim /* Don't allow two handlers. */ 640231844Sjkim 641231844Sjkim if (AcpiGbl_GlobalEventHandler) 642231844Sjkim { 643231844Sjkim Status = AE_ALREADY_EXISTS; 644231844Sjkim goto Cleanup; 645231844Sjkim } 646231844Sjkim 647231844Sjkim AcpiGbl_GlobalEventHandler = Handler; 648231844Sjkim AcpiGbl_GlobalEventHandlerContext = Context; 649231844Sjkim 650231844Sjkim 651231844SjkimCleanup: 652231844Sjkim (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 653231844Sjkim return_ACPI_STATUS (Status); 654231844Sjkim} 655231844Sjkim 656231844SjkimACPI_EXPORT_SYMBOL (AcpiInstallGlobalEventHandler) 657231844Sjkim 658231844Sjkim 659231844Sjkim/******************************************************************************* 660231844Sjkim * 661231844Sjkim * FUNCTION: AcpiInstallFixedEventHandler 662231844Sjkim * 663231844Sjkim * PARAMETERS: Event - Event type to enable. 664231844Sjkim * Handler - Pointer to the handler function for the 665231844Sjkim * event 666231844Sjkim * Context - Value passed to the handler on each GPE 667231844Sjkim * 668231844Sjkim * RETURN: Status 669231844Sjkim * 670231844Sjkim * DESCRIPTION: Saves the pointer to the handler function and then enables the 671231844Sjkim * event. 672231844Sjkim * 673231844Sjkim ******************************************************************************/ 674231844Sjkim 675231844SjkimACPI_STATUS 676231844SjkimAcpiInstallFixedEventHandler ( 677231844Sjkim UINT32 Event, 678231844Sjkim ACPI_EVENT_HANDLER Handler, 679231844Sjkim void *Context) 680231844Sjkim{ 681231844Sjkim ACPI_STATUS Status; 682231844Sjkim 683231844Sjkim 684231844Sjkim ACPI_FUNCTION_TRACE (AcpiInstallFixedEventHandler); 685231844Sjkim 686231844Sjkim 687231844Sjkim /* Parameter validation */ 688231844Sjkim 689231844Sjkim if (Event > ACPI_EVENT_MAX) 690231844Sjkim { 691231844Sjkim return_ACPI_STATUS (AE_BAD_PARAMETER); 692231844Sjkim } 693231844Sjkim 694231844Sjkim Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 695231844Sjkim if (ACPI_FAILURE (Status)) 696231844Sjkim { 697231844Sjkim return_ACPI_STATUS (Status); 698231844Sjkim } 699231844Sjkim 700246849Sjkim /* Do not allow multiple handlers */ 701231844Sjkim 702246849Sjkim if (AcpiGbl_FixedEventHandlers[Event].Handler) 703231844Sjkim { 704231844Sjkim Status = AE_ALREADY_EXISTS; 705231844Sjkim goto Cleanup; 706231844Sjkim } 707231844Sjkim 708231844Sjkim /* Install the handler before enabling the event */ 709231844Sjkim 710231844Sjkim AcpiGbl_FixedEventHandlers[Event].Handler = Handler; 711231844Sjkim AcpiGbl_FixedEventHandlers[Event].Context = Context; 712231844Sjkim 713231844Sjkim Status = AcpiEnableEvent (Event, 0); 714231844Sjkim if (ACPI_FAILURE (Status)) 715231844Sjkim { 716246849Sjkim ACPI_WARNING ((AE_INFO, 717246849Sjkim "Could not enable fixed event - %s (%u)", 718246849Sjkim AcpiUtGetEventName (Event), Event)); 719231844Sjkim 720231844Sjkim /* Remove the handler */ 721231844Sjkim 722231844Sjkim AcpiGbl_FixedEventHandlers[Event].Handler = NULL; 723231844Sjkim AcpiGbl_FixedEventHandlers[Event].Context = NULL; 724231844Sjkim } 725231844Sjkim else 726231844Sjkim { 727231844Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 728246849Sjkim "Enabled fixed event %s (%X), Handler=%p\n", 729246849Sjkim AcpiUtGetEventName (Event), Event, Handler)); 730231844Sjkim } 731231844Sjkim 732231844Sjkim 733231844SjkimCleanup: 734231844Sjkim (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 735231844Sjkim return_ACPI_STATUS (Status); 736231844Sjkim} 737231844Sjkim 738231844SjkimACPI_EXPORT_SYMBOL (AcpiInstallFixedEventHandler) 739231844Sjkim 740231844Sjkim 741231844Sjkim/******************************************************************************* 742231844Sjkim * 743231844Sjkim * FUNCTION: AcpiRemoveFixedEventHandler 744231844Sjkim * 745231844Sjkim * PARAMETERS: Event - Event type to disable. 746231844Sjkim * Handler - Address of the handler 747231844Sjkim * 748231844Sjkim * RETURN: Status 749231844Sjkim * 750231844Sjkim * DESCRIPTION: Disables the event and unregisters the event handler. 751231844Sjkim * 752231844Sjkim ******************************************************************************/ 753231844Sjkim 754231844SjkimACPI_STATUS 755231844SjkimAcpiRemoveFixedEventHandler ( 756231844Sjkim UINT32 Event, 757231844Sjkim ACPI_EVENT_HANDLER Handler) 758231844Sjkim{ 759231844Sjkim ACPI_STATUS Status = AE_OK; 760231844Sjkim 761231844Sjkim 762231844Sjkim ACPI_FUNCTION_TRACE (AcpiRemoveFixedEventHandler); 763231844Sjkim 764231844Sjkim 765231844Sjkim /* Parameter validation */ 766231844Sjkim 767231844Sjkim if (Event > ACPI_EVENT_MAX) 768231844Sjkim { 769231844Sjkim return_ACPI_STATUS (AE_BAD_PARAMETER); 770231844Sjkim } 771231844Sjkim 772231844Sjkim Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 773231844Sjkim if (ACPI_FAILURE (Status)) 774231844Sjkim { 775231844Sjkim return_ACPI_STATUS (Status); 776231844Sjkim } 777231844Sjkim 778231844Sjkim /* Disable the event before removing the handler */ 779231844Sjkim 780231844Sjkim Status = AcpiDisableEvent (Event, 0); 781231844Sjkim 782231844Sjkim /* Always Remove the handler */ 783231844Sjkim 784231844Sjkim AcpiGbl_FixedEventHandlers[Event].Handler = NULL; 785231844Sjkim AcpiGbl_FixedEventHandlers[Event].Context = NULL; 786231844Sjkim 787231844Sjkim if (ACPI_FAILURE (Status)) 788231844Sjkim { 789231844Sjkim ACPI_WARNING ((AE_INFO, 790246849Sjkim "Could not disable fixed event - %s (%u)", 791246849Sjkim AcpiUtGetEventName (Event), Event)); 792231844Sjkim } 793231844Sjkim else 794231844Sjkim { 795246849Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 796246849Sjkim "Disabled fixed event - %s (%X)\n", 797246849Sjkim AcpiUtGetEventName (Event), Event)); 798231844Sjkim } 799231844Sjkim 800231844Sjkim (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 801231844Sjkim return_ACPI_STATUS (Status); 802231844Sjkim} 803231844Sjkim 804231844SjkimACPI_EXPORT_SYMBOL (AcpiRemoveFixedEventHandler) 805231844Sjkim 806231844Sjkim 807231844Sjkim/******************************************************************************* 808231844Sjkim * 80967754Smsmith * FUNCTION: AcpiInstallGpeHandler 81067754Smsmith * 811151937Sjkim * PARAMETERS: GpeDevice - Namespace node for the GPE (NULL for FADT 812151937Sjkim * defined GPEs) 813151937Sjkim * GpeNumber - The GPE number within the GPE block 81467754Smsmith * Type - Whether this GPE should be treated as an 81567754Smsmith * edge- or level-triggered interrupt. 816129684Snjl * Address - Address of the handler 81767754Smsmith * Context - Value passed to the handler on each GPE 81867754Smsmith * 81967754Smsmith * RETURN: Status 82067754Smsmith * 82167754Smsmith * DESCRIPTION: Install a handler for a General Purpose Event. 82267754Smsmith * 82367754Smsmith ******************************************************************************/ 82467754Smsmith 82567754SmsmithACPI_STATUS 82667754SmsmithAcpiInstallGpeHandler ( 827117521Snjl ACPI_HANDLE GpeDevice, 82867754Smsmith UINT32 GpeNumber, 82967754Smsmith UINT32 Type, 830216471Sjkim ACPI_GPE_HANDLER Address, 83167754Smsmith void *Context) 83267754Smsmith{ 833129684Snjl ACPI_GPE_EVENT_INFO *GpeEventInfo; 834216471Sjkim ACPI_GPE_HANDLER_INFO *Handler; 83591116Smsmith ACPI_STATUS Status; 836167802Sjkim ACPI_CPU_FLAGS Flags; 83767754Smsmith 83877424Smsmith 839167802Sjkim ACPI_FUNCTION_TRACE (AcpiInstallGpeHandler); 84067754Smsmith 84177424Smsmith 84267754Smsmith /* Parameter validation */ 84367754Smsmith 844206117Sjkim if ((!Address) || (Type & ~ACPI_GPE_XRUPT_TYPE_MASK)) 84567754Smsmith { 84667754Smsmith return_ACPI_STATUS (AE_BAD_PARAMETER); 84767754Smsmith } 84867754Smsmith 849117521Snjl Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 850117521Snjl if (ACPI_FAILURE (Status)) 851117521Snjl { 852117521Snjl return_ACPI_STATUS (Status); 853117521Snjl } 854117521Snjl 855216471Sjkim /* Allocate and init handler object (before lock) */ 856216471Sjkim 857216471Sjkim Handler = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_GPE_HANDLER_INFO)); 858216471Sjkim if (!Handler) 859216471Sjkim { 860216471Sjkim Status = AE_NO_MEMORY; 861216471Sjkim goto UnlockAndExit; 862216471Sjkim } 863216471Sjkim 864216471Sjkim Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 865216471Sjkim 86667754Smsmith /* Ensure that we have a valid GPE number */ 86767754Smsmith 868117521Snjl GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 869114237Snjl if (!GpeEventInfo) 87067754Smsmith { 871117521Snjl Status = AE_BAD_PARAMETER; 872216471Sjkim goto FreeAndExit; 87367754Smsmith } 87467754Smsmith 87567754Smsmith /* Make sure that there isn't a handler there already */ 87667754Smsmith 877193267Sjkim if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) == 878193267Sjkim ACPI_GPE_DISPATCH_HANDLER) 87967754Smsmith { 88087031Smsmith Status = AE_ALREADY_EXISTS; 881216471Sjkim goto FreeAndExit; 88267754Smsmith } 88367754Smsmith 884216471Sjkim Handler->Address = Address; 885216471Sjkim Handler->Context = Context; 886216471Sjkim Handler->MethodNode = GpeEventInfo->Dispatch.MethodNode; 887216471Sjkim Handler->OriginalFlags = (UINT8) (GpeEventInfo->Flags & 888216471Sjkim (ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK)); 88967754Smsmith 890216471Sjkim /* 891216471Sjkim * If the GPE is associated with a method, it may have been enabled 892216471Sjkim * automatically during initialization, in which case it has to be 893216471Sjkim * disabled now to avoid spurious execution of the handler. 894216471Sjkim */ 895216471Sjkim if (((Handler->OriginalFlags & ACPI_GPE_DISPATCH_METHOD) || 896216471Sjkim (Handler->OriginalFlags & ACPI_GPE_DISPATCH_NOTIFY)) && 897216471Sjkim GpeEventInfo->RuntimeCount) 898129684Snjl { 899216471Sjkim Handler->OriginallyEnabled = TRUE; 900216471Sjkim (void) AcpiEvRemoveGpeReference (GpeEventInfo); 901216471Sjkim 902216471Sjkim /* Sanity check of original type against new type */ 903216471Sjkim 904216471Sjkim if (Type != (UINT32) (GpeEventInfo->Flags & ACPI_GPE_XRUPT_TYPE_MASK)) 905216471Sjkim { 906216471Sjkim ACPI_WARNING ((AE_INFO, "GPE type mismatch (level/edge)")); 907216471Sjkim } 908129684Snjl } 90967754Smsmith 910129684Snjl /* Install the handler */ 91185756Smsmith 912129684Snjl GpeEventInfo->Dispatch.Handler = Handler; 91399679Siwasaki 914216471Sjkim /* Setup up dispatch flags to indicate handler (vs. method/notify) */ 915129684Snjl 916193267Sjkim GpeEventInfo->Flags &= ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK); 917129684Snjl GpeEventInfo->Flags |= (UINT8) (Type | ACPI_GPE_DISPATCH_HANDLER); 918129684Snjl 919151937Sjkim AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 920129684Snjl 921129684Snjl 922117521SnjlUnlockAndExit: 92391116Smsmith (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 92467754Smsmith return_ACPI_STATUS (Status); 925216471Sjkim 926216471SjkimFreeAndExit: 927216471Sjkim AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 928216471Sjkim ACPI_FREE (Handler); 929216471Sjkim goto UnlockAndExit; 93067754Smsmith} 93167754Smsmith 932167802SjkimACPI_EXPORT_SYMBOL (AcpiInstallGpeHandler) 93367754Smsmith 934167802Sjkim 93577424Smsmith/******************************************************************************* 93667754Smsmith * 93767754Smsmith * FUNCTION: AcpiRemoveGpeHandler 93867754Smsmith * 939151937Sjkim * PARAMETERS: GpeDevice - Namespace node for the GPE (NULL for FADT 940151937Sjkim * defined GPEs) 941151937Sjkim * GpeNumber - The event to remove a handler 942129684Snjl * Address - Address of the handler 94367754Smsmith * 94467754Smsmith * RETURN: Status 94567754Smsmith * 94667754Smsmith * DESCRIPTION: Remove a handler for a General Purpose AcpiEvent. 94767754Smsmith * 94867754Smsmith ******************************************************************************/ 94967754Smsmith 95067754SmsmithACPI_STATUS 95167754SmsmithAcpiRemoveGpeHandler ( 952117521Snjl ACPI_HANDLE GpeDevice, 95367754Smsmith UINT32 GpeNumber, 954216471Sjkim ACPI_GPE_HANDLER Address) 95567754Smsmith{ 956129684Snjl ACPI_GPE_EVENT_INFO *GpeEventInfo; 957216471Sjkim ACPI_GPE_HANDLER_INFO *Handler; 95891116Smsmith ACPI_STATUS Status; 959167802Sjkim ACPI_CPU_FLAGS Flags; 96067754Smsmith 96167754Smsmith 962167802Sjkim ACPI_FUNCTION_TRACE (AcpiRemoveGpeHandler); 96367754Smsmith 96467754Smsmith 96567754Smsmith /* Parameter validation */ 96667754Smsmith 967129684Snjl if (!Address) 96867754Smsmith { 96967754Smsmith return_ACPI_STATUS (AE_BAD_PARAMETER); 97067754Smsmith } 97167754Smsmith 972235945Sjkim /* Make sure all deferred GPE tasks are completed */ 973235945Sjkim 974235945Sjkim AcpiOsWaitEventsComplete (); 975235945Sjkim 976117521Snjl Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 977117521Snjl if (ACPI_FAILURE (Status)) 978117521Snjl { 979117521Snjl return_ACPI_STATUS (Status); 980117521Snjl } 981117521Snjl 982216471Sjkim Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 983216471Sjkim 98467754Smsmith /* Ensure that we have a valid GPE number */ 98567754Smsmith 986117521Snjl GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 987114237Snjl if (!GpeEventInfo) 98867754Smsmith { 989117521Snjl Status = AE_BAD_PARAMETER; 990117521Snjl goto UnlockAndExit; 99167754Smsmith } 99267754Smsmith 993129684Snjl /* Make sure that a handler is indeed installed */ 99467754Smsmith 995193267Sjkim if ((GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) != 996193267Sjkim ACPI_GPE_DISPATCH_HANDLER) 99799679Siwasaki { 998129684Snjl Status = AE_NOT_EXIST; 999117521Snjl goto UnlockAndExit; 100099679Siwasaki } 100167754Smsmith 100267754Smsmith /* Make sure that the installed handler is the same */ 100367754Smsmith 1004129684Snjl if (GpeEventInfo->Dispatch.Handler->Address != Address) 100567754Smsmith { 100667754Smsmith Status = AE_BAD_PARAMETER; 1007117521Snjl goto UnlockAndExit; 100867754Smsmith } 100967754Smsmith 101067754Smsmith /* Remove the handler */ 101167754Smsmith 1012129684Snjl Handler = GpeEventInfo->Dispatch.Handler; 1013129684Snjl 1014129684Snjl /* Restore Method node (if any), set dispatch flags */ 1015129684Snjl 1016129684Snjl GpeEventInfo->Dispatch.MethodNode = Handler->MethodNode; 1017216471Sjkim GpeEventInfo->Flags &= 1018216471Sjkim ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK); 1019216471Sjkim GpeEventInfo->Flags |= Handler->OriginalFlags; 1020216471Sjkim 1021216471Sjkim /* 1022216471Sjkim * If the GPE was previously associated with a method and it was 1023216471Sjkim * enabled, it should be enabled at this point to restore the 1024216471Sjkim * post-initialization configuration. 1025216471Sjkim */ 1026216471Sjkim if ((Handler->OriginalFlags & ACPI_GPE_DISPATCH_METHOD) && 1027216471Sjkim Handler->OriginallyEnabled) 1028129684Snjl { 1029216471Sjkim (void) AcpiEvAddGpeReference (GpeEventInfo); 1030129684Snjl } 103167754Smsmith 1032129684Snjl /* Now we can free the handler object */ 103385756Smsmith 1034167802Sjkim ACPI_FREE (Handler); 1035129684Snjl 1036129684Snjl 1037117521SnjlUnlockAndExit: 1038216471Sjkim AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 103991116Smsmith (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 104067754Smsmith return_ACPI_STATUS (Status); 104167754Smsmith} 104267754Smsmith 1043167802SjkimACPI_EXPORT_SYMBOL (AcpiRemoveGpeHandler) 104467754Smsmith 1045167802Sjkim 104677424Smsmith/******************************************************************************* 104767754Smsmith * 104867754Smsmith * FUNCTION: AcpiAcquireGlobalLock 104967754Smsmith * 105067754Smsmith * PARAMETERS: Timeout - How long the caller is willing to wait 1051151937Sjkim * Handle - Where the handle to the lock is returned 1052151937Sjkim * (if acquired) 105367754Smsmith * 105467754Smsmith * RETURN: Status 105567754Smsmith * 105667754Smsmith * DESCRIPTION: Acquire the ACPI Global Lock 105767754Smsmith * 1058167802Sjkim * Note: Allows callers with the same thread ID to acquire the global lock 1059167802Sjkim * multiple times. In other words, externally, the behavior of the global lock 1060167802Sjkim * is identical to an AML mutex. On the first acquire, a new handle is 1061167802Sjkim * returned. On any subsequent calls to acquire by the same thread, the same 1062167802Sjkim * handle is returned. 1063167802Sjkim * 106467754Smsmith ******************************************************************************/ 106585756Smsmith 106667754SmsmithACPI_STATUS 106767754SmsmithAcpiAcquireGlobalLock ( 1068107325Siwasaki UINT16 Timeout, 106991116Smsmith UINT32 *Handle) 107067754Smsmith{ 107167754Smsmith ACPI_STATUS Status; 107267754Smsmith 107367754Smsmith 107491116Smsmith if (!Handle) 107591116Smsmith { 107691116Smsmith return (AE_BAD_PARAMETER); 107791116Smsmith } 107891116Smsmith 1079167802Sjkim /* Must lock interpreter to prevent race conditions */ 108077424Smsmith 1081167802Sjkim AcpiExEnterInterpreter (); 108267754Smsmith 1083167802Sjkim Status = AcpiExAcquireMutexObject (Timeout, 1084167802Sjkim AcpiGbl_GlobalLockMutex, AcpiOsGetThreadId ()); 1085167802Sjkim 108691116Smsmith if (ACPI_SUCCESS (Status)) 108791116Smsmith { 1088172314Sjkim /* Return the global lock handle (updated in AcpiEvAcquireGlobalLock) */ 1089167802Sjkim 109091116Smsmith *Handle = AcpiGbl_GlobalLockHandle; 109191116Smsmith } 109291116Smsmith 1093167802Sjkim AcpiExExitInterpreter (); 109467754Smsmith return (Status); 109567754Smsmith} 109667754Smsmith 1097167802SjkimACPI_EXPORT_SYMBOL (AcpiAcquireGlobalLock) 109867754Smsmith 1099167802Sjkim 110077424Smsmith/******************************************************************************* 110167754Smsmith * 110267754Smsmith * FUNCTION: AcpiReleaseGlobalLock 110367754Smsmith * 110467754Smsmith * PARAMETERS: Handle - Returned from AcpiAcquireGlobalLock 110567754Smsmith * 110667754Smsmith * RETURN: Status 110767754Smsmith * 1108151937Sjkim * DESCRIPTION: Release the ACPI Global Lock. The handle must be valid. 110967754Smsmith * 111067754Smsmith ******************************************************************************/ 111167754Smsmith 111267754SmsmithACPI_STATUS 111367754SmsmithAcpiReleaseGlobalLock ( 111491116Smsmith UINT32 Handle) 111567754Smsmith{ 111699679Siwasaki ACPI_STATUS Status; 111785756Smsmith 111899679Siwasaki 1119167802Sjkim if (!Handle || (Handle != AcpiGbl_GlobalLockHandle)) 112091116Smsmith { 112191116Smsmith return (AE_NOT_ACQUIRED); 112291116Smsmith } 112391116Smsmith 1124167802Sjkim Status = AcpiExReleaseMutexObject (AcpiGbl_GlobalLockMutex); 112599679Siwasaki return (Status); 112667754Smsmith} 112767754Smsmith 1128167802SjkimACPI_EXPORT_SYMBOL (AcpiReleaseGlobalLock) 112967754Smsmith 1130231844Sjkim#endif /* !ACPI_REDUCED_HARDWARE */ 1131