1ae115bc7Smrj /****************************************************************************** 2ae115bc7Smrj * 3ae115bc7Smrj * Module Name: evxface - External interfaces for ACPI events 4ae115bc7Smrj * 5ae115bc7Smrj *****************************************************************************/ 6ae115bc7Smrj 726f3cdf0SGordon Ross /* 8*385cc6b4SJerry Jelinek * Copyright (C) 2000 - 2016, Intel Corp. 9ae115bc7Smrj * All rights reserved. 10ae115bc7Smrj * 1126f3cdf0SGordon Ross * Redistribution and use in source and binary forms, with or without 1226f3cdf0SGordon Ross * modification, are permitted provided that the following conditions 1326f3cdf0SGordon Ross * are met: 1426f3cdf0SGordon Ross * 1. Redistributions of source code must retain the above copyright 1526f3cdf0SGordon Ross * notice, this list of conditions, and the following disclaimer, 1626f3cdf0SGordon Ross * without modification. 1726f3cdf0SGordon Ross * 2. Redistributions in binary form must reproduce at minimum a disclaimer 1826f3cdf0SGordon Ross * substantially similar to the "NO WARRANTY" disclaimer below 1926f3cdf0SGordon Ross * ("Disclaimer") and any redistribution must be conditioned upon 2026f3cdf0SGordon Ross * including a substantially similar Disclaimer requirement for further 2126f3cdf0SGordon Ross * binary redistribution. 2226f3cdf0SGordon Ross * 3. Neither the names of the above-listed copyright holders nor the names 2326f3cdf0SGordon Ross * of any contributors may be used to endorse or promote products derived 2426f3cdf0SGordon Ross * from this software without specific prior written permission. 25ae115bc7Smrj * 2626f3cdf0SGordon Ross * Alternatively, this software may be distributed under the terms of the 2726f3cdf0SGordon Ross * GNU General Public License ("GPL") version 2 as published by the Free 2826f3cdf0SGordon Ross * Software Foundation. 29ae115bc7Smrj * 3026f3cdf0SGordon Ross * NO WARRANTY 3126f3cdf0SGordon Ross * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 3226f3cdf0SGordon Ross * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 3326f3cdf0SGordon Ross * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 3426f3cdf0SGordon Ross * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 3526f3cdf0SGordon Ross * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 3626f3cdf0SGordon Ross * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 3726f3cdf0SGordon Ross * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3826f3cdf0SGordon Ross * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 3926f3cdf0SGordon Ross * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 4026f3cdf0SGordon Ross * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 4126f3cdf0SGordon Ross * POSSIBILITY OF SUCH DAMAGES. 4226f3cdf0SGordon Ross */ 43ae115bc7Smrj 44*385cc6b4SJerry Jelinek #define EXPORT_ACPI_INTERFACES 45ae115bc7Smrj 46ae115bc7Smrj #include "acpi.h" 47aa2aa9a6SDana Myers #include "accommon.h" 48ae115bc7Smrj #include "acnamesp.h" 49ae115bc7Smrj #include "acevents.h" 50ae115bc7Smrj #include "acinterp.h" 51ae115bc7Smrj 52ae115bc7Smrj #define _COMPONENT ACPI_EVENTS 53ae115bc7Smrj ACPI_MODULE_NAME ("evxface") 54ae115bc7Smrj 55*385cc6b4SJerry Jelinek #if (!ACPI_REDUCED_HARDWARE) 56*385cc6b4SJerry Jelinek 57*385cc6b4SJerry Jelinek /* Local prototypes */ 58*385cc6b4SJerry Jelinek 59*385cc6b4SJerry Jelinek static ACPI_STATUS 60*385cc6b4SJerry Jelinek AcpiEvInstallGpeHandler ( 61*385cc6b4SJerry Jelinek ACPI_HANDLE GpeDevice, 62*385cc6b4SJerry Jelinek UINT32 GpeNumber, 63*385cc6b4SJerry Jelinek UINT32 Type, 64*385cc6b4SJerry Jelinek BOOLEAN IsRawHandler, 65*385cc6b4SJerry Jelinek ACPI_GPE_HANDLER Address, 66*385cc6b4SJerry Jelinek void *Context); 67*385cc6b4SJerry Jelinek 68*385cc6b4SJerry Jelinek #endif 69*385cc6b4SJerry Jelinek 70*385cc6b4SJerry Jelinek 71*385cc6b4SJerry Jelinek /******************************************************************************* 72*385cc6b4SJerry Jelinek * 73*385cc6b4SJerry Jelinek * FUNCTION: AcpiInstallNotifyHandler 74*385cc6b4SJerry Jelinek * 75*385cc6b4SJerry Jelinek * PARAMETERS: Device - The device for which notifies will be handled 76*385cc6b4SJerry Jelinek * HandlerType - The type of handler: 77*385cc6b4SJerry Jelinek * ACPI_SYSTEM_NOTIFY: System Handler (00-7F) 78*385cc6b4SJerry Jelinek * ACPI_DEVICE_NOTIFY: Device Handler (80-FF) 79*385cc6b4SJerry Jelinek * ACPI_ALL_NOTIFY: Both System and Device 80*385cc6b4SJerry Jelinek * Handler - Address of the handler 81*385cc6b4SJerry Jelinek * Context - Value passed to the handler on each GPE 82*385cc6b4SJerry Jelinek * 83*385cc6b4SJerry Jelinek * RETURN: Status 84*385cc6b4SJerry Jelinek * 85*385cc6b4SJerry Jelinek * DESCRIPTION: Install a handler for notifications on an ACPI Device, 86*385cc6b4SJerry Jelinek * ThermalZone, or Processor object. 87*385cc6b4SJerry Jelinek * 88*385cc6b4SJerry Jelinek * NOTES: The Root namespace object may have only one handler for each 89*385cc6b4SJerry Jelinek * type of notify (System/Device). Device/Thermal/Processor objects 90*385cc6b4SJerry Jelinek * may have one device notify handler, and multiple system notify 91*385cc6b4SJerry Jelinek * handlers. 92*385cc6b4SJerry Jelinek * 93*385cc6b4SJerry Jelinek ******************************************************************************/ 94*385cc6b4SJerry Jelinek 95*385cc6b4SJerry Jelinek ACPI_STATUS 96*385cc6b4SJerry Jelinek AcpiInstallNotifyHandler ( 97*385cc6b4SJerry Jelinek ACPI_HANDLE Device, 98*385cc6b4SJerry Jelinek UINT32 HandlerType, 99*385cc6b4SJerry Jelinek ACPI_NOTIFY_HANDLER Handler, 100*385cc6b4SJerry Jelinek void *Context) 101*385cc6b4SJerry Jelinek { 102*385cc6b4SJerry Jelinek ACPI_NAMESPACE_NODE *Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Device); 103*385cc6b4SJerry Jelinek ACPI_OPERAND_OBJECT *ObjDesc; 104*385cc6b4SJerry Jelinek ACPI_OPERAND_OBJECT *HandlerObj; 105*385cc6b4SJerry Jelinek ACPI_STATUS Status; 106*385cc6b4SJerry Jelinek UINT32 i; 107*385cc6b4SJerry Jelinek 108*385cc6b4SJerry Jelinek 109*385cc6b4SJerry Jelinek ACPI_FUNCTION_TRACE (AcpiInstallNotifyHandler); 110*385cc6b4SJerry Jelinek 111*385cc6b4SJerry Jelinek 112*385cc6b4SJerry Jelinek /* Parameter validation */ 113*385cc6b4SJerry Jelinek 114*385cc6b4SJerry Jelinek if ((!Device) || (!Handler) || (!HandlerType) || 115*385cc6b4SJerry Jelinek (HandlerType > ACPI_MAX_NOTIFY_HANDLER_TYPE)) 116*385cc6b4SJerry Jelinek { 117*385cc6b4SJerry Jelinek return_ACPI_STATUS (AE_BAD_PARAMETER); 118*385cc6b4SJerry Jelinek } 119*385cc6b4SJerry Jelinek 120*385cc6b4SJerry Jelinek Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 121*385cc6b4SJerry Jelinek if (ACPI_FAILURE (Status)) 122*385cc6b4SJerry Jelinek { 123*385cc6b4SJerry Jelinek return_ACPI_STATUS (Status); 124*385cc6b4SJerry Jelinek } 125*385cc6b4SJerry Jelinek 126*385cc6b4SJerry Jelinek /* 127*385cc6b4SJerry Jelinek * Root Object: 128*385cc6b4SJerry Jelinek * Registering a notify handler on the root object indicates that the 129*385cc6b4SJerry Jelinek * caller wishes to receive notifications for all objects. Note that 130*385cc6b4SJerry Jelinek * only one global handler can be registered per notify type. 131*385cc6b4SJerry Jelinek * Ensure that a handler is not already installed. 132*385cc6b4SJerry Jelinek */ 133*385cc6b4SJerry Jelinek if (Device == ACPI_ROOT_OBJECT) 134*385cc6b4SJerry Jelinek { 135*385cc6b4SJerry Jelinek for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++) 136*385cc6b4SJerry Jelinek { 137*385cc6b4SJerry Jelinek if (HandlerType & (i+1)) 138*385cc6b4SJerry Jelinek { 139*385cc6b4SJerry Jelinek if (AcpiGbl_GlobalNotify[i].Handler) 140*385cc6b4SJerry Jelinek { 141*385cc6b4SJerry Jelinek Status = AE_ALREADY_EXISTS; 142*385cc6b4SJerry Jelinek goto UnlockAndExit; 143*385cc6b4SJerry Jelinek } 144*385cc6b4SJerry Jelinek 145*385cc6b4SJerry Jelinek AcpiGbl_GlobalNotify[i].Handler = Handler; 146*385cc6b4SJerry Jelinek AcpiGbl_GlobalNotify[i].Context = Context; 147*385cc6b4SJerry Jelinek } 148*385cc6b4SJerry Jelinek } 149*385cc6b4SJerry Jelinek 150*385cc6b4SJerry Jelinek goto UnlockAndExit; /* Global notify handler installed, all done */ 151*385cc6b4SJerry Jelinek } 152*385cc6b4SJerry Jelinek 153*385cc6b4SJerry Jelinek /* 154*385cc6b4SJerry Jelinek * All Other Objects: 155*385cc6b4SJerry Jelinek * Caller will only receive notifications specific to the target 156*385cc6b4SJerry Jelinek * object. Note that only certain object types are allowed to 157*385cc6b4SJerry Jelinek * receive notifications. 158*385cc6b4SJerry Jelinek */ 159*385cc6b4SJerry Jelinek 160*385cc6b4SJerry Jelinek /* Are Notifies allowed on this object? */ 161*385cc6b4SJerry Jelinek 162*385cc6b4SJerry Jelinek if (!AcpiEvIsNotifyObject (Node)) 163*385cc6b4SJerry Jelinek { 164*385cc6b4SJerry Jelinek Status = AE_TYPE; 165*385cc6b4SJerry Jelinek goto UnlockAndExit; 166*385cc6b4SJerry Jelinek } 167*385cc6b4SJerry Jelinek 168*385cc6b4SJerry Jelinek /* Check for an existing internal object, might not exist */ 169*385cc6b4SJerry Jelinek 170*385cc6b4SJerry Jelinek ObjDesc = AcpiNsGetAttachedObject (Node); 171*385cc6b4SJerry Jelinek if (!ObjDesc) 172*385cc6b4SJerry Jelinek { 173*385cc6b4SJerry Jelinek /* Create a new object */ 174*385cc6b4SJerry Jelinek 175*385cc6b4SJerry Jelinek ObjDesc = AcpiUtCreateInternalObject (Node->Type); 176*385cc6b4SJerry Jelinek if (!ObjDesc) 177*385cc6b4SJerry Jelinek { 178*385cc6b4SJerry Jelinek Status = AE_NO_MEMORY; 179*385cc6b4SJerry Jelinek goto UnlockAndExit; 180*385cc6b4SJerry Jelinek } 181*385cc6b4SJerry Jelinek 182*385cc6b4SJerry Jelinek /* Attach new object to the Node, remove local reference */ 183*385cc6b4SJerry Jelinek 184*385cc6b4SJerry Jelinek Status = AcpiNsAttachObject (Device, ObjDesc, Node->Type); 185*385cc6b4SJerry Jelinek AcpiUtRemoveReference (ObjDesc); 186*385cc6b4SJerry Jelinek if (ACPI_FAILURE (Status)) 187*385cc6b4SJerry Jelinek { 188*385cc6b4SJerry Jelinek goto UnlockAndExit; 189*385cc6b4SJerry Jelinek } 190*385cc6b4SJerry Jelinek } 191*385cc6b4SJerry Jelinek 192*385cc6b4SJerry Jelinek /* Ensure that the handler is not already installed in the lists */ 193*385cc6b4SJerry Jelinek 194*385cc6b4SJerry Jelinek for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++) 195*385cc6b4SJerry Jelinek { 196*385cc6b4SJerry Jelinek if (HandlerType & (i+1)) 197*385cc6b4SJerry Jelinek { 198*385cc6b4SJerry Jelinek HandlerObj = ObjDesc->CommonNotify.NotifyList[i]; 199*385cc6b4SJerry Jelinek while (HandlerObj) 200*385cc6b4SJerry Jelinek { 201*385cc6b4SJerry Jelinek if (HandlerObj->Notify.Handler == Handler) 202*385cc6b4SJerry Jelinek { 203*385cc6b4SJerry Jelinek Status = AE_ALREADY_EXISTS; 204*385cc6b4SJerry Jelinek goto UnlockAndExit; 205*385cc6b4SJerry Jelinek } 206*385cc6b4SJerry Jelinek 207*385cc6b4SJerry Jelinek HandlerObj = HandlerObj->Notify.Next[i]; 208*385cc6b4SJerry Jelinek } 209*385cc6b4SJerry Jelinek } 210*385cc6b4SJerry Jelinek } 211*385cc6b4SJerry Jelinek 212*385cc6b4SJerry Jelinek /* Create and populate a new notify handler object */ 213*385cc6b4SJerry Jelinek 214*385cc6b4SJerry Jelinek HandlerObj = AcpiUtCreateInternalObject (ACPI_TYPE_LOCAL_NOTIFY); 215*385cc6b4SJerry Jelinek if (!HandlerObj) 216*385cc6b4SJerry Jelinek { 217*385cc6b4SJerry Jelinek Status = AE_NO_MEMORY; 218*385cc6b4SJerry Jelinek goto UnlockAndExit; 219*385cc6b4SJerry Jelinek } 220*385cc6b4SJerry Jelinek 221*385cc6b4SJerry Jelinek HandlerObj->Notify.Node = Node; 222*385cc6b4SJerry Jelinek HandlerObj->Notify.HandlerType = HandlerType; 223*385cc6b4SJerry Jelinek HandlerObj->Notify.Handler = Handler; 224*385cc6b4SJerry Jelinek HandlerObj->Notify.Context = Context; 225*385cc6b4SJerry Jelinek 226*385cc6b4SJerry Jelinek /* Install the handler at the list head(s) */ 227*385cc6b4SJerry Jelinek 228*385cc6b4SJerry Jelinek for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++) 229*385cc6b4SJerry Jelinek { 230*385cc6b4SJerry Jelinek if (HandlerType & (i+1)) 231*385cc6b4SJerry Jelinek { 232*385cc6b4SJerry Jelinek HandlerObj->Notify.Next[i] = 233*385cc6b4SJerry Jelinek ObjDesc->CommonNotify.NotifyList[i]; 234*385cc6b4SJerry Jelinek 235*385cc6b4SJerry Jelinek ObjDesc->CommonNotify.NotifyList[i] = HandlerObj; 236*385cc6b4SJerry Jelinek } 237*385cc6b4SJerry Jelinek } 238*385cc6b4SJerry Jelinek 239*385cc6b4SJerry Jelinek /* Add an extra reference if handler was installed in both lists */ 240*385cc6b4SJerry Jelinek 241*385cc6b4SJerry Jelinek if (HandlerType == ACPI_ALL_NOTIFY) 242*385cc6b4SJerry Jelinek { 243*385cc6b4SJerry Jelinek AcpiUtAddReference (HandlerObj); 244*385cc6b4SJerry Jelinek } 245*385cc6b4SJerry Jelinek 246*385cc6b4SJerry Jelinek 247*385cc6b4SJerry Jelinek UnlockAndExit: 248*385cc6b4SJerry Jelinek (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 249*385cc6b4SJerry Jelinek return_ACPI_STATUS (Status); 250*385cc6b4SJerry Jelinek } 251*385cc6b4SJerry Jelinek 252*385cc6b4SJerry Jelinek ACPI_EXPORT_SYMBOL (AcpiInstallNotifyHandler) 253*385cc6b4SJerry Jelinek 254*385cc6b4SJerry Jelinek 255*385cc6b4SJerry Jelinek /******************************************************************************* 256*385cc6b4SJerry Jelinek * 257*385cc6b4SJerry Jelinek * FUNCTION: AcpiRemoveNotifyHandler 258*385cc6b4SJerry Jelinek * 259*385cc6b4SJerry Jelinek * PARAMETERS: Device - The device for which the handler is installed 260*385cc6b4SJerry Jelinek * HandlerType - The type of handler: 261*385cc6b4SJerry Jelinek * ACPI_SYSTEM_NOTIFY: System Handler (00-7F) 262*385cc6b4SJerry Jelinek * ACPI_DEVICE_NOTIFY: Device Handler (80-FF) 263*385cc6b4SJerry Jelinek * ACPI_ALL_NOTIFY: Both System and Device 264*385cc6b4SJerry Jelinek * Handler - Address of the handler 265*385cc6b4SJerry Jelinek * 266*385cc6b4SJerry Jelinek * RETURN: Status 267*385cc6b4SJerry Jelinek * 268*385cc6b4SJerry Jelinek * DESCRIPTION: Remove a handler for notifies on an ACPI device 269*385cc6b4SJerry Jelinek * 270*385cc6b4SJerry Jelinek ******************************************************************************/ 271*385cc6b4SJerry Jelinek 272*385cc6b4SJerry Jelinek ACPI_STATUS 273*385cc6b4SJerry Jelinek AcpiRemoveNotifyHandler ( 274*385cc6b4SJerry Jelinek ACPI_HANDLE Device, 275*385cc6b4SJerry Jelinek UINT32 HandlerType, 276*385cc6b4SJerry Jelinek ACPI_NOTIFY_HANDLER Handler) 277*385cc6b4SJerry Jelinek { 278*385cc6b4SJerry Jelinek ACPI_NAMESPACE_NODE *Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Device); 279*385cc6b4SJerry Jelinek ACPI_OPERAND_OBJECT *ObjDesc; 280*385cc6b4SJerry Jelinek ACPI_OPERAND_OBJECT *HandlerObj; 281*385cc6b4SJerry Jelinek ACPI_OPERAND_OBJECT *PreviousHandlerObj; 282*385cc6b4SJerry Jelinek ACPI_STATUS Status = AE_OK; 283*385cc6b4SJerry Jelinek UINT32 i; 284*385cc6b4SJerry Jelinek 285*385cc6b4SJerry Jelinek 286*385cc6b4SJerry Jelinek ACPI_FUNCTION_TRACE (AcpiRemoveNotifyHandler); 287*385cc6b4SJerry Jelinek 288*385cc6b4SJerry Jelinek 289*385cc6b4SJerry Jelinek /* Parameter validation */ 290*385cc6b4SJerry Jelinek 291*385cc6b4SJerry Jelinek if ((!Device) || (!Handler) || (!HandlerType) || 292*385cc6b4SJerry Jelinek (HandlerType > ACPI_MAX_NOTIFY_HANDLER_TYPE)) 293*385cc6b4SJerry Jelinek { 294*385cc6b4SJerry Jelinek return_ACPI_STATUS (AE_BAD_PARAMETER); 295*385cc6b4SJerry Jelinek } 296*385cc6b4SJerry Jelinek 297*385cc6b4SJerry Jelinek /* Root Object. Global handlers are removed here */ 298*385cc6b4SJerry Jelinek 299*385cc6b4SJerry Jelinek if (Device == ACPI_ROOT_OBJECT) 300*385cc6b4SJerry Jelinek { 301*385cc6b4SJerry Jelinek for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++) 302*385cc6b4SJerry Jelinek { 303*385cc6b4SJerry Jelinek if (HandlerType & (i+1)) 304*385cc6b4SJerry Jelinek { 305*385cc6b4SJerry Jelinek Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 306*385cc6b4SJerry Jelinek if (ACPI_FAILURE (Status)) 307*385cc6b4SJerry Jelinek { 308*385cc6b4SJerry Jelinek return_ACPI_STATUS (Status); 309*385cc6b4SJerry Jelinek } 310*385cc6b4SJerry Jelinek 311*385cc6b4SJerry Jelinek if (!AcpiGbl_GlobalNotify[i].Handler || 312*385cc6b4SJerry Jelinek (AcpiGbl_GlobalNotify[i].Handler != Handler)) 313*385cc6b4SJerry Jelinek { 314*385cc6b4SJerry Jelinek Status = AE_NOT_EXIST; 315*385cc6b4SJerry Jelinek goto UnlockAndExit; 316*385cc6b4SJerry Jelinek } 317*385cc6b4SJerry Jelinek 318*385cc6b4SJerry Jelinek ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 319*385cc6b4SJerry Jelinek "Removing global notify handler\n")); 320*385cc6b4SJerry Jelinek 321*385cc6b4SJerry Jelinek AcpiGbl_GlobalNotify[i].Handler = NULL; 322*385cc6b4SJerry Jelinek AcpiGbl_GlobalNotify[i].Context = NULL; 323*385cc6b4SJerry Jelinek 324*385cc6b4SJerry Jelinek (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 325*385cc6b4SJerry Jelinek 326*385cc6b4SJerry Jelinek /* Make sure all deferred notify tasks are completed */ 327*385cc6b4SJerry Jelinek 328*385cc6b4SJerry Jelinek AcpiOsWaitEventsComplete (); 329*385cc6b4SJerry Jelinek } 330*385cc6b4SJerry Jelinek } 331*385cc6b4SJerry Jelinek 332*385cc6b4SJerry Jelinek return_ACPI_STATUS (AE_OK); 333*385cc6b4SJerry Jelinek } 334*385cc6b4SJerry Jelinek 335*385cc6b4SJerry Jelinek /* All other objects: Are Notifies allowed on this object? */ 336*385cc6b4SJerry Jelinek 337*385cc6b4SJerry Jelinek if (!AcpiEvIsNotifyObject (Node)) 338*385cc6b4SJerry Jelinek { 339*385cc6b4SJerry Jelinek return_ACPI_STATUS (AE_TYPE); 340*385cc6b4SJerry Jelinek } 341*385cc6b4SJerry Jelinek 342*385cc6b4SJerry Jelinek /* Must have an existing internal object */ 343*385cc6b4SJerry Jelinek 344*385cc6b4SJerry Jelinek ObjDesc = AcpiNsGetAttachedObject (Node); 345*385cc6b4SJerry Jelinek if (!ObjDesc) 346*385cc6b4SJerry Jelinek { 347*385cc6b4SJerry Jelinek return_ACPI_STATUS (AE_NOT_EXIST); 348*385cc6b4SJerry Jelinek } 349*385cc6b4SJerry Jelinek 350*385cc6b4SJerry Jelinek /* Internal object exists. Find the handler and remove it */ 351*385cc6b4SJerry Jelinek 352*385cc6b4SJerry Jelinek for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++) 353*385cc6b4SJerry Jelinek { 354*385cc6b4SJerry Jelinek if (HandlerType & (i+1)) 355*385cc6b4SJerry Jelinek { 356*385cc6b4SJerry Jelinek Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 357*385cc6b4SJerry Jelinek if (ACPI_FAILURE (Status)) 358*385cc6b4SJerry Jelinek { 359*385cc6b4SJerry Jelinek return_ACPI_STATUS (Status); 360*385cc6b4SJerry Jelinek } 361*385cc6b4SJerry Jelinek 362*385cc6b4SJerry Jelinek HandlerObj = ObjDesc->CommonNotify.NotifyList[i]; 363*385cc6b4SJerry Jelinek PreviousHandlerObj = NULL; 364*385cc6b4SJerry Jelinek 365*385cc6b4SJerry Jelinek /* Attempt to find the handler in the handler list */ 366*385cc6b4SJerry Jelinek 367*385cc6b4SJerry Jelinek while (HandlerObj && 368*385cc6b4SJerry Jelinek (HandlerObj->Notify.Handler != Handler)) 369*385cc6b4SJerry Jelinek { 370*385cc6b4SJerry Jelinek PreviousHandlerObj = HandlerObj; 371*385cc6b4SJerry Jelinek HandlerObj = HandlerObj->Notify.Next[i]; 372*385cc6b4SJerry Jelinek } 373*385cc6b4SJerry Jelinek 374*385cc6b4SJerry Jelinek if (!HandlerObj) 375*385cc6b4SJerry Jelinek { 376*385cc6b4SJerry Jelinek Status = AE_NOT_EXIST; 377*385cc6b4SJerry Jelinek goto UnlockAndExit; 378*385cc6b4SJerry Jelinek } 379*385cc6b4SJerry Jelinek 380*385cc6b4SJerry Jelinek /* Remove the handler object from the list */ 381*385cc6b4SJerry Jelinek 382*385cc6b4SJerry Jelinek if (PreviousHandlerObj) /* Handler is not at the list head */ 383*385cc6b4SJerry Jelinek { 384*385cc6b4SJerry Jelinek PreviousHandlerObj->Notify.Next[i] = 385*385cc6b4SJerry Jelinek HandlerObj->Notify.Next[i]; 386*385cc6b4SJerry Jelinek } 387*385cc6b4SJerry Jelinek else /* Handler is at the list head */ 388*385cc6b4SJerry Jelinek { 389*385cc6b4SJerry Jelinek ObjDesc->CommonNotify.NotifyList[i] = 390*385cc6b4SJerry Jelinek HandlerObj->Notify.Next[i]; 391*385cc6b4SJerry Jelinek } 392*385cc6b4SJerry Jelinek 393*385cc6b4SJerry Jelinek (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 394*385cc6b4SJerry Jelinek 395*385cc6b4SJerry Jelinek /* Make sure all deferred notify tasks are completed */ 396*385cc6b4SJerry Jelinek 397*385cc6b4SJerry Jelinek AcpiOsWaitEventsComplete (); 398*385cc6b4SJerry Jelinek AcpiUtRemoveReference (HandlerObj); 399*385cc6b4SJerry Jelinek } 400*385cc6b4SJerry Jelinek } 401*385cc6b4SJerry Jelinek 402*385cc6b4SJerry Jelinek return_ACPI_STATUS (Status); 403*385cc6b4SJerry Jelinek 404*385cc6b4SJerry Jelinek 405*385cc6b4SJerry Jelinek UnlockAndExit: 406*385cc6b4SJerry Jelinek (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 407*385cc6b4SJerry Jelinek return_ACPI_STATUS (Status); 408*385cc6b4SJerry Jelinek } 409*385cc6b4SJerry Jelinek 410*385cc6b4SJerry Jelinek ACPI_EXPORT_SYMBOL (AcpiRemoveNotifyHandler) 411*385cc6b4SJerry Jelinek 412ae115bc7Smrj 413ae115bc7Smrj /******************************************************************************* 414ae115bc7Smrj * 415ae115bc7Smrj * FUNCTION: AcpiInstallExceptionHandler 416ae115bc7Smrj * 417ae115bc7Smrj * PARAMETERS: Handler - Pointer to the handler function for the 418ae115bc7Smrj * event 419ae115bc7Smrj * 420ae115bc7Smrj * RETURN: Status 421ae115bc7Smrj * 422ae115bc7Smrj * DESCRIPTION: Saves the pointer to the handler function 423ae115bc7Smrj * 424ae115bc7Smrj ******************************************************************************/ 425ae115bc7Smrj 426ae115bc7Smrj ACPI_STATUS 427ae115bc7Smrj AcpiInstallExceptionHandler ( 428ae115bc7Smrj ACPI_EXCEPTION_HANDLER Handler) 429ae115bc7Smrj { 430ae115bc7Smrj ACPI_STATUS Status; 431ae115bc7Smrj 432ae115bc7Smrj 433ae115bc7Smrj ACPI_FUNCTION_TRACE (AcpiInstallExceptionHandler); 434ae115bc7Smrj 435ae115bc7Smrj 436ae115bc7Smrj Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 437ae115bc7Smrj if (ACPI_FAILURE (Status)) 438ae115bc7Smrj { 439ae115bc7Smrj return_ACPI_STATUS (Status); 440ae115bc7Smrj } 441ae115bc7Smrj 442ae115bc7Smrj /* Don't allow two handlers. */ 443ae115bc7Smrj 444ae115bc7Smrj if (AcpiGbl_ExceptionHandler) 445ae115bc7Smrj { 446ae115bc7Smrj Status = AE_ALREADY_EXISTS; 447ae115bc7Smrj goto Cleanup; 448ae115bc7Smrj } 449ae115bc7Smrj 450ae115bc7Smrj /* Install the handler */ 451ae115bc7Smrj 452ae115bc7Smrj AcpiGbl_ExceptionHandler = Handler; 453ae115bc7Smrj 454ae115bc7Smrj Cleanup: 455ae115bc7Smrj (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 456ae115bc7Smrj return_ACPI_STATUS (Status); 457ae115bc7Smrj } 458ae115bc7Smrj 459ae115bc7Smrj ACPI_EXPORT_SYMBOL (AcpiInstallExceptionHandler) 460ae115bc7Smrj 461ae115bc7Smrj 462*385cc6b4SJerry Jelinek #if (!ACPI_REDUCED_HARDWARE) 463*385cc6b4SJerry Jelinek /******************************************************************************* 464*385cc6b4SJerry Jelinek * 465*385cc6b4SJerry Jelinek * FUNCTION: AcpiInstallSciHandler 466*385cc6b4SJerry Jelinek * 467*385cc6b4SJerry Jelinek * PARAMETERS: Address - Address of the handler 468*385cc6b4SJerry Jelinek * Context - Value passed to the handler on each SCI 469*385cc6b4SJerry Jelinek * 470*385cc6b4SJerry Jelinek * RETURN: Status 471*385cc6b4SJerry Jelinek * 472*385cc6b4SJerry Jelinek * DESCRIPTION: Install a handler for a System Control Interrupt. 473*385cc6b4SJerry Jelinek * 474*385cc6b4SJerry Jelinek ******************************************************************************/ 475*385cc6b4SJerry Jelinek 476*385cc6b4SJerry Jelinek ACPI_STATUS 477*385cc6b4SJerry Jelinek AcpiInstallSciHandler ( 478*385cc6b4SJerry Jelinek ACPI_SCI_HANDLER Address, 479*385cc6b4SJerry Jelinek void *Context) 480*385cc6b4SJerry Jelinek { 481*385cc6b4SJerry Jelinek ACPI_SCI_HANDLER_INFO *NewSciHandler; 482*385cc6b4SJerry Jelinek ACPI_SCI_HANDLER_INFO *SciHandler; 483*385cc6b4SJerry Jelinek ACPI_CPU_FLAGS Flags; 484*385cc6b4SJerry Jelinek ACPI_STATUS Status; 485*385cc6b4SJerry Jelinek 486*385cc6b4SJerry Jelinek 487*385cc6b4SJerry Jelinek ACPI_FUNCTION_TRACE (AcpiInstallSciHandler); 488*385cc6b4SJerry Jelinek 489*385cc6b4SJerry Jelinek 490*385cc6b4SJerry Jelinek if (!Address) 491*385cc6b4SJerry Jelinek { 492*385cc6b4SJerry Jelinek return_ACPI_STATUS (AE_BAD_PARAMETER); 493*385cc6b4SJerry Jelinek } 494*385cc6b4SJerry Jelinek 495*385cc6b4SJerry Jelinek /* Allocate and init a handler object */ 496*385cc6b4SJerry Jelinek 497*385cc6b4SJerry Jelinek NewSciHandler = ACPI_ALLOCATE (sizeof (ACPI_SCI_HANDLER_INFO)); 498*385cc6b4SJerry Jelinek if (!NewSciHandler) 499*385cc6b4SJerry Jelinek { 500*385cc6b4SJerry Jelinek return_ACPI_STATUS (AE_NO_MEMORY); 501*385cc6b4SJerry Jelinek } 502*385cc6b4SJerry Jelinek 503*385cc6b4SJerry Jelinek NewSciHandler->Address = Address; 504*385cc6b4SJerry Jelinek NewSciHandler->Context = Context; 505*385cc6b4SJerry Jelinek 506*385cc6b4SJerry Jelinek Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 507*385cc6b4SJerry Jelinek if (ACPI_FAILURE (Status)) 508*385cc6b4SJerry Jelinek { 509*385cc6b4SJerry Jelinek goto Exit; 510*385cc6b4SJerry Jelinek } 511*385cc6b4SJerry Jelinek 512*385cc6b4SJerry Jelinek /* Lock list during installation */ 513*385cc6b4SJerry Jelinek 514*385cc6b4SJerry Jelinek Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 515*385cc6b4SJerry Jelinek SciHandler = AcpiGbl_SciHandlerList; 516*385cc6b4SJerry Jelinek 517*385cc6b4SJerry Jelinek /* Ensure handler does not already exist */ 518*385cc6b4SJerry Jelinek 519*385cc6b4SJerry Jelinek while (SciHandler) 520*385cc6b4SJerry Jelinek { 521*385cc6b4SJerry Jelinek if (Address == SciHandler->Address) 522*385cc6b4SJerry Jelinek { 523*385cc6b4SJerry Jelinek Status = AE_ALREADY_EXISTS; 524*385cc6b4SJerry Jelinek goto UnlockAndExit; 525*385cc6b4SJerry Jelinek } 526*385cc6b4SJerry Jelinek 527*385cc6b4SJerry Jelinek SciHandler = SciHandler->Next; 528*385cc6b4SJerry Jelinek } 529*385cc6b4SJerry Jelinek 530*385cc6b4SJerry Jelinek /* Install the new handler into the global list (at head) */ 531*385cc6b4SJerry Jelinek 532*385cc6b4SJerry Jelinek NewSciHandler->Next = AcpiGbl_SciHandlerList; 533*385cc6b4SJerry Jelinek AcpiGbl_SciHandlerList = NewSciHandler; 534*385cc6b4SJerry Jelinek 535*385cc6b4SJerry Jelinek 536*385cc6b4SJerry Jelinek UnlockAndExit: 537*385cc6b4SJerry Jelinek 538*385cc6b4SJerry Jelinek AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 539*385cc6b4SJerry Jelinek (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 540*385cc6b4SJerry Jelinek 541*385cc6b4SJerry Jelinek Exit: 542*385cc6b4SJerry Jelinek if (ACPI_FAILURE (Status)) 543*385cc6b4SJerry Jelinek { 544*385cc6b4SJerry Jelinek ACPI_FREE (NewSciHandler); 545*385cc6b4SJerry Jelinek } 546*385cc6b4SJerry Jelinek return_ACPI_STATUS (Status); 547*385cc6b4SJerry Jelinek } 548*385cc6b4SJerry Jelinek 549*385cc6b4SJerry Jelinek ACPI_EXPORT_SYMBOL (AcpiInstallSciHandler) 550*385cc6b4SJerry Jelinek 551*385cc6b4SJerry Jelinek 552*385cc6b4SJerry Jelinek /******************************************************************************* 553*385cc6b4SJerry Jelinek * 554*385cc6b4SJerry Jelinek * FUNCTION: AcpiRemoveSciHandler 555*385cc6b4SJerry Jelinek * 556*385cc6b4SJerry Jelinek * PARAMETERS: Address - Address of the handler 557*385cc6b4SJerry Jelinek * 558*385cc6b4SJerry Jelinek * RETURN: Status 559*385cc6b4SJerry Jelinek * 560*385cc6b4SJerry Jelinek * DESCRIPTION: Remove a handler for a System Control Interrupt. 561*385cc6b4SJerry Jelinek * 562*385cc6b4SJerry Jelinek ******************************************************************************/ 563*385cc6b4SJerry Jelinek 564*385cc6b4SJerry Jelinek ACPI_STATUS 565*385cc6b4SJerry Jelinek AcpiRemoveSciHandler ( 566*385cc6b4SJerry Jelinek ACPI_SCI_HANDLER Address) 567*385cc6b4SJerry Jelinek { 568*385cc6b4SJerry Jelinek ACPI_SCI_HANDLER_INFO *PrevSciHandler; 569*385cc6b4SJerry Jelinek ACPI_SCI_HANDLER_INFO *NextSciHandler; 570*385cc6b4SJerry Jelinek ACPI_CPU_FLAGS Flags; 571*385cc6b4SJerry Jelinek ACPI_STATUS Status; 572*385cc6b4SJerry Jelinek 573*385cc6b4SJerry Jelinek 574*385cc6b4SJerry Jelinek ACPI_FUNCTION_TRACE (AcpiRemoveSciHandler); 575*385cc6b4SJerry Jelinek 576*385cc6b4SJerry Jelinek 577*385cc6b4SJerry Jelinek if (!Address) 578*385cc6b4SJerry Jelinek { 579*385cc6b4SJerry Jelinek return_ACPI_STATUS (AE_BAD_PARAMETER); 580*385cc6b4SJerry Jelinek } 581*385cc6b4SJerry Jelinek 582*385cc6b4SJerry Jelinek Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 583*385cc6b4SJerry Jelinek if (ACPI_FAILURE (Status)) 584*385cc6b4SJerry Jelinek { 585*385cc6b4SJerry Jelinek return_ACPI_STATUS (Status); 586*385cc6b4SJerry Jelinek } 587*385cc6b4SJerry Jelinek 588*385cc6b4SJerry Jelinek /* Remove the SCI handler with lock */ 589*385cc6b4SJerry Jelinek 590*385cc6b4SJerry Jelinek Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 591*385cc6b4SJerry Jelinek 592*385cc6b4SJerry Jelinek PrevSciHandler = NULL; 593*385cc6b4SJerry Jelinek NextSciHandler = AcpiGbl_SciHandlerList; 594*385cc6b4SJerry Jelinek while (NextSciHandler) 595*385cc6b4SJerry Jelinek { 596*385cc6b4SJerry Jelinek if (NextSciHandler->Address == Address) 597*385cc6b4SJerry Jelinek { 598*385cc6b4SJerry Jelinek /* Unlink and free the SCI handler info block */ 599*385cc6b4SJerry Jelinek 600*385cc6b4SJerry Jelinek if (PrevSciHandler) 601*385cc6b4SJerry Jelinek { 602*385cc6b4SJerry Jelinek PrevSciHandler->Next = NextSciHandler->Next; 603*385cc6b4SJerry Jelinek } 604*385cc6b4SJerry Jelinek else 605*385cc6b4SJerry Jelinek { 606*385cc6b4SJerry Jelinek AcpiGbl_SciHandlerList = NextSciHandler->Next; 607*385cc6b4SJerry Jelinek } 608*385cc6b4SJerry Jelinek 609*385cc6b4SJerry Jelinek AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 610*385cc6b4SJerry Jelinek ACPI_FREE (NextSciHandler); 611*385cc6b4SJerry Jelinek goto UnlockAndExit; 612*385cc6b4SJerry Jelinek } 613*385cc6b4SJerry Jelinek 614*385cc6b4SJerry Jelinek PrevSciHandler = NextSciHandler; 615*385cc6b4SJerry Jelinek NextSciHandler = NextSciHandler->Next; 616*385cc6b4SJerry Jelinek } 617*385cc6b4SJerry Jelinek 618*385cc6b4SJerry Jelinek AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 619*385cc6b4SJerry Jelinek Status = AE_NOT_EXIST; 620*385cc6b4SJerry Jelinek 621*385cc6b4SJerry Jelinek 622*385cc6b4SJerry Jelinek UnlockAndExit: 623*385cc6b4SJerry Jelinek (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 624*385cc6b4SJerry Jelinek return_ACPI_STATUS (Status); 625*385cc6b4SJerry Jelinek } 626*385cc6b4SJerry Jelinek 627*385cc6b4SJerry Jelinek ACPI_EXPORT_SYMBOL (AcpiRemoveSciHandler) 628*385cc6b4SJerry Jelinek 629*385cc6b4SJerry Jelinek 630ae115bc7Smrj /******************************************************************************* 631ae115bc7Smrj * 63226f3cdf0SGordon Ross * FUNCTION: AcpiInstallGlobalEventHandler 63326f3cdf0SGordon Ross * 63426f3cdf0SGordon Ross * PARAMETERS: Handler - Pointer to the global event handler function 63526f3cdf0SGordon Ross * Context - Value passed to the handler on each event 63626f3cdf0SGordon Ross * 63726f3cdf0SGordon Ross * RETURN: Status 63826f3cdf0SGordon Ross * 63926f3cdf0SGordon Ross * DESCRIPTION: Saves the pointer to the handler function. The global handler 64026f3cdf0SGordon Ross * is invoked upon each incoming GPE and Fixed Event. It is 64126f3cdf0SGordon Ross * invoked at interrupt level at the time of the event dispatch. 64226f3cdf0SGordon Ross * Can be used to update event counters, etc. 64326f3cdf0SGordon Ross * 64426f3cdf0SGordon Ross ******************************************************************************/ 64526f3cdf0SGordon Ross 64626f3cdf0SGordon Ross ACPI_STATUS 64726f3cdf0SGordon Ross AcpiInstallGlobalEventHandler ( 64826f3cdf0SGordon Ross ACPI_GBL_EVENT_HANDLER Handler, 64926f3cdf0SGordon Ross void *Context) 65026f3cdf0SGordon Ross { 65126f3cdf0SGordon Ross ACPI_STATUS Status; 65226f3cdf0SGordon Ross 65326f3cdf0SGordon Ross 65426f3cdf0SGordon Ross ACPI_FUNCTION_TRACE (AcpiInstallGlobalEventHandler); 65526f3cdf0SGordon Ross 65626f3cdf0SGordon Ross 65726f3cdf0SGordon Ross /* Parameter validation */ 65826f3cdf0SGordon Ross 65926f3cdf0SGordon Ross if (!Handler) 66026f3cdf0SGordon Ross { 66126f3cdf0SGordon Ross return_ACPI_STATUS (AE_BAD_PARAMETER); 66226f3cdf0SGordon Ross } 66326f3cdf0SGordon Ross 66426f3cdf0SGordon Ross Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 66526f3cdf0SGordon Ross if (ACPI_FAILURE (Status)) 66626f3cdf0SGordon Ross { 66726f3cdf0SGordon Ross return_ACPI_STATUS (Status); 66826f3cdf0SGordon Ross } 66926f3cdf0SGordon Ross 67026f3cdf0SGordon Ross /* Don't allow two handlers. */ 67126f3cdf0SGordon Ross 67226f3cdf0SGordon Ross if (AcpiGbl_GlobalEventHandler) 67326f3cdf0SGordon Ross { 67426f3cdf0SGordon Ross Status = AE_ALREADY_EXISTS; 67526f3cdf0SGordon Ross goto Cleanup; 67626f3cdf0SGordon Ross } 67726f3cdf0SGordon Ross 67826f3cdf0SGordon Ross AcpiGbl_GlobalEventHandler = Handler; 67926f3cdf0SGordon Ross AcpiGbl_GlobalEventHandlerContext = Context; 68026f3cdf0SGordon Ross 68126f3cdf0SGordon Ross 68226f3cdf0SGordon Ross Cleanup: 68326f3cdf0SGordon Ross (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 68426f3cdf0SGordon Ross return_ACPI_STATUS (Status); 68526f3cdf0SGordon Ross } 68626f3cdf0SGordon Ross 68726f3cdf0SGordon Ross ACPI_EXPORT_SYMBOL (AcpiInstallGlobalEventHandler) 68826f3cdf0SGordon Ross 68926f3cdf0SGordon Ross 69026f3cdf0SGordon Ross /******************************************************************************* 69126f3cdf0SGordon Ross * 692ae115bc7Smrj * FUNCTION: AcpiInstallFixedEventHandler 693ae115bc7Smrj * 694ae115bc7Smrj * PARAMETERS: Event - Event type to enable. 695ae115bc7Smrj * Handler - Pointer to the handler function for the 696ae115bc7Smrj * event 697ae115bc7Smrj * Context - Value passed to the handler on each GPE 698ae115bc7Smrj * 699ae115bc7Smrj * RETURN: Status 700ae115bc7Smrj * 701ae115bc7Smrj * DESCRIPTION: Saves the pointer to the handler function and then enables the 702ae115bc7Smrj * event. 703ae115bc7Smrj * 704ae115bc7Smrj ******************************************************************************/ 705ae115bc7Smrj 706ae115bc7Smrj ACPI_STATUS 707ae115bc7Smrj AcpiInstallFixedEventHandler ( 708ae115bc7Smrj UINT32 Event, 709ae115bc7Smrj ACPI_EVENT_HANDLER Handler, 710ae115bc7Smrj void *Context) 711ae115bc7Smrj { 712ae115bc7Smrj ACPI_STATUS Status; 713ae115bc7Smrj 714ae115bc7Smrj 715ae115bc7Smrj ACPI_FUNCTION_TRACE (AcpiInstallFixedEventHandler); 716ae115bc7Smrj 717ae115bc7Smrj 718ae115bc7Smrj /* Parameter validation */ 719ae115bc7Smrj 720ae115bc7Smrj if (Event > ACPI_EVENT_MAX) 721ae115bc7Smrj { 722ae115bc7Smrj return_ACPI_STATUS (AE_BAD_PARAMETER); 723ae115bc7Smrj } 724ae115bc7Smrj 725ae115bc7Smrj Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 726ae115bc7Smrj if (ACPI_FAILURE (Status)) 727ae115bc7Smrj { 728ae115bc7Smrj return_ACPI_STATUS (Status); 729ae115bc7Smrj } 730ae115bc7Smrj 731*385cc6b4SJerry Jelinek /* Do not allow multiple handlers */ 732ae115bc7Smrj 733*385cc6b4SJerry Jelinek if (AcpiGbl_FixedEventHandlers[Event].Handler) 734ae115bc7Smrj { 735ae115bc7Smrj Status = AE_ALREADY_EXISTS; 736ae115bc7Smrj goto Cleanup; 737ae115bc7Smrj } 738ae115bc7Smrj 739ae115bc7Smrj /* Install the handler before enabling the event */ 740ae115bc7Smrj 741ae115bc7Smrj AcpiGbl_FixedEventHandlers[Event].Handler = Handler; 742ae115bc7Smrj AcpiGbl_FixedEventHandlers[Event].Context = Context; 743ae115bc7Smrj 744ae115bc7Smrj Status = AcpiEnableEvent (Event, 0); 745ae115bc7Smrj if (ACPI_FAILURE (Status)) 746ae115bc7Smrj { 747*385cc6b4SJerry Jelinek ACPI_WARNING ((AE_INFO, 748*385cc6b4SJerry Jelinek "Could not enable fixed event - %s (%u)", 749*385cc6b4SJerry Jelinek AcpiUtGetEventName (Event), Event)); 750ae115bc7Smrj 751ae115bc7Smrj /* Remove the handler */ 752ae115bc7Smrj 753ae115bc7Smrj AcpiGbl_FixedEventHandlers[Event].Handler = NULL; 754ae115bc7Smrj AcpiGbl_FixedEventHandlers[Event].Context = NULL; 755ae115bc7Smrj } 756ae115bc7Smrj else 757ae115bc7Smrj { 758ae115bc7Smrj ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 759*385cc6b4SJerry Jelinek "Enabled fixed event %s (%X), Handler=%p\n", 760*385cc6b4SJerry Jelinek AcpiUtGetEventName (Event), Event, Handler)); 761ae115bc7Smrj } 762ae115bc7Smrj 763ae115bc7Smrj 764ae115bc7Smrj Cleanup: 765ae115bc7Smrj (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 766ae115bc7Smrj return_ACPI_STATUS (Status); 767ae115bc7Smrj } 768ae115bc7Smrj 769ae115bc7Smrj ACPI_EXPORT_SYMBOL (AcpiInstallFixedEventHandler) 770ae115bc7Smrj 771ae115bc7Smrj 772ae115bc7Smrj /******************************************************************************* 773ae115bc7Smrj * 774ae115bc7Smrj * FUNCTION: AcpiRemoveFixedEventHandler 775ae115bc7Smrj * 776ae115bc7Smrj * PARAMETERS: Event - Event type to disable. 777ae115bc7Smrj * Handler - Address of the handler 778ae115bc7Smrj * 779ae115bc7Smrj * RETURN: Status 780ae115bc7Smrj * 781ae115bc7Smrj * DESCRIPTION: Disables the event and unregisters the event handler. 782ae115bc7Smrj * 783ae115bc7Smrj ******************************************************************************/ 784ae115bc7Smrj 785ae115bc7Smrj ACPI_STATUS 786ae115bc7Smrj AcpiRemoveFixedEventHandler ( 787ae115bc7Smrj UINT32 Event, 788ae115bc7Smrj ACPI_EVENT_HANDLER Handler) 789ae115bc7Smrj { 790ae115bc7Smrj ACPI_STATUS Status = AE_OK; 791ae115bc7Smrj 792ae115bc7Smrj 793ae115bc7Smrj ACPI_FUNCTION_TRACE (AcpiRemoveFixedEventHandler); 794ae115bc7Smrj 795ae115bc7Smrj 796ae115bc7Smrj /* Parameter validation */ 797ae115bc7Smrj 798ae115bc7Smrj if (Event > ACPI_EVENT_MAX) 799ae115bc7Smrj { 800ae115bc7Smrj return_ACPI_STATUS (AE_BAD_PARAMETER); 801ae115bc7Smrj } 802ae115bc7Smrj 803ae115bc7Smrj Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 804ae115bc7Smrj if (ACPI_FAILURE (Status)) 805ae115bc7Smrj { 806ae115bc7Smrj return_ACPI_STATUS (Status); 807ae115bc7Smrj } 808ae115bc7Smrj 809ae115bc7Smrj /* Disable the event before removing the handler */ 810ae115bc7Smrj 811ae115bc7Smrj Status = AcpiDisableEvent (Event, 0); 812ae115bc7Smrj 813ae115bc7Smrj /* Always Remove the handler */ 814ae115bc7Smrj 815ae115bc7Smrj AcpiGbl_FixedEventHandlers[Event].Handler = NULL; 816ae115bc7Smrj AcpiGbl_FixedEventHandlers[Event].Context = NULL; 817ae115bc7Smrj 818ae115bc7Smrj if (ACPI_FAILURE (Status)) 819ae115bc7Smrj { 820ae115bc7Smrj ACPI_WARNING ((AE_INFO, 821*385cc6b4SJerry Jelinek "Could not disable fixed event - %s (%u)", 822*385cc6b4SJerry Jelinek AcpiUtGetEventName (Event), Event)); 823ae115bc7Smrj } 824ae115bc7Smrj else 825ae115bc7Smrj { 826*385cc6b4SJerry Jelinek ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 827*385cc6b4SJerry Jelinek "Disabled fixed event - %s (%X)\n", 828*385cc6b4SJerry Jelinek AcpiUtGetEventName (Event), Event)); 829ae115bc7Smrj } 830ae115bc7Smrj 831ae115bc7Smrj (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 832ae115bc7Smrj return_ACPI_STATUS (Status); 833ae115bc7Smrj } 834ae115bc7Smrj 835ae115bc7Smrj ACPI_EXPORT_SYMBOL (AcpiRemoveFixedEventHandler) 836ae115bc7Smrj 837ae115bc7Smrj 838ae115bc7Smrj /******************************************************************************* 839ae115bc7Smrj * 840*385cc6b4SJerry Jelinek * FUNCTION: AcpiEvInstallGpeHandler 841ae115bc7Smrj * 842ae115bc7Smrj * PARAMETERS: GpeDevice - Namespace node for the GPE (NULL for FADT 843ae115bc7Smrj * defined GPEs) 844ae115bc7Smrj * GpeNumber - The GPE number within the GPE block 845ae115bc7Smrj * Type - Whether this GPE should be treated as an 846ae115bc7Smrj * edge- or level-triggered interrupt. 847*385cc6b4SJerry Jelinek * IsRawHandler - Whether this GPE should be handled using 848*385cc6b4SJerry Jelinek * the special GPE handler mode. 849ae115bc7Smrj * Address - Address of the handler 850ae115bc7Smrj * Context - Value passed to the handler on each GPE 851ae115bc7Smrj * 852ae115bc7Smrj * RETURN: Status 853ae115bc7Smrj * 854*385cc6b4SJerry Jelinek * DESCRIPTION: Internal function to install a handler for a General Purpose 855*385cc6b4SJerry Jelinek * Event. 856ae115bc7Smrj * 857ae115bc7Smrj ******************************************************************************/ 858ae115bc7Smrj 859*385cc6b4SJerry Jelinek static ACPI_STATUS 860*385cc6b4SJerry Jelinek AcpiEvInstallGpeHandler ( 861ae115bc7Smrj ACPI_HANDLE GpeDevice, 862ae115bc7Smrj UINT32 GpeNumber, 863ae115bc7Smrj UINT32 Type, 864*385cc6b4SJerry Jelinek BOOLEAN IsRawHandler, 86526f3cdf0SGordon Ross ACPI_GPE_HANDLER Address, 866ae115bc7Smrj void *Context) 867ae115bc7Smrj { 868ae115bc7Smrj ACPI_GPE_EVENT_INFO *GpeEventInfo; 86926f3cdf0SGordon Ross ACPI_GPE_HANDLER_INFO *Handler; 870ae115bc7Smrj ACPI_STATUS Status; 871ae115bc7Smrj ACPI_CPU_FLAGS Flags; 872ae115bc7Smrj 873ae115bc7Smrj 874*385cc6b4SJerry Jelinek ACPI_FUNCTION_TRACE (EvInstallGpeHandler); 875ae115bc7Smrj 876ae115bc7Smrj 877ae115bc7Smrj /* Parameter validation */ 878ae115bc7Smrj 87926f3cdf0SGordon Ross if ((!Address) || (Type & ~ACPI_GPE_XRUPT_TYPE_MASK)) 880ae115bc7Smrj { 881ae115bc7Smrj return_ACPI_STATUS (AE_BAD_PARAMETER); 882ae115bc7Smrj } 883ae115bc7Smrj 884ae115bc7Smrj Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 885ae115bc7Smrj if (ACPI_FAILURE (Status)) 886ae115bc7Smrj { 887ae115bc7Smrj return_ACPI_STATUS (Status); 888ae115bc7Smrj } 889ae115bc7Smrj 89026f3cdf0SGordon Ross /* Allocate and init handler object (before lock) */ 89126f3cdf0SGordon Ross 89226f3cdf0SGordon Ross Handler = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_GPE_HANDLER_INFO)); 89326f3cdf0SGordon Ross if (!Handler) 89426f3cdf0SGordon Ross { 89526f3cdf0SGordon Ross Status = AE_NO_MEMORY; 89626f3cdf0SGordon Ross goto UnlockAndExit; 89726f3cdf0SGordon Ross } 89826f3cdf0SGordon Ross 89926f3cdf0SGordon Ross Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 90026f3cdf0SGordon Ross 901ae115bc7Smrj /* Ensure that we have a valid GPE number */ 902ae115bc7Smrj 903ae115bc7Smrj GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 904ae115bc7Smrj if (!GpeEventInfo) 905ae115bc7Smrj { 906ae115bc7Smrj Status = AE_BAD_PARAMETER; 90726f3cdf0SGordon Ross goto FreeAndExit; 908ae115bc7Smrj } 909ae115bc7Smrj 910ae115bc7Smrj /* Make sure that there isn't a handler there already */ 911ae115bc7Smrj 912*385cc6b4SJerry Jelinek if ((ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) == 913*385cc6b4SJerry Jelinek ACPI_GPE_DISPATCH_HANDLER) || 914*385cc6b4SJerry Jelinek (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) == 915*385cc6b4SJerry Jelinek ACPI_GPE_DISPATCH_RAW_HANDLER)) 916ae115bc7Smrj { 917ae115bc7Smrj Status = AE_ALREADY_EXISTS; 91826f3cdf0SGordon Ross goto FreeAndExit; 919ae115bc7Smrj } 920ae115bc7Smrj 921ae115bc7Smrj Handler->Address = Address; 922ae115bc7Smrj Handler->Context = Context; 923ae115bc7Smrj Handler->MethodNode = GpeEventInfo->Dispatch.MethodNode; 92426f3cdf0SGordon Ross Handler->OriginalFlags = (UINT8) (GpeEventInfo->Flags & 92526f3cdf0SGordon Ross (ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK)); 926ae115bc7Smrj 92726f3cdf0SGordon Ross /* 92826f3cdf0SGordon Ross * If the GPE is associated with a method, it may have been enabled 92926f3cdf0SGordon Ross * automatically during initialization, in which case it has to be 93026f3cdf0SGordon Ross * disabled now to avoid spurious execution of the handler. 93126f3cdf0SGordon Ross */ 932*385cc6b4SJerry Jelinek if (((ACPI_GPE_DISPATCH_TYPE (Handler->OriginalFlags) == 933*385cc6b4SJerry Jelinek ACPI_GPE_DISPATCH_METHOD) || 934*385cc6b4SJerry Jelinek (ACPI_GPE_DISPATCH_TYPE (Handler->OriginalFlags) == 935*385cc6b4SJerry Jelinek ACPI_GPE_DISPATCH_NOTIFY)) && 93626f3cdf0SGordon Ross GpeEventInfo->RuntimeCount) 937ae115bc7Smrj { 93826f3cdf0SGordon Ross Handler->OriginallyEnabled = TRUE; 93926f3cdf0SGordon Ross (void) AcpiEvRemoveGpeReference (GpeEventInfo); 94026f3cdf0SGordon Ross 94126f3cdf0SGordon Ross /* Sanity check of original type against new type */ 94226f3cdf0SGordon Ross 94326f3cdf0SGordon Ross if (Type != (UINT32) (GpeEventInfo->Flags & ACPI_GPE_XRUPT_TYPE_MASK)) 94426f3cdf0SGordon Ross { 94526f3cdf0SGordon Ross ACPI_WARNING ((AE_INFO, "GPE type mismatch (level/edge)")); 94626f3cdf0SGordon Ross } 947ae115bc7Smrj } 948ae115bc7Smrj 949ae115bc7Smrj /* Install the handler */ 950ae115bc7Smrj 951ae115bc7Smrj GpeEventInfo->Dispatch.Handler = Handler; 952ae115bc7Smrj 95326f3cdf0SGordon Ross /* Setup up dispatch flags to indicate handler (vs. method/notify) */ 954ae115bc7Smrj 955aa2aa9a6SDana Myers GpeEventInfo->Flags &= ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK); 956*385cc6b4SJerry Jelinek GpeEventInfo->Flags |= (UINT8) (Type | (IsRawHandler ? 957*385cc6b4SJerry Jelinek ACPI_GPE_DISPATCH_RAW_HANDLER : ACPI_GPE_DISPATCH_HANDLER)); 958ae115bc7Smrj 959ae115bc7Smrj AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 960ae115bc7Smrj 961ae115bc7Smrj 962ae115bc7Smrj UnlockAndExit: 963ae115bc7Smrj (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 964ae115bc7Smrj return_ACPI_STATUS (Status); 96526f3cdf0SGordon Ross 96626f3cdf0SGordon Ross FreeAndExit: 96726f3cdf0SGordon Ross AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 96826f3cdf0SGordon Ross ACPI_FREE (Handler); 96926f3cdf0SGordon Ross goto UnlockAndExit; 970ae115bc7Smrj } 971ae115bc7Smrj 972*385cc6b4SJerry Jelinek 973*385cc6b4SJerry Jelinek /******************************************************************************* 974*385cc6b4SJerry Jelinek * 975*385cc6b4SJerry Jelinek * FUNCTION: AcpiInstallGpeHandler 976*385cc6b4SJerry Jelinek * 977*385cc6b4SJerry Jelinek * PARAMETERS: GpeDevice - Namespace node for the GPE (NULL for FADT 978*385cc6b4SJerry Jelinek * defined GPEs) 979*385cc6b4SJerry Jelinek * GpeNumber - The GPE number within the GPE block 980*385cc6b4SJerry Jelinek * Type - Whether this GPE should be treated as an 981*385cc6b4SJerry Jelinek * edge- or level-triggered interrupt. 982*385cc6b4SJerry Jelinek * Address - Address of the handler 983*385cc6b4SJerry Jelinek * Context - Value passed to the handler on each GPE 984*385cc6b4SJerry Jelinek * 985*385cc6b4SJerry Jelinek * RETURN: Status 986*385cc6b4SJerry Jelinek * 987*385cc6b4SJerry Jelinek * DESCRIPTION: Install a handler for a General Purpose Event. 988*385cc6b4SJerry Jelinek * 989*385cc6b4SJerry Jelinek ******************************************************************************/ 990*385cc6b4SJerry Jelinek 991*385cc6b4SJerry Jelinek ACPI_STATUS 992*385cc6b4SJerry Jelinek AcpiInstallGpeHandler ( 993*385cc6b4SJerry Jelinek ACPI_HANDLE GpeDevice, 994*385cc6b4SJerry Jelinek UINT32 GpeNumber, 995*385cc6b4SJerry Jelinek UINT32 Type, 996*385cc6b4SJerry Jelinek ACPI_GPE_HANDLER Address, 997*385cc6b4SJerry Jelinek void *Context) 998*385cc6b4SJerry Jelinek { 999*385cc6b4SJerry Jelinek ACPI_STATUS Status; 1000*385cc6b4SJerry Jelinek 1001*385cc6b4SJerry Jelinek 1002*385cc6b4SJerry Jelinek ACPI_FUNCTION_TRACE (AcpiInstallGpeHandler); 1003*385cc6b4SJerry Jelinek 1004*385cc6b4SJerry Jelinek 1005*385cc6b4SJerry Jelinek Status = AcpiEvInstallGpeHandler (GpeDevice, GpeNumber, Type, 1006*385cc6b4SJerry Jelinek FALSE, Address, Context); 1007*385cc6b4SJerry Jelinek 1008*385cc6b4SJerry Jelinek return_ACPI_STATUS (Status); 1009*385cc6b4SJerry Jelinek } 1010*385cc6b4SJerry Jelinek 1011ae115bc7Smrj ACPI_EXPORT_SYMBOL (AcpiInstallGpeHandler) 1012ae115bc7Smrj 1013ae115bc7Smrj 1014ae115bc7Smrj /******************************************************************************* 1015ae115bc7Smrj * 1016*385cc6b4SJerry Jelinek * FUNCTION: AcpiInstallGpeRawHandler 1017*385cc6b4SJerry Jelinek * 1018*385cc6b4SJerry Jelinek * PARAMETERS: GpeDevice - Namespace node for the GPE (NULL for FADT 1019*385cc6b4SJerry Jelinek * defined GPEs) 1020*385cc6b4SJerry Jelinek * GpeNumber - The GPE number within the GPE block 1021*385cc6b4SJerry Jelinek * Type - Whether this GPE should be treated as an 1022*385cc6b4SJerry Jelinek * edge- or level-triggered interrupt. 1023*385cc6b4SJerry Jelinek * Address - Address of the handler 1024*385cc6b4SJerry Jelinek * Context - Value passed to the handler on each GPE 1025*385cc6b4SJerry Jelinek * 1026*385cc6b4SJerry Jelinek * RETURN: Status 1027*385cc6b4SJerry Jelinek * 1028*385cc6b4SJerry Jelinek * DESCRIPTION: Install a handler for a General Purpose Event. 1029*385cc6b4SJerry Jelinek * 1030*385cc6b4SJerry Jelinek ******************************************************************************/ 1031*385cc6b4SJerry Jelinek 1032*385cc6b4SJerry Jelinek ACPI_STATUS 1033*385cc6b4SJerry Jelinek AcpiInstallGpeRawHandler ( 1034*385cc6b4SJerry Jelinek ACPI_HANDLE GpeDevice, 1035*385cc6b4SJerry Jelinek UINT32 GpeNumber, 1036*385cc6b4SJerry Jelinek UINT32 Type, 1037*385cc6b4SJerry Jelinek ACPI_GPE_HANDLER Address, 1038*385cc6b4SJerry Jelinek void *Context) 1039*385cc6b4SJerry Jelinek { 1040*385cc6b4SJerry Jelinek ACPI_STATUS Status; 1041*385cc6b4SJerry Jelinek 1042*385cc6b4SJerry Jelinek 1043*385cc6b4SJerry Jelinek ACPI_FUNCTION_TRACE (AcpiInstallGpeRawHandler); 1044*385cc6b4SJerry Jelinek 1045*385cc6b4SJerry Jelinek 1046*385cc6b4SJerry Jelinek Status = AcpiEvInstallGpeHandler (GpeDevice, GpeNumber, Type, 1047*385cc6b4SJerry Jelinek TRUE, Address, Context); 1048*385cc6b4SJerry Jelinek 1049*385cc6b4SJerry Jelinek return_ACPI_STATUS (Status); 1050*385cc6b4SJerry Jelinek } 1051*385cc6b4SJerry Jelinek 1052*385cc6b4SJerry Jelinek ACPI_EXPORT_SYMBOL (AcpiInstallGpeRawHandler) 1053*385cc6b4SJerry Jelinek 1054*385cc6b4SJerry Jelinek 1055*385cc6b4SJerry Jelinek /******************************************************************************* 1056*385cc6b4SJerry Jelinek * 1057ae115bc7Smrj * FUNCTION: AcpiRemoveGpeHandler 1058ae115bc7Smrj * 1059ae115bc7Smrj * PARAMETERS: GpeDevice - Namespace node for the GPE (NULL for FADT 1060ae115bc7Smrj * defined GPEs) 1061ae115bc7Smrj * GpeNumber - The event to remove a handler 1062ae115bc7Smrj * Address - Address of the handler 1063ae115bc7Smrj * 1064ae115bc7Smrj * RETURN: Status 1065ae115bc7Smrj * 1066ae115bc7Smrj * DESCRIPTION: Remove a handler for a General Purpose AcpiEvent. 1067ae115bc7Smrj * 1068ae115bc7Smrj ******************************************************************************/ 1069ae115bc7Smrj 1070ae115bc7Smrj ACPI_STATUS 1071ae115bc7Smrj AcpiRemoveGpeHandler ( 1072ae115bc7Smrj ACPI_HANDLE GpeDevice, 1073ae115bc7Smrj UINT32 GpeNumber, 107426f3cdf0SGordon Ross ACPI_GPE_HANDLER Address) 1075ae115bc7Smrj { 1076ae115bc7Smrj ACPI_GPE_EVENT_INFO *GpeEventInfo; 107726f3cdf0SGordon Ross ACPI_GPE_HANDLER_INFO *Handler; 1078ae115bc7Smrj ACPI_STATUS Status; 1079ae115bc7Smrj ACPI_CPU_FLAGS Flags; 1080ae115bc7Smrj 1081ae115bc7Smrj 1082ae115bc7Smrj ACPI_FUNCTION_TRACE (AcpiRemoveGpeHandler); 1083ae115bc7Smrj 1084ae115bc7Smrj 1085ae115bc7Smrj /* Parameter validation */ 1086ae115bc7Smrj 1087ae115bc7Smrj if (!Address) 1088ae115bc7Smrj { 1089ae115bc7Smrj return_ACPI_STATUS (AE_BAD_PARAMETER); 1090ae115bc7Smrj } 1091ae115bc7Smrj 1092ae115bc7Smrj Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 1093ae115bc7Smrj if (ACPI_FAILURE (Status)) 1094ae115bc7Smrj { 1095ae115bc7Smrj return_ACPI_STATUS (Status); 1096ae115bc7Smrj } 1097ae115bc7Smrj 109826f3cdf0SGordon Ross Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 109926f3cdf0SGordon Ross 1100ae115bc7Smrj /* Ensure that we have a valid GPE number */ 1101ae115bc7Smrj 1102ae115bc7Smrj GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 1103ae115bc7Smrj if (!GpeEventInfo) 1104ae115bc7Smrj { 1105ae115bc7Smrj Status = AE_BAD_PARAMETER; 1106ae115bc7Smrj goto UnlockAndExit; 1107ae115bc7Smrj } 1108ae115bc7Smrj 1109ae115bc7Smrj /* Make sure that a handler is indeed installed */ 1110ae115bc7Smrj 1111*385cc6b4SJerry Jelinek if ((ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) != 1112*385cc6b4SJerry Jelinek ACPI_GPE_DISPATCH_HANDLER) && 1113*385cc6b4SJerry Jelinek (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) != 1114*385cc6b4SJerry Jelinek ACPI_GPE_DISPATCH_RAW_HANDLER)) 1115ae115bc7Smrj { 1116ae115bc7Smrj Status = AE_NOT_EXIST; 1117ae115bc7Smrj goto UnlockAndExit; 1118ae115bc7Smrj } 1119ae115bc7Smrj 1120ae115bc7Smrj /* Make sure that the installed handler is the same */ 1121ae115bc7Smrj 1122ae115bc7Smrj if (GpeEventInfo->Dispatch.Handler->Address != Address) 1123ae115bc7Smrj { 1124ae115bc7Smrj Status = AE_BAD_PARAMETER; 1125ae115bc7Smrj goto UnlockAndExit; 1126ae115bc7Smrj } 1127ae115bc7Smrj 1128ae115bc7Smrj /* Remove the handler */ 1129ae115bc7Smrj 1130ae115bc7Smrj Handler = GpeEventInfo->Dispatch.Handler; 1131*385cc6b4SJerry Jelinek GpeEventInfo->Dispatch.Handler = NULL; 1132ae115bc7Smrj 1133ae115bc7Smrj /* Restore Method node (if any), set dispatch flags */ 1134ae115bc7Smrj 1135ae115bc7Smrj GpeEventInfo->Dispatch.MethodNode = Handler->MethodNode; 113626f3cdf0SGordon Ross GpeEventInfo->Flags &= 113726f3cdf0SGordon Ross ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK); 113826f3cdf0SGordon Ross GpeEventInfo->Flags |= Handler->OriginalFlags; 113926f3cdf0SGordon Ross 114026f3cdf0SGordon Ross /* 114126f3cdf0SGordon Ross * If the GPE was previously associated with a method and it was 114226f3cdf0SGordon Ross * enabled, it should be enabled at this point to restore the 114326f3cdf0SGordon Ross * post-initialization configuration. 114426f3cdf0SGordon Ross */ 1145*385cc6b4SJerry Jelinek if (((ACPI_GPE_DISPATCH_TYPE (Handler->OriginalFlags) == 1146*385cc6b4SJerry Jelinek ACPI_GPE_DISPATCH_METHOD) || 1147*385cc6b4SJerry Jelinek (ACPI_GPE_DISPATCH_TYPE (Handler->OriginalFlags) == 1148*385cc6b4SJerry Jelinek ACPI_GPE_DISPATCH_NOTIFY)) && 114926f3cdf0SGordon Ross Handler->OriginallyEnabled) 1150ae115bc7Smrj { 115126f3cdf0SGordon Ross (void) AcpiEvAddGpeReference (GpeEventInfo); 1152ae115bc7Smrj } 1153ae115bc7Smrj 1154*385cc6b4SJerry Jelinek AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 1155*385cc6b4SJerry Jelinek (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 1156*385cc6b4SJerry Jelinek 1157*385cc6b4SJerry Jelinek /* Make sure all deferred GPE tasks are completed */ 1158*385cc6b4SJerry Jelinek 1159*385cc6b4SJerry Jelinek AcpiOsWaitEventsComplete (); 1160*385cc6b4SJerry Jelinek 1161ae115bc7Smrj /* Now we can free the handler object */ 1162ae115bc7Smrj 1163ae115bc7Smrj ACPI_FREE (Handler); 1164*385cc6b4SJerry Jelinek return_ACPI_STATUS (Status); 1165ae115bc7Smrj 1166ae115bc7Smrj UnlockAndExit: 116726f3cdf0SGordon Ross AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 1168ae115bc7Smrj (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 1169ae115bc7Smrj return_ACPI_STATUS (Status); 1170ae115bc7Smrj } 1171ae115bc7Smrj 1172ae115bc7Smrj ACPI_EXPORT_SYMBOL (AcpiRemoveGpeHandler) 1173ae115bc7Smrj 1174ae115bc7Smrj 1175ae115bc7Smrj /******************************************************************************* 1176ae115bc7Smrj * 1177ae115bc7Smrj * FUNCTION: AcpiAcquireGlobalLock 1178ae115bc7Smrj * 1179ae115bc7Smrj * PARAMETERS: Timeout - How long the caller is willing to wait 1180ae115bc7Smrj * Handle - Where the handle to the lock is returned 1181ae115bc7Smrj * (if acquired) 1182ae115bc7Smrj * 1183ae115bc7Smrj * RETURN: Status 1184ae115bc7Smrj * 1185ae115bc7Smrj * DESCRIPTION: Acquire the ACPI Global Lock 1186ae115bc7Smrj * 1187db2bae30SDana Myers * Note: Allows callers with the same thread ID to acquire the global lock 1188db2bae30SDana Myers * multiple times. In other words, externally, the behavior of the global lock 1189db2bae30SDana Myers * is identical to an AML mutex. On the first acquire, a new handle is 1190db2bae30SDana Myers * returned. On any subsequent calls to acquire by the same thread, the same 1191db2bae30SDana Myers * handle is returned. 1192db2bae30SDana Myers * 1193ae115bc7Smrj ******************************************************************************/ 1194ae115bc7Smrj 1195ae115bc7Smrj ACPI_STATUS 1196ae115bc7Smrj AcpiAcquireGlobalLock ( 1197ae115bc7Smrj UINT16 Timeout, 1198ae115bc7Smrj UINT32 *Handle) 1199ae115bc7Smrj { 1200ae115bc7Smrj ACPI_STATUS Status; 1201ae115bc7Smrj 1202ae115bc7Smrj 1203ae115bc7Smrj if (!Handle) 1204ae115bc7Smrj { 1205ae115bc7Smrj return (AE_BAD_PARAMETER); 1206ae115bc7Smrj } 1207ae115bc7Smrj 1208db2bae30SDana Myers /* Must lock interpreter to prevent race conditions */ 1209ae115bc7Smrj 1210db2bae30SDana Myers AcpiExEnterInterpreter (); 1211db2bae30SDana Myers 1212db2bae30SDana Myers Status = AcpiExAcquireMutexObject (Timeout, 1213db2bae30SDana Myers AcpiGbl_GlobalLockMutex, AcpiOsGetThreadId ()); 1214ae115bc7Smrj 1215ae115bc7Smrj if (ACPI_SUCCESS (Status)) 1216ae115bc7Smrj { 1217db2bae30SDana Myers /* Return the global lock handle (updated in AcpiEvAcquireGlobalLock) */ 1218db2bae30SDana Myers 1219ae115bc7Smrj *Handle = AcpiGbl_GlobalLockHandle; 1220ae115bc7Smrj } 1221ae115bc7Smrj 1222db2bae30SDana Myers AcpiExExitInterpreter (); 1223ae115bc7Smrj return (Status); 1224ae115bc7Smrj } 1225ae115bc7Smrj 1226ae115bc7Smrj ACPI_EXPORT_SYMBOL (AcpiAcquireGlobalLock) 1227ae115bc7Smrj 1228ae115bc7Smrj 1229ae115bc7Smrj /******************************************************************************* 1230ae115bc7Smrj * 1231ae115bc7Smrj * FUNCTION: AcpiReleaseGlobalLock 1232ae115bc7Smrj * 1233ae115bc7Smrj * PARAMETERS: Handle - Returned from AcpiAcquireGlobalLock 1234ae115bc7Smrj * 1235ae115bc7Smrj * RETURN: Status 1236ae115bc7Smrj * 1237ae115bc7Smrj * DESCRIPTION: Release the ACPI Global Lock. The handle must be valid. 1238ae115bc7Smrj * 1239ae115bc7Smrj ******************************************************************************/ 1240ae115bc7Smrj 1241ae115bc7Smrj ACPI_STATUS 1242ae115bc7Smrj AcpiReleaseGlobalLock ( 1243ae115bc7Smrj UINT32 Handle) 1244ae115bc7Smrj { 1245ae115bc7Smrj ACPI_STATUS Status; 1246ae115bc7Smrj 1247ae115bc7Smrj 1248db2bae30SDana Myers if (!Handle || (Handle != AcpiGbl_GlobalLockHandle)) 1249ae115bc7Smrj { 1250ae115bc7Smrj return (AE_NOT_ACQUIRED); 1251ae115bc7Smrj } 1252ae115bc7Smrj 1253db2bae30SDana Myers Status = AcpiExReleaseMutexObject (AcpiGbl_GlobalLockMutex); 1254ae115bc7Smrj return (Status); 1255ae115bc7Smrj } 1256ae115bc7Smrj 1257ae115bc7Smrj ACPI_EXPORT_SYMBOL (AcpiReleaseGlobalLock) 1258ae115bc7Smrj 1259*385cc6b4SJerry Jelinek #endif /* !ACPI_REDUCED_HARDWARE */ 1260