1 1.1 jruoho /****************************************************************************** 2 1.1 jruoho * 3 1.1 jruoho * Module Name: evxface - External interfaces for ACPI events 4 1.1 jruoho * 5 1.1 jruoho *****************************************************************************/ 6 1.1 jruoho 7 1.17 christos /****************************************************************************** 8 1.17 christos * 9 1.17 christos * 1. Copyright Notice 10 1.17 christos * 11 1.18 christos * Some or all of this work - Copyright (c) 1999 - 2025, Intel Corp. 12 1.1 jruoho * All rights reserved. 13 1.1 jruoho * 14 1.17 christos * 2. License 15 1.17 christos * 16 1.17 christos * 2.1. This is your license from Intel Corp. under its intellectual property 17 1.17 christos * rights. You may have additional license terms from the party that provided 18 1.17 christos * you this software, covering your right to use that party's intellectual 19 1.17 christos * property rights. 20 1.17 christos * 21 1.17 christos * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 22 1.17 christos * copy of the source code appearing in this file ("Covered Code") an 23 1.17 christos * irrevocable, perpetual, worldwide license under Intel's copyrights in the 24 1.17 christos * base code distributed originally by Intel ("Original Intel Code") to copy, 25 1.17 christos * make derivatives, distribute, use and display any portion of the Covered 26 1.17 christos * Code in any form, with the right to sublicense such rights; and 27 1.17 christos * 28 1.17 christos * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 29 1.17 christos * license (with the right to sublicense), under only those claims of Intel 30 1.17 christos * patents that are infringed by the Original Intel Code, to make, use, sell, 31 1.17 christos * offer to sell, and import the Covered Code and derivative works thereof 32 1.17 christos * solely to the minimum extent necessary to exercise the above copyright 33 1.17 christos * license, and in no event shall the patent license extend to any additions 34 1.17 christos * to or modifications of the Original Intel Code. No other license or right 35 1.17 christos * is granted directly or by implication, estoppel or otherwise; 36 1.17 christos * 37 1.17 christos * The above copyright and patent license is granted only if the following 38 1.17 christos * conditions are met: 39 1.17 christos * 40 1.17 christos * 3. Conditions 41 1.17 christos * 42 1.17 christos * 3.1. Redistribution of Source with Rights to Further Distribute Source. 43 1.17 christos * Redistribution of source code of any substantial portion of the Covered 44 1.17 christos * Code or modification with rights to further distribute source must include 45 1.17 christos * the above Copyright Notice, the above License, this list of Conditions, 46 1.17 christos * and the following Disclaimer and Export Compliance provision. In addition, 47 1.17 christos * Licensee must cause all Covered Code to which Licensee contributes to 48 1.17 christos * contain a file documenting the changes Licensee made to create that Covered 49 1.17 christos * Code and the date of any change. Licensee must include in that file the 50 1.17 christos * documentation of any changes made by any predecessor Licensee. Licensee 51 1.17 christos * must include a prominent statement that the modification is derived, 52 1.17 christos * directly or indirectly, from Original Intel Code. 53 1.17 christos * 54 1.17 christos * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 55 1.17 christos * Redistribution of source code of any substantial portion of the Covered 56 1.17 christos * Code or modification without rights to further distribute source must 57 1.17 christos * include the following Disclaimer and Export Compliance provision in the 58 1.17 christos * documentation and/or other materials provided with distribution. In 59 1.17 christos * addition, Licensee may not authorize further sublicense of source of any 60 1.17 christos * portion of the Covered Code, and must include terms to the effect that the 61 1.17 christos * license from Licensee to its licensee is limited to the intellectual 62 1.17 christos * property embodied in the software Licensee provides to its licensee, and 63 1.17 christos * not to intellectual property embodied in modifications its licensee may 64 1.17 christos * make. 65 1.17 christos * 66 1.17 christos * 3.3. Redistribution of Executable. Redistribution in executable form of any 67 1.17 christos * substantial portion of the Covered Code or modification must reproduce the 68 1.17 christos * above Copyright Notice, and the following Disclaimer and Export Compliance 69 1.17 christos * provision in the documentation and/or other materials provided with the 70 1.17 christos * distribution. 71 1.17 christos * 72 1.17 christos * 3.4. Intel retains all right, title, and interest in and to the Original 73 1.17 christos * Intel Code. 74 1.17 christos * 75 1.17 christos * 3.5. Neither the name Intel nor any other trademark owned or controlled by 76 1.17 christos * Intel shall be used in advertising or otherwise to promote the sale, use or 77 1.17 christos * other dealings in products derived from or relating to the Covered Code 78 1.17 christos * without prior written authorization from Intel. 79 1.17 christos * 80 1.17 christos * 4. Disclaimer and Export Compliance 81 1.17 christos * 82 1.17 christos * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 83 1.17 christos * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 84 1.17 christos * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 85 1.17 christos * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 86 1.17 christos * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 87 1.17 christos * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 88 1.17 christos * PARTICULAR PURPOSE. 89 1.17 christos * 90 1.17 christos * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 91 1.17 christos * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 92 1.17 christos * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 93 1.17 christos * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 94 1.17 christos * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 95 1.17 christos * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 96 1.17 christos * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 97 1.17 christos * LIMITED REMEDY. 98 1.17 christos * 99 1.17 christos * 4.3. Licensee shall not export, either directly or indirectly, any of this 100 1.17 christos * software or system incorporating such software without first obtaining any 101 1.17 christos * required license or other approval from the U. S. Department of Commerce or 102 1.17 christos * any other agency or department of the United States Government. In the 103 1.17 christos * event Licensee exports any such software from the United States or 104 1.17 christos * re-exports any such software from a foreign destination, Licensee shall 105 1.17 christos * ensure that the distribution and export/re-export of the software is in 106 1.17 christos * compliance with all laws, regulations, orders, or other restrictions of the 107 1.17 christos * U.S. Export Administration Regulations. Licensee agrees that neither it nor 108 1.17 christos * any of its subsidiaries will export/re-export any technical data, process, 109 1.17 christos * software, or service, directly or indirectly, to any country for which the 110 1.17 christos * United States government or any agency thereof requires an export license, 111 1.17 christos * other governmental approval, or letter of assurance, without first obtaining 112 1.17 christos * such license, approval or letter. 113 1.17 christos * 114 1.17 christos ***************************************************************************** 115 1.17 christos * 116 1.17 christos * Alternatively, you may choose to be licensed under the terms of the 117 1.17 christos * following license: 118 1.17 christos * 119 1.4 jruoho * Redistribution and use in source and binary forms, with or without 120 1.4 jruoho * modification, are permitted provided that the following conditions 121 1.4 jruoho * are met: 122 1.4 jruoho * 1. Redistributions of source code must retain the above copyright 123 1.4 jruoho * notice, this list of conditions, and the following disclaimer, 124 1.4 jruoho * without modification. 125 1.4 jruoho * 2. Redistributions in binary form must reproduce at minimum a disclaimer 126 1.4 jruoho * substantially similar to the "NO WARRANTY" disclaimer below 127 1.4 jruoho * ("Disclaimer") and any redistribution must be conditioned upon 128 1.4 jruoho * including a substantially similar Disclaimer requirement for further 129 1.4 jruoho * binary redistribution. 130 1.4 jruoho * 3. Neither the names of the above-listed copyright holders nor the names 131 1.4 jruoho * of any contributors may be used to endorse or promote products derived 132 1.4 jruoho * from this software without specific prior written permission. 133 1.4 jruoho * 134 1.4 jruoho * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 135 1.4 jruoho * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 136 1.14 christos * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 137 1.4 jruoho * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 138 1.17 christos * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 139 1.17 christos * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 140 1.17 christos * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 141 1.17 christos * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 142 1.17 christos * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 143 1.17 christos * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 144 1.17 christos * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 145 1.17 christos * 146 1.17 christos * Alternatively, you may choose to be licensed under the terms of the 147 1.17 christos * GNU General Public License ("GPL") version 2 as published by the Free 148 1.17 christos * Software Foundation. 149 1.17 christos * 150 1.17 christos *****************************************************************************/ 151 1.1 jruoho 152 1.5 christos #define EXPORT_ACPI_INTERFACES 153 1.1 jruoho 154 1.1 jruoho #include "acpi.h" 155 1.1 jruoho #include "accommon.h" 156 1.1 jruoho #include "acnamesp.h" 157 1.1 jruoho #include "acevents.h" 158 1.1 jruoho #include "acinterp.h" 159 1.1 jruoho 160 1.1 jruoho #define _COMPONENT ACPI_EVENTS 161 1.1 jruoho ACPI_MODULE_NAME ("evxface") 162 1.1 jruoho 163 1.7 christos #if (!ACPI_REDUCED_HARDWARE) 164 1.7 christos 165 1.7 christos /* Local prototypes */ 166 1.7 christos 167 1.7 christos static ACPI_STATUS 168 1.7 christos AcpiEvInstallGpeHandler ( 169 1.7 christos ACPI_HANDLE GpeDevice, 170 1.7 christos UINT32 GpeNumber, 171 1.7 christos UINT32 Type, 172 1.7 christos BOOLEAN IsRawHandler, 173 1.7 christos ACPI_GPE_HANDLER Address, 174 1.7 christos void *Context); 175 1.7 christos 176 1.7 christos #endif 177 1.7 christos 178 1.1 jruoho 179 1.1 jruoho /******************************************************************************* 180 1.1 jruoho * 181 1.5 christos * FUNCTION: AcpiInstallNotifyHandler 182 1.5 christos * 183 1.5 christos * PARAMETERS: Device - The device for which notifies will be handled 184 1.5 christos * HandlerType - The type of handler: 185 1.5 christos * ACPI_SYSTEM_NOTIFY: System Handler (00-7F) 186 1.5 christos * ACPI_DEVICE_NOTIFY: Device Handler (80-FF) 187 1.5 christos * ACPI_ALL_NOTIFY: Both System and Device 188 1.5 christos * Handler - Address of the handler 189 1.5 christos * Context - Value passed to the handler on each GPE 190 1.5 christos * 191 1.5 christos * RETURN: Status 192 1.5 christos * 193 1.5 christos * DESCRIPTION: Install a handler for notifications on an ACPI Device, 194 1.5 christos * ThermalZone, or Processor object. 195 1.5 christos * 196 1.5 christos * NOTES: The Root namespace object may have only one handler for each 197 1.5 christos * type of notify (System/Device). Device/Thermal/Processor objects 198 1.5 christos * may have one device notify handler, and multiple system notify 199 1.5 christos * handlers. 200 1.5 christos * 201 1.5 christos ******************************************************************************/ 202 1.5 christos 203 1.5 christos ACPI_STATUS 204 1.5 christos AcpiInstallNotifyHandler ( 205 1.5 christos ACPI_HANDLE Device, 206 1.5 christos UINT32 HandlerType, 207 1.5 christos ACPI_NOTIFY_HANDLER Handler, 208 1.5 christos void *Context) 209 1.5 christos { 210 1.5 christos ACPI_NAMESPACE_NODE *Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Device); 211 1.5 christos ACPI_OPERAND_OBJECT *ObjDesc; 212 1.5 christos ACPI_OPERAND_OBJECT *HandlerObj; 213 1.5 christos ACPI_STATUS Status; 214 1.5 christos UINT32 i; 215 1.5 christos 216 1.5 christos 217 1.5 christos ACPI_FUNCTION_TRACE (AcpiInstallNotifyHandler); 218 1.5 christos 219 1.5 christos 220 1.5 christos /* Parameter validation */ 221 1.5 christos 222 1.5 christos if ((!Device) || (!Handler) || (!HandlerType) || 223 1.5 christos (HandlerType > ACPI_MAX_NOTIFY_HANDLER_TYPE)) 224 1.5 christos { 225 1.5 christos return_ACPI_STATUS (AE_BAD_PARAMETER); 226 1.5 christos } 227 1.5 christos 228 1.5 christos Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 229 1.5 christos if (ACPI_FAILURE (Status)) 230 1.5 christos { 231 1.5 christos return_ACPI_STATUS (Status); 232 1.5 christos } 233 1.5 christos 234 1.5 christos /* 235 1.5 christos * Root Object: 236 1.5 christos * Registering a notify handler on the root object indicates that the 237 1.5 christos * caller wishes to receive notifications for all objects. Note that 238 1.5 christos * only one global handler can be registered per notify type. 239 1.5 christos * Ensure that a handler is not already installed. 240 1.5 christos */ 241 1.5 christos if (Device == ACPI_ROOT_OBJECT) 242 1.5 christos { 243 1.5 christos for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++) 244 1.5 christos { 245 1.5 christos if (HandlerType & (i+1)) 246 1.5 christos { 247 1.5 christos if (AcpiGbl_GlobalNotify[i].Handler) 248 1.5 christos { 249 1.5 christos Status = AE_ALREADY_EXISTS; 250 1.5 christos goto UnlockAndExit; 251 1.5 christos } 252 1.5 christos 253 1.5 christos AcpiGbl_GlobalNotify[i].Handler = Handler; 254 1.5 christos AcpiGbl_GlobalNotify[i].Context = Context; 255 1.5 christos } 256 1.5 christos } 257 1.5 christos 258 1.5 christos goto UnlockAndExit; /* Global notify handler installed, all done */ 259 1.5 christos } 260 1.5 christos 261 1.5 christos /* 262 1.5 christos * All Other Objects: 263 1.5 christos * Caller will only receive notifications specific to the target 264 1.5 christos * object. Note that only certain object types are allowed to 265 1.5 christos * receive notifications. 266 1.5 christos */ 267 1.5 christos 268 1.5 christos /* Are Notifies allowed on this object? */ 269 1.5 christos 270 1.5 christos if (!AcpiEvIsNotifyObject (Node)) 271 1.5 christos { 272 1.5 christos Status = AE_TYPE; 273 1.5 christos goto UnlockAndExit; 274 1.5 christos } 275 1.5 christos 276 1.5 christos /* Check for an existing internal object, might not exist */ 277 1.5 christos 278 1.5 christos ObjDesc = AcpiNsGetAttachedObject (Node); 279 1.5 christos if (!ObjDesc) 280 1.5 christos { 281 1.5 christos /* Create a new object */ 282 1.5 christos 283 1.5 christos ObjDesc = AcpiUtCreateInternalObject (Node->Type); 284 1.5 christos if (!ObjDesc) 285 1.5 christos { 286 1.5 christos Status = AE_NO_MEMORY; 287 1.5 christos goto UnlockAndExit; 288 1.5 christos } 289 1.5 christos 290 1.5 christos /* Attach new object to the Node, remove local reference */ 291 1.5 christos 292 1.5 christos Status = AcpiNsAttachObject (Device, ObjDesc, Node->Type); 293 1.5 christos AcpiUtRemoveReference (ObjDesc); 294 1.5 christos if (ACPI_FAILURE (Status)) 295 1.5 christos { 296 1.5 christos goto UnlockAndExit; 297 1.5 christos } 298 1.5 christos } 299 1.5 christos 300 1.5 christos /* Ensure that the handler is not already installed in the lists */ 301 1.5 christos 302 1.5 christos for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++) 303 1.5 christos { 304 1.5 christos if (HandlerType & (i+1)) 305 1.5 christos { 306 1.5 christos HandlerObj = ObjDesc->CommonNotify.NotifyList[i]; 307 1.5 christos while (HandlerObj) 308 1.5 christos { 309 1.5 christos if (HandlerObj->Notify.Handler == Handler) 310 1.5 christos { 311 1.5 christos Status = AE_ALREADY_EXISTS; 312 1.5 christos goto UnlockAndExit; 313 1.5 christos } 314 1.5 christos 315 1.5 christos HandlerObj = HandlerObj->Notify.Next[i]; 316 1.5 christos } 317 1.5 christos } 318 1.5 christos } 319 1.5 christos 320 1.5 christos /* Create and populate a new notify handler object */ 321 1.5 christos 322 1.5 christos HandlerObj = AcpiUtCreateInternalObject (ACPI_TYPE_LOCAL_NOTIFY); 323 1.5 christos if (!HandlerObj) 324 1.5 christos { 325 1.5 christos Status = AE_NO_MEMORY; 326 1.5 christos goto UnlockAndExit; 327 1.5 christos } 328 1.5 christos 329 1.5 christos HandlerObj->Notify.Node = Node; 330 1.5 christos HandlerObj->Notify.HandlerType = HandlerType; 331 1.5 christos HandlerObj->Notify.Handler = Handler; 332 1.5 christos HandlerObj->Notify.Context = Context; 333 1.5 christos 334 1.5 christos /* Install the handler at the list head(s) */ 335 1.5 christos 336 1.5 christos for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++) 337 1.5 christos { 338 1.5 christos if (HandlerType & (i+1)) 339 1.5 christos { 340 1.5 christos HandlerObj->Notify.Next[i] = 341 1.5 christos ObjDesc->CommonNotify.NotifyList[i]; 342 1.5 christos 343 1.5 christos ObjDesc->CommonNotify.NotifyList[i] = HandlerObj; 344 1.5 christos } 345 1.5 christos } 346 1.5 christos 347 1.5 christos /* Add an extra reference if handler was installed in both lists */ 348 1.5 christos 349 1.5 christos if (HandlerType == ACPI_ALL_NOTIFY) 350 1.5 christos { 351 1.5 christos AcpiUtAddReference (HandlerObj); 352 1.5 christos } 353 1.5 christos 354 1.5 christos 355 1.5 christos UnlockAndExit: 356 1.5 christos (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 357 1.5 christos return_ACPI_STATUS (Status); 358 1.5 christos } 359 1.5 christos 360 1.5 christos ACPI_EXPORT_SYMBOL (AcpiInstallNotifyHandler) 361 1.5 christos 362 1.5 christos 363 1.5 christos /******************************************************************************* 364 1.5 christos * 365 1.5 christos * FUNCTION: AcpiRemoveNotifyHandler 366 1.5 christos * 367 1.5 christos * PARAMETERS: Device - The device for which the handler is installed 368 1.5 christos * HandlerType - The type of handler: 369 1.5 christos * ACPI_SYSTEM_NOTIFY: System Handler (00-7F) 370 1.5 christos * ACPI_DEVICE_NOTIFY: Device Handler (80-FF) 371 1.5 christos * ACPI_ALL_NOTIFY: Both System and Device 372 1.5 christos * Handler - Address of the handler 373 1.5 christos * 374 1.5 christos * RETURN: Status 375 1.5 christos * 376 1.5 christos * DESCRIPTION: Remove a handler for notifies on an ACPI device 377 1.5 christos * 378 1.5 christos ******************************************************************************/ 379 1.5 christos 380 1.5 christos ACPI_STATUS 381 1.5 christos AcpiRemoveNotifyHandler ( 382 1.5 christos ACPI_HANDLE Device, 383 1.5 christos UINT32 HandlerType, 384 1.5 christos ACPI_NOTIFY_HANDLER Handler) 385 1.5 christos { 386 1.5 christos ACPI_NAMESPACE_NODE *Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Device); 387 1.5 christos ACPI_OPERAND_OBJECT *ObjDesc; 388 1.5 christos ACPI_OPERAND_OBJECT *HandlerObj; 389 1.5 christos ACPI_OPERAND_OBJECT *PreviousHandlerObj; 390 1.6 christos ACPI_STATUS Status = AE_OK; 391 1.5 christos UINT32 i; 392 1.5 christos 393 1.5 christos 394 1.5 christos ACPI_FUNCTION_TRACE (AcpiRemoveNotifyHandler); 395 1.5 christos 396 1.5 christos 397 1.5 christos /* Parameter validation */ 398 1.5 christos 399 1.5 christos if ((!Device) || (!Handler) || (!HandlerType) || 400 1.5 christos (HandlerType > ACPI_MAX_NOTIFY_HANDLER_TYPE)) 401 1.5 christos { 402 1.5 christos return_ACPI_STATUS (AE_BAD_PARAMETER); 403 1.5 christos } 404 1.5 christos 405 1.5 christos /* Root Object. Global handlers are removed here */ 406 1.5 christos 407 1.5 christos if (Device == ACPI_ROOT_OBJECT) 408 1.5 christos { 409 1.5 christos for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++) 410 1.5 christos { 411 1.5 christos if (HandlerType & (i+1)) 412 1.5 christos { 413 1.6 christos Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 414 1.6 christos if (ACPI_FAILURE (Status)) 415 1.6 christos { 416 1.6 christos return_ACPI_STATUS (Status); 417 1.6 christos } 418 1.6 christos 419 1.5 christos if (!AcpiGbl_GlobalNotify[i].Handler || 420 1.5 christos (AcpiGbl_GlobalNotify[i].Handler != Handler)) 421 1.5 christos { 422 1.5 christos Status = AE_NOT_EXIST; 423 1.5 christos goto UnlockAndExit; 424 1.5 christos } 425 1.5 christos 426 1.5 christos ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 427 1.5 christos "Removing global notify handler\n")); 428 1.5 christos 429 1.5 christos AcpiGbl_GlobalNotify[i].Handler = NULL; 430 1.5 christos AcpiGbl_GlobalNotify[i].Context = NULL; 431 1.6 christos 432 1.6 christos (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 433 1.6 christos 434 1.6 christos /* Make sure all deferred notify tasks are completed */ 435 1.6 christos 436 1.6 christos AcpiOsWaitEventsComplete (); 437 1.5 christos } 438 1.5 christos } 439 1.5 christos 440 1.6 christos return_ACPI_STATUS (AE_OK); 441 1.5 christos } 442 1.5 christos 443 1.5 christos /* All other objects: Are Notifies allowed on this object? */ 444 1.5 christos 445 1.5 christos if (!AcpiEvIsNotifyObject (Node)) 446 1.5 christos { 447 1.6 christos return_ACPI_STATUS (AE_TYPE); 448 1.5 christos } 449 1.5 christos 450 1.5 christos /* Must have an existing internal object */ 451 1.5 christos 452 1.5 christos ObjDesc = AcpiNsGetAttachedObject (Node); 453 1.5 christos if (!ObjDesc) 454 1.5 christos { 455 1.6 christos return_ACPI_STATUS (AE_NOT_EXIST); 456 1.5 christos } 457 1.5 christos 458 1.5 christos /* Internal object exists. Find the handler and remove it */ 459 1.5 christos 460 1.5 christos for (i = 0; i < ACPI_NUM_NOTIFY_TYPES; i++) 461 1.5 christos { 462 1.5 christos if (HandlerType & (i+1)) 463 1.5 christos { 464 1.6 christos Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 465 1.6 christos if (ACPI_FAILURE (Status)) 466 1.6 christos { 467 1.6 christos return_ACPI_STATUS (Status); 468 1.6 christos } 469 1.6 christos 470 1.5 christos HandlerObj = ObjDesc->CommonNotify.NotifyList[i]; 471 1.5 christos PreviousHandlerObj = NULL; 472 1.5 christos 473 1.5 christos /* Attempt to find the handler in the handler list */ 474 1.5 christos 475 1.5 christos while (HandlerObj && 476 1.5 christos (HandlerObj->Notify.Handler != Handler)) 477 1.5 christos { 478 1.5 christos PreviousHandlerObj = HandlerObj; 479 1.5 christos HandlerObj = HandlerObj->Notify.Next[i]; 480 1.5 christos } 481 1.5 christos 482 1.5 christos if (!HandlerObj) 483 1.5 christos { 484 1.5 christos Status = AE_NOT_EXIST; 485 1.5 christos goto UnlockAndExit; 486 1.5 christos } 487 1.5 christos 488 1.5 christos /* Remove the handler object from the list */ 489 1.5 christos 490 1.5 christos if (PreviousHandlerObj) /* Handler is not at the list head */ 491 1.5 christos { 492 1.5 christos PreviousHandlerObj->Notify.Next[i] = 493 1.5 christos HandlerObj->Notify.Next[i]; 494 1.5 christos } 495 1.5 christos else /* Handler is at the list head */ 496 1.5 christos { 497 1.5 christos ObjDesc->CommonNotify.NotifyList[i] = 498 1.5 christos HandlerObj->Notify.Next[i]; 499 1.5 christos } 500 1.5 christos 501 1.6 christos (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 502 1.6 christos 503 1.6 christos /* Make sure all deferred notify tasks are completed */ 504 1.6 christos 505 1.6 christos AcpiOsWaitEventsComplete (); 506 1.5 christos AcpiUtRemoveReference (HandlerObj); 507 1.5 christos } 508 1.5 christos } 509 1.5 christos 510 1.6 christos return_ACPI_STATUS (Status); 511 1.6 christos 512 1.5 christos 513 1.5 christos UnlockAndExit: 514 1.5 christos (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 515 1.5 christos return_ACPI_STATUS (Status); 516 1.5 christos } 517 1.5 christos 518 1.5 christos ACPI_EXPORT_SYMBOL (AcpiRemoveNotifyHandler) 519 1.5 christos 520 1.5 christos 521 1.5 christos /******************************************************************************* 522 1.5 christos * 523 1.1 jruoho * FUNCTION: AcpiInstallExceptionHandler 524 1.1 jruoho * 525 1.1 jruoho * PARAMETERS: Handler - Pointer to the handler function for the 526 1.1 jruoho * event 527 1.1 jruoho * 528 1.1 jruoho * RETURN: Status 529 1.1 jruoho * 530 1.1 jruoho * DESCRIPTION: Saves the pointer to the handler function 531 1.1 jruoho * 532 1.1 jruoho ******************************************************************************/ 533 1.1 jruoho 534 1.1 jruoho ACPI_STATUS 535 1.1 jruoho AcpiInstallExceptionHandler ( 536 1.1 jruoho ACPI_EXCEPTION_HANDLER Handler) 537 1.1 jruoho { 538 1.1 jruoho ACPI_STATUS Status; 539 1.1 jruoho 540 1.1 jruoho 541 1.1 jruoho ACPI_FUNCTION_TRACE (AcpiInstallExceptionHandler); 542 1.1 jruoho 543 1.1 jruoho 544 1.1 jruoho Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 545 1.1 jruoho if (ACPI_FAILURE (Status)) 546 1.1 jruoho { 547 1.1 jruoho return_ACPI_STATUS (Status); 548 1.1 jruoho } 549 1.1 jruoho 550 1.5 christos /* Don't allow two handlers. */ 551 1.5 christos 552 1.5 christos if (AcpiGbl_ExceptionHandler) 553 1.5 christos { 554 1.5 christos Status = AE_ALREADY_EXISTS; 555 1.5 christos goto Cleanup; 556 1.5 christos } 557 1.5 christos 558 1.5 christos /* Install the handler */ 559 1.5 christos 560 1.5 christos AcpiGbl_ExceptionHandler = Handler; 561 1.5 christos 562 1.5 christos Cleanup: 563 1.5 christos (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 564 1.5 christos return_ACPI_STATUS (Status); 565 1.5 christos } 566 1.5 christos 567 1.5 christos ACPI_EXPORT_SYMBOL (AcpiInstallExceptionHandler) 568 1.5 christos 569 1.5 christos 570 1.5 christos #if (!ACPI_REDUCED_HARDWARE) 571 1.5 christos /******************************************************************************* 572 1.5 christos * 573 1.5 christos * FUNCTION: AcpiInstallSciHandler 574 1.5 christos * 575 1.5 christos * PARAMETERS: Address - Address of the handler 576 1.5 christos * Context - Value passed to the handler on each SCI 577 1.5 christos * 578 1.5 christos * RETURN: Status 579 1.5 christos * 580 1.5 christos * DESCRIPTION: Install a handler for a System Control Interrupt. 581 1.5 christos * 582 1.5 christos ******************************************************************************/ 583 1.5 christos 584 1.5 christos ACPI_STATUS 585 1.5 christos AcpiInstallSciHandler ( 586 1.5 christos ACPI_SCI_HANDLER Address, 587 1.5 christos void *Context) 588 1.5 christos { 589 1.5 christos ACPI_SCI_HANDLER_INFO *NewSciHandler; 590 1.5 christos ACPI_SCI_HANDLER_INFO *SciHandler; 591 1.5 christos ACPI_CPU_FLAGS Flags; 592 1.5 christos ACPI_STATUS Status; 593 1.5 christos 594 1.5 christos 595 1.5 christos ACPI_FUNCTION_TRACE (AcpiInstallSciHandler); 596 1.5 christos 597 1.5 christos 598 1.5 christos if (!Address) 599 1.5 christos { 600 1.5 christos return_ACPI_STATUS (AE_BAD_PARAMETER); 601 1.5 christos } 602 1.5 christos 603 1.5 christos /* Allocate and init a handler object */ 604 1.5 christos 605 1.5 christos NewSciHandler = ACPI_ALLOCATE (sizeof (ACPI_SCI_HANDLER_INFO)); 606 1.5 christos if (!NewSciHandler) 607 1.5 christos { 608 1.5 christos return_ACPI_STATUS (AE_NO_MEMORY); 609 1.5 christos } 610 1.5 christos 611 1.5 christos NewSciHandler->Address = Address; 612 1.5 christos NewSciHandler->Context = Context; 613 1.5 christos 614 1.5 christos Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 615 1.5 christos if (ACPI_FAILURE (Status)) 616 1.5 christos { 617 1.5 christos goto Exit; 618 1.5 christos } 619 1.5 christos 620 1.5 christos /* Lock list during installation */ 621 1.5 christos 622 1.5 christos Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 623 1.5 christos SciHandler = AcpiGbl_SciHandlerList; 624 1.5 christos 625 1.5 christos /* Ensure handler does not already exist */ 626 1.5 christos 627 1.5 christos while (SciHandler) 628 1.5 christos { 629 1.5 christos if (Address == SciHandler->Address) 630 1.5 christos { 631 1.5 christos Status = AE_ALREADY_EXISTS; 632 1.5 christos goto UnlockAndExit; 633 1.5 christos } 634 1.5 christos 635 1.5 christos SciHandler = SciHandler->Next; 636 1.5 christos } 637 1.5 christos 638 1.5 christos /* Install the new handler into the global list (at head) */ 639 1.5 christos 640 1.5 christos NewSciHandler->Next = AcpiGbl_SciHandlerList; 641 1.5 christos AcpiGbl_SciHandlerList = NewSciHandler; 642 1.5 christos 643 1.5 christos 644 1.5 christos UnlockAndExit: 645 1.5 christos 646 1.5 christos AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 647 1.5 christos (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 648 1.5 christos 649 1.5 christos Exit: 650 1.5 christos if (ACPI_FAILURE (Status)) 651 1.5 christos { 652 1.5 christos ACPI_FREE (NewSciHandler); 653 1.5 christos } 654 1.5 christos return_ACPI_STATUS (Status); 655 1.5 christos } 656 1.5 christos 657 1.6 christos ACPI_EXPORT_SYMBOL (AcpiInstallSciHandler) 658 1.6 christos 659 1.5 christos 660 1.5 christos /******************************************************************************* 661 1.5 christos * 662 1.5 christos * FUNCTION: AcpiRemoveSciHandler 663 1.5 christos * 664 1.5 christos * PARAMETERS: Address - Address of the handler 665 1.5 christos * 666 1.5 christos * RETURN: Status 667 1.5 christos * 668 1.5 christos * DESCRIPTION: Remove a handler for a System Control Interrupt. 669 1.5 christos * 670 1.5 christos ******************************************************************************/ 671 1.5 christos 672 1.5 christos ACPI_STATUS 673 1.5 christos AcpiRemoveSciHandler ( 674 1.5 christos ACPI_SCI_HANDLER Address) 675 1.5 christos { 676 1.5 christos ACPI_SCI_HANDLER_INFO *PrevSciHandler; 677 1.5 christos ACPI_SCI_HANDLER_INFO *NextSciHandler; 678 1.5 christos ACPI_CPU_FLAGS Flags; 679 1.5 christos ACPI_STATUS Status; 680 1.5 christos 681 1.5 christos 682 1.5 christos ACPI_FUNCTION_TRACE (AcpiRemoveSciHandler); 683 1.5 christos 684 1.5 christos 685 1.5 christos if (!Address) 686 1.5 christos { 687 1.5 christos return_ACPI_STATUS (AE_BAD_PARAMETER); 688 1.5 christos } 689 1.5 christos 690 1.5 christos Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 691 1.5 christos if (ACPI_FAILURE (Status)) 692 1.5 christos { 693 1.5 christos return_ACPI_STATUS (Status); 694 1.5 christos } 695 1.5 christos 696 1.5 christos /* Remove the SCI handler with lock */ 697 1.5 christos 698 1.5 christos Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 699 1.5 christos 700 1.5 christos PrevSciHandler = NULL; 701 1.5 christos NextSciHandler = AcpiGbl_SciHandlerList; 702 1.5 christos while (NextSciHandler) 703 1.5 christos { 704 1.5 christos if (NextSciHandler->Address == Address) 705 1.5 christos { 706 1.5 christos /* Unlink and free the SCI handler info block */ 707 1.5 christos 708 1.5 christos if (PrevSciHandler) 709 1.5 christos { 710 1.5 christos PrevSciHandler->Next = NextSciHandler->Next; 711 1.5 christos } 712 1.5 christos else 713 1.5 christos { 714 1.5 christos AcpiGbl_SciHandlerList = NextSciHandler->Next; 715 1.5 christos } 716 1.5 christos 717 1.5 christos AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 718 1.5 christos ACPI_FREE (NextSciHandler); 719 1.5 christos goto UnlockAndExit; 720 1.5 christos } 721 1.1 jruoho 722 1.5 christos PrevSciHandler = NextSciHandler; 723 1.5 christos NextSciHandler = NextSciHandler->Next; 724 1.1 jruoho } 725 1.1 jruoho 726 1.5 christos AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 727 1.5 christos Status = AE_NOT_EXIST; 728 1.1 jruoho 729 1.1 jruoho 730 1.5 christos UnlockAndExit: 731 1.1 jruoho (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 732 1.1 jruoho return_ACPI_STATUS (Status); 733 1.1 jruoho } 734 1.1 jruoho 735 1.6 christos ACPI_EXPORT_SYMBOL (AcpiRemoveSciHandler) 736 1.6 christos 737 1.1 jruoho 738 1.1 jruoho /******************************************************************************* 739 1.1 jruoho * 740 1.4 jruoho * FUNCTION: AcpiInstallGlobalEventHandler 741 1.4 jruoho * 742 1.4 jruoho * PARAMETERS: Handler - Pointer to the global event handler function 743 1.4 jruoho * Context - Value passed to the handler on each event 744 1.4 jruoho * 745 1.4 jruoho * RETURN: Status 746 1.4 jruoho * 747 1.4 jruoho * DESCRIPTION: Saves the pointer to the handler function. The global handler 748 1.4 jruoho * is invoked upon each incoming GPE and Fixed Event. It is 749 1.4 jruoho * invoked at interrupt level at the time of the event dispatch. 750 1.4 jruoho * Can be used to update event counters, etc. 751 1.4 jruoho * 752 1.4 jruoho ******************************************************************************/ 753 1.4 jruoho 754 1.4 jruoho ACPI_STATUS 755 1.4 jruoho AcpiInstallGlobalEventHandler ( 756 1.4 jruoho ACPI_GBL_EVENT_HANDLER Handler, 757 1.4 jruoho void *Context) 758 1.4 jruoho { 759 1.4 jruoho ACPI_STATUS Status; 760 1.4 jruoho 761 1.4 jruoho 762 1.4 jruoho ACPI_FUNCTION_TRACE (AcpiInstallGlobalEventHandler); 763 1.4 jruoho 764 1.4 jruoho 765 1.4 jruoho /* Parameter validation */ 766 1.4 jruoho 767 1.4 jruoho if (!Handler) 768 1.4 jruoho { 769 1.4 jruoho return_ACPI_STATUS (AE_BAD_PARAMETER); 770 1.4 jruoho } 771 1.4 jruoho 772 1.4 jruoho Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 773 1.4 jruoho if (ACPI_FAILURE (Status)) 774 1.4 jruoho { 775 1.4 jruoho return_ACPI_STATUS (Status); 776 1.4 jruoho } 777 1.4 jruoho 778 1.4 jruoho /* Don't allow two handlers. */ 779 1.4 jruoho 780 1.4 jruoho if (AcpiGbl_GlobalEventHandler) 781 1.4 jruoho { 782 1.4 jruoho Status = AE_ALREADY_EXISTS; 783 1.4 jruoho goto Cleanup; 784 1.4 jruoho } 785 1.4 jruoho 786 1.4 jruoho AcpiGbl_GlobalEventHandler = Handler; 787 1.4 jruoho AcpiGbl_GlobalEventHandlerContext = Context; 788 1.4 jruoho 789 1.4 jruoho 790 1.4 jruoho Cleanup: 791 1.4 jruoho (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 792 1.4 jruoho return_ACPI_STATUS (Status); 793 1.4 jruoho } 794 1.4 jruoho 795 1.4 jruoho ACPI_EXPORT_SYMBOL (AcpiInstallGlobalEventHandler) 796 1.4 jruoho 797 1.4 jruoho 798 1.4 jruoho /******************************************************************************* 799 1.4 jruoho * 800 1.1 jruoho * FUNCTION: AcpiInstallFixedEventHandler 801 1.1 jruoho * 802 1.1 jruoho * PARAMETERS: Event - Event type to enable. 803 1.1 jruoho * Handler - Pointer to the handler function for the 804 1.1 jruoho * event 805 1.1 jruoho * Context - Value passed to the handler on each GPE 806 1.1 jruoho * 807 1.1 jruoho * RETURN: Status 808 1.1 jruoho * 809 1.1 jruoho * DESCRIPTION: Saves the pointer to the handler function and then enables the 810 1.1 jruoho * event. 811 1.1 jruoho * 812 1.1 jruoho ******************************************************************************/ 813 1.1 jruoho 814 1.1 jruoho ACPI_STATUS 815 1.1 jruoho AcpiInstallFixedEventHandler ( 816 1.1 jruoho UINT32 Event, 817 1.1 jruoho ACPI_EVENT_HANDLER Handler, 818 1.1 jruoho void *Context) 819 1.1 jruoho { 820 1.1 jruoho ACPI_STATUS Status; 821 1.1 jruoho 822 1.1 jruoho 823 1.1 jruoho ACPI_FUNCTION_TRACE (AcpiInstallFixedEventHandler); 824 1.1 jruoho 825 1.1 jruoho 826 1.1 jruoho /* Parameter validation */ 827 1.1 jruoho 828 1.1 jruoho if (Event > ACPI_EVENT_MAX) 829 1.1 jruoho { 830 1.1 jruoho return_ACPI_STATUS (AE_BAD_PARAMETER); 831 1.1 jruoho } 832 1.1 jruoho 833 1.1 jruoho Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 834 1.1 jruoho if (ACPI_FAILURE (Status)) 835 1.1 jruoho { 836 1.1 jruoho return_ACPI_STATUS (Status); 837 1.1 jruoho } 838 1.1 jruoho 839 1.5 christos /* Do not allow multiple handlers */ 840 1.1 jruoho 841 1.5 christos if (AcpiGbl_FixedEventHandlers[Event].Handler) 842 1.1 jruoho { 843 1.1 jruoho Status = AE_ALREADY_EXISTS; 844 1.1 jruoho goto Cleanup; 845 1.1 jruoho } 846 1.1 jruoho 847 1.1 jruoho /* Install the handler before enabling the event */ 848 1.1 jruoho 849 1.1 jruoho AcpiGbl_FixedEventHandlers[Event].Handler = Handler; 850 1.1 jruoho AcpiGbl_FixedEventHandlers[Event].Context = Context; 851 1.1 jruoho 852 1.1 jruoho Status = AcpiEnableEvent (Event, 0); 853 1.1 jruoho if (ACPI_FAILURE (Status)) 854 1.1 jruoho { 855 1.5 christos ACPI_WARNING ((AE_INFO, 856 1.5 christos "Could not enable fixed event - %s (%u)", 857 1.5 christos AcpiUtGetEventName (Event), Event)); 858 1.1 jruoho 859 1.1 jruoho /* Remove the handler */ 860 1.1 jruoho 861 1.1 jruoho AcpiGbl_FixedEventHandlers[Event].Handler = NULL; 862 1.1 jruoho AcpiGbl_FixedEventHandlers[Event].Context = NULL; 863 1.1 jruoho } 864 1.1 jruoho else 865 1.1 jruoho { 866 1.1 jruoho ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 867 1.5 christos "Enabled fixed event %s (%X), Handler=%p\n", 868 1.5 christos AcpiUtGetEventName (Event), Event, Handler)); 869 1.1 jruoho } 870 1.1 jruoho 871 1.1 jruoho 872 1.1 jruoho Cleanup: 873 1.1 jruoho (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 874 1.1 jruoho return_ACPI_STATUS (Status); 875 1.1 jruoho } 876 1.1 jruoho 877 1.1 jruoho ACPI_EXPORT_SYMBOL (AcpiInstallFixedEventHandler) 878 1.1 jruoho 879 1.1 jruoho 880 1.1 jruoho /******************************************************************************* 881 1.1 jruoho * 882 1.1 jruoho * FUNCTION: AcpiRemoveFixedEventHandler 883 1.1 jruoho * 884 1.1 jruoho * PARAMETERS: Event - Event type to disable. 885 1.1 jruoho * Handler - Address of the handler 886 1.1 jruoho * 887 1.1 jruoho * RETURN: Status 888 1.1 jruoho * 889 1.1 jruoho * DESCRIPTION: Disables the event and unregisters the event handler. 890 1.1 jruoho * 891 1.1 jruoho ******************************************************************************/ 892 1.1 jruoho 893 1.1 jruoho ACPI_STATUS 894 1.1 jruoho AcpiRemoveFixedEventHandler ( 895 1.1 jruoho UINT32 Event, 896 1.1 jruoho ACPI_EVENT_HANDLER Handler) 897 1.1 jruoho { 898 1.1 jruoho ACPI_STATUS Status = AE_OK; 899 1.1 jruoho 900 1.1 jruoho 901 1.1 jruoho ACPI_FUNCTION_TRACE (AcpiRemoveFixedEventHandler); 902 1.1 jruoho 903 1.1 jruoho 904 1.1 jruoho /* Parameter validation */ 905 1.1 jruoho 906 1.1 jruoho if (Event > ACPI_EVENT_MAX) 907 1.1 jruoho { 908 1.1 jruoho return_ACPI_STATUS (AE_BAD_PARAMETER); 909 1.1 jruoho } 910 1.1 jruoho 911 1.1 jruoho Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 912 1.1 jruoho if (ACPI_FAILURE (Status)) 913 1.1 jruoho { 914 1.1 jruoho return_ACPI_STATUS (Status); 915 1.1 jruoho } 916 1.1 jruoho 917 1.1 jruoho /* Disable the event before removing the handler */ 918 1.1 jruoho 919 1.1 jruoho Status = AcpiDisableEvent (Event, 0); 920 1.1 jruoho 921 1.1 jruoho /* Always Remove the handler */ 922 1.1 jruoho 923 1.1 jruoho AcpiGbl_FixedEventHandlers[Event].Handler = NULL; 924 1.1 jruoho AcpiGbl_FixedEventHandlers[Event].Context = NULL; 925 1.1 jruoho 926 1.1 jruoho if (ACPI_FAILURE (Status)) 927 1.1 jruoho { 928 1.1 jruoho ACPI_WARNING ((AE_INFO, 929 1.5 christos "Could not disable fixed event - %s (%u)", 930 1.5 christos AcpiUtGetEventName (Event), Event)); 931 1.1 jruoho } 932 1.1 jruoho else 933 1.1 jruoho { 934 1.5 christos ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 935 1.5 christos "Disabled fixed event - %s (%X)\n", 936 1.5 christos AcpiUtGetEventName (Event), Event)); 937 1.1 jruoho } 938 1.1 jruoho 939 1.1 jruoho (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 940 1.1 jruoho return_ACPI_STATUS (Status); 941 1.1 jruoho } 942 1.1 jruoho 943 1.1 jruoho ACPI_EXPORT_SYMBOL (AcpiRemoveFixedEventHandler) 944 1.1 jruoho 945 1.1 jruoho 946 1.1 jruoho /******************************************************************************* 947 1.1 jruoho * 948 1.7 christos * FUNCTION: AcpiEvInstallGpeHandler 949 1.1 jruoho * 950 1.1 jruoho * PARAMETERS: GpeDevice - Namespace node for the GPE (NULL for FADT 951 1.1 jruoho * defined GPEs) 952 1.1 jruoho * GpeNumber - The GPE number within the GPE block 953 1.1 jruoho * Type - Whether this GPE should be treated as an 954 1.1 jruoho * edge- or level-triggered interrupt. 955 1.7 christos * IsRawHandler - Whether this GPE should be handled using 956 1.7 christos * the special GPE handler mode. 957 1.1 jruoho * Address - Address of the handler 958 1.1 jruoho * Context - Value passed to the handler on each GPE 959 1.1 jruoho * 960 1.1 jruoho * RETURN: Status 961 1.1 jruoho * 962 1.7 christos * DESCRIPTION: Internal function to install a handler for a General Purpose 963 1.7 christos * Event. 964 1.1 jruoho * 965 1.1 jruoho ******************************************************************************/ 966 1.1 jruoho 967 1.7 christos static ACPI_STATUS 968 1.7 christos AcpiEvInstallGpeHandler ( 969 1.1 jruoho ACPI_HANDLE GpeDevice, 970 1.1 jruoho UINT32 GpeNumber, 971 1.1 jruoho UINT32 Type, 972 1.7 christos BOOLEAN IsRawHandler, 973 1.4 jruoho ACPI_GPE_HANDLER Address, 974 1.1 jruoho void *Context) 975 1.1 jruoho { 976 1.1 jruoho ACPI_GPE_EVENT_INFO *GpeEventInfo; 977 1.4 jruoho ACPI_GPE_HANDLER_INFO *Handler; 978 1.1 jruoho ACPI_STATUS Status; 979 1.1 jruoho ACPI_CPU_FLAGS Flags; 980 1.1 jruoho 981 1.1 jruoho 982 1.7 christos ACPI_FUNCTION_TRACE (EvInstallGpeHandler); 983 1.1 jruoho 984 1.1 jruoho 985 1.1 jruoho /* Parameter validation */ 986 1.1 jruoho 987 1.1 jruoho if ((!Address) || (Type & ~ACPI_GPE_XRUPT_TYPE_MASK)) 988 1.1 jruoho { 989 1.1 jruoho return_ACPI_STATUS (AE_BAD_PARAMETER); 990 1.1 jruoho } 991 1.1 jruoho 992 1.1 jruoho Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 993 1.1 jruoho if (ACPI_FAILURE (Status)) 994 1.1 jruoho { 995 1.1 jruoho return_ACPI_STATUS (Status); 996 1.1 jruoho } 997 1.1 jruoho 998 1.4 jruoho /* Allocate and init handler object (before lock) */ 999 1.4 jruoho 1000 1.4 jruoho Handler = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_GPE_HANDLER_INFO)); 1001 1.4 jruoho if (!Handler) 1002 1.4 jruoho { 1003 1.4 jruoho Status = AE_NO_MEMORY; 1004 1.4 jruoho goto UnlockAndExit; 1005 1.4 jruoho } 1006 1.4 jruoho 1007 1.4 jruoho Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 1008 1.4 jruoho 1009 1.1 jruoho /* Ensure that we have a valid GPE number */ 1010 1.1 jruoho 1011 1.1 jruoho GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 1012 1.1 jruoho if (!GpeEventInfo) 1013 1.1 jruoho { 1014 1.1 jruoho Status = AE_BAD_PARAMETER; 1015 1.4 jruoho goto FreeAndExit; 1016 1.1 jruoho } 1017 1.1 jruoho 1018 1.1 jruoho /* Make sure that there isn't a handler there already */ 1019 1.1 jruoho 1020 1.7 christos if ((ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) == 1021 1.7 christos ACPI_GPE_DISPATCH_HANDLER) || 1022 1.7 christos (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) == 1023 1.7 christos ACPI_GPE_DISPATCH_RAW_HANDLER)) 1024 1.1 jruoho { 1025 1.1 jruoho Status = AE_ALREADY_EXISTS; 1026 1.4 jruoho goto FreeAndExit; 1027 1.1 jruoho } 1028 1.1 jruoho 1029 1.4 jruoho Handler->Address = Address; 1030 1.4 jruoho Handler->Context = Context; 1031 1.4 jruoho Handler->MethodNode = GpeEventInfo->Dispatch.MethodNode; 1032 1.4 jruoho Handler->OriginalFlags = (UINT8) (GpeEventInfo->Flags & 1033 1.4 jruoho (ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK)); 1034 1.1 jruoho 1035 1.4 jruoho /* 1036 1.4 jruoho * If the GPE is associated with a method, it may have been enabled 1037 1.4 jruoho * automatically during initialization, in which case it has to be 1038 1.4 jruoho * disabled now to avoid spurious execution of the handler. 1039 1.4 jruoho */ 1040 1.7 christos if (((ACPI_GPE_DISPATCH_TYPE (Handler->OriginalFlags) == 1041 1.7 christos ACPI_GPE_DISPATCH_METHOD) || 1042 1.7 christos (ACPI_GPE_DISPATCH_TYPE (Handler->OriginalFlags) == 1043 1.7 christos ACPI_GPE_DISPATCH_NOTIFY)) && 1044 1.4 jruoho GpeEventInfo->RuntimeCount) 1045 1.1 jruoho { 1046 1.4 jruoho Handler->OriginallyEnabled = TRUE; 1047 1.4 jruoho (void) AcpiEvRemoveGpeReference (GpeEventInfo); 1048 1.1 jruoho 1049 1.4 jruoho /* Sanity check of original type against new type */ 1050 1.1 jruoho 1051 1.4 jruoho if (Type != (UINT32) (GpeEventInfo->Flags & ACPI_GPE_XRUPT_TYPE_MASK)) 1052 1.4 jruoho { 1053 1.4 jruoho ACPI_WARNING ((AE_INFO, "GPE type mismatch (level/edge)")); 1054 1.4 jruoho } 1055 1.1 jruoho } 1056 1.1 jruoho 1057 1.1 jruoho /* Install the handler */ 1058 1.1 jruoho 1059 1.1 jruoho GpeEventInfo->Dispatch.Handler = Handler; 1060 1.1 jruoho 1061 1.4 jruoho /* Setup up dispatch flags to indicate handler (vs. method/notify) */ 1062 1.1 jruoho 1063 1.1 jruoho GpeEventInfo->Flags &= ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK); 1064 1.7 christos GpeEventInfo->Flags |= (UINT8) (Type | (IsRawHandler ? 1065 1.7 christos ACPI_GPE_DISPATCH_RAW_HANDLER : ACPI_GPE_DISPATCH_HANDLER)); 1066 1.1 jruoho 1067 1.1 jruoho AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 1068 1.1 jruoho 1069 1.1 jruoho 1070 1.1 jruoho UnlockAndExit: 1071 1.1 jruoho (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 1072 1.1 jruoho return_ACPI_STATUS (Status); 1073 1.4 jruoho 1074 1.4 jruoho FreeAndExit: 1075 1.4 jruoho AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 1076 1.4 jruoho ACPI_FREE (Handler); 1077 1.4 jruoho goto UnlockAndExit; 1078 1.1 jruoho } 1079 1.1 jruoho 1080 1.7 christos 1081 1.7 christos /******************************************************************************* 1082 1.7 christos * 1083 1.7 christos * FUNCTION: AcpiInstallGpeHandler 1084 1.7 christos * 1085 1.7 christos * PARAMETERS: GpeDevice - Namespace node for the GPE (NULL for FADT 1086 1.7 christos * defined GPEs) 1087 1.7 christos * GpeNumber - The GPE number within the GPE block 1088 1.7 christos * Type - Whether this GPE should be treated as an 1089 1.7 christos * edge- or level-triggered interrupt. 1090 1.7 christos * Address - Address of the handler 1091 1.7 christos * Context - Value passed to the handler on each GPE 1092 1.7 christos * 1093 1.7 christos * RETURN: Status 1094 1.7 christos * 1095 1.7 christos * DESCRIPTION: Install a handler for a General Purpose Event. 1096 1.7 christos * 1097 1.7 christos ******************************************************************************/ 1098 1.7 christos 1099 1.7 christos ACPI_STATUS 1100 1.7 christos AcpiInstallGpeHandler ( 1101 1.7 christos ACPI_HANDLE GpeDevice, 1102 1.7 christos UINT32 GpeNumber, 1103 1.7 christos UINT32 Type, 1104 1.7 christos ACPI_GPE_HANDLER Address, 1105 1.7 christos void *Context) 1106 1.7 christos { 1107 1.7 christos ACPI_STATUS Status; 1108 1.7 christos 1109 1.7 christos 1110 1.7 christos ACPI_FUNCTION_TRACE (AcpiInstallGpeHandler); 1111 1.7 christos 1112 1.7 christos 1113 1.8 christos Status = AcpiEvInstallGpeHandler (GpeDevice, GpeNumber, Type, 1114 1.8 christos FALSE, Address, Context); 1115 1.7 christos 1116 1.7 christos return_ACPI_STATUS (Status); 1117 1.7 christos } 1118 1.7 christos 1119 1.1 jruoho ACPI_EXPORT_SYMBOL (AcpiInstallGpeHandler) 1120 1.1 jruoho 1121 1.1 jruoho 1122 1.1 jruoho /******************************************************************************* 1123 1.1 jruoho * 1124 1.7 christos * FUNCTION: AcpiInstallGpeRawHandler 1125 1.7 christos * 1126 1.7 christos * PARAMETERS: GpeDevice - Namespace node for the GPE (NULL for FADT 1127 1.7 christos * defined GPEs) 1128 1.7 christos * GpeNumber - The GPE number within the GPE block 1129 1.7 christos * Type - Whether this GPE should be treated as an 1130 1.7 christos * edge- or level-triggered interrupt. 1131 1.7 christos * Address - Address of the handler 1132 1.7 christos * Context - Value passed to the handler on each GPE 1133 1.7 christos * 1134 1.7 christos * RETURN: Status 1135 1.7 christos * 1136 1.7 christos * DESCRIPTION: Install a handler for a General Purpose Event. 1137 1.7 christos * 1138 1.7 christos ******************************************************************************/ 1139 1.7 christos 1140 1.7 christos ACPI_STATUS 1141 1.7 christos AcpiInstallGpeRawHandler ( 1142 1.7 christos ACPI_HANDLE GpeDevice, 1143 1.7 christos UINT32 GpeNumber, 1144 1.7 christos UINT32 Type, 1145 1.7 christos ACPI_GPE_HANDLER Address, 1146 1.7 christos void *Context) 1147 1.7 christos { 1148 1.7 christos ACPI_STATUS Status; 1149 1.7 christos 1150 1.7 christos 1151 1.7 christos ACPI_FUNCTION_TRACE (AcpiInstallGpeRawHandler); 1152 1.7 christos 1153 1.7 christos 1154 1.8 christos Status = AcpiEvInstallGpeHandler (GpeDevice, GpeNumber, Type, 1155 1.8 christos TRUE, Address, Context); 1156 1.7 christos 1157 1.7 christos return_ACPI_STATUS (Status); 1158 1.7 christos } 1159 1.7 christos 1160 1.7 christos ACPI_EXPORT_SYMBOL (AcpiInstallGpeRawHandler) 1161 1.7 christos 1162 1.7 christos 1163 1.7 christos /******************************************************************************* 1164 1.7 christos * 1165 1.1 jruoho * FUNCTION: AcpiRemoveGpeHandler 1166 1.1 jruoho * 1167 1.1 jruoho * PARAMETERS: GpeDevice - Namespace node for the GPE (NULL for FADT 1168 1.1 jruoho * defined GPEs) 1169 1.1 jruoho * GpeNumber - The event to remove a handler 1170 1.1 jruoho * Address - Address of the handler 1171 1.1 jruoho * 1172 1.1 jruoho * RETURN: Status 1173 1.1 jruoho * 1174 1.1 jruoho * DESCRIPTION: Remove a handler for a General Purpose AcpiEvent. 1175 1.1 jruoho * 1176 1.1 jruoho ******************************************************************************/ 1177 1.1 jruoho 1178 1.1 jruoho ACPI_STATUS 1179 1.1 jruoho AcpiRemoveGpeHandler ( 1180 1.1 jruoho ACPI_HANDLE GpeDevice, 1181 1.1 jruoho UINT32 GpeNumber, 1182 1.4 jruoho ACPI_GPE_HANDLER Address) 1183 1.1 jruoho { 1184 1.1 jruoho ACPI_GPE_EVENT_INFO *GpeEventInfo; 1185 1.4 jruoho ACPI_GPE_HANDLER_INFO *Handler; 1186 1.1 jruoho ACPI_STATUS Status; 1187 1.1 jruoho ACPI_CPU_FLAGS Flags; 1188 1.1 jruoho 1189 1.1 jruoho 1190 1.1 jruoho ACPI_FUNCTION_TRACE (AcpiRemoveGpeHandler); 1191 1.1 jruoho 1192 1.1 jruoho 1193 1.1 jruoho /* Parameter validation */ 1194 1.1 jruoho 1195 1.1 jruoho if (!Address) 1196 1.1 jruoho { 1197 1.1 jruoho return_ACPI_STATUS (AE_BAD_PARAMETER); 1198 1.1 jruoho } 1199 1.1 jruoho 1200 1.1 jruoho Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 1201 1.1 jruoho if (ACPI_FAILURE (Status)) 1202 1.1 jruoho { 1203 1.1 jruoho return_ACPI_STATUS (Status); 1204 1.1 jruoho } 1205 1.1 jruoho 1206 1.4 jruoho Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 1207 1.4 jruoho 1208 1.1 jruoho /* Ensure that we have a valid GPE number */ 1209 1.1 jruoho 1210 1.1 jruoho GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 1211 1.1 jruoho if (!GpeEventInfo) 1212 1.1 jruoho { 1213 1.1 jruoho Status = AE_BAD_PARAMETER; 1214 1.1 jruoho goto UnlockAndExit; 1215 1.1 jruoho } 1216 1.1 jruoho 1217 1.1 jruoho /* Make sure that a handler is indeed installed */ 1218 1.1 jruoho 1219 1.7 christos if ((ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) != 1220 1.7 christos ACPI_GPE_DISPATCH_HANDLER) && 1221 1.7 christos (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) != 1222 1.7 christos ACPI_GPE_DISPATCH_RAW_HANDLER)) 1223 1.1 jruoho { 1224 1.1 jruoho Status = AE_NOT_EXIST; 1225 1.1 jruoho goto UnlockAndExit; 1226 1.1 jruoho } 1227 1.1 jruoho 1228 1.1 jruoho /* Make sure that the installed handler is the same */ 1229 1.1 jruoho 1230 1.1 jruoho if (GpeEventInfo->Dispatch.Handler->Address != Address) 1231 1.1 jruoho { 1232 1.1 jruoho Status = AE_BAD_PARAMETER; 1233 1.1 jruoho goto UnlockAndExit; 1234 1.1 jruoho } 1235 1.1 jruoho 1236 1.1 jruoho /* Remove the handler */ 1237 1.1 jruoho 1238 1.1 jruoho Handler = GpeEventInfo->Dispatch.Handler; 1239 1.7 christos GpeEventInfo->Dispatch.Handler = NULL; 1240 1.1 jruoho 1241 1.1 jruoho /* Restore Method node (if any), set dispatch flags */ 1242 1.1 jruoho 1243 1.1 jruoho GpeEventInfo->Dispatch.MethodNode = Handler->MethodNode; 1244 1.4 jruoho GpeEventInfo->Flags &= 1245 1.4 jruoho ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK); 1246 1.4 jruoho GpeEventInfo->Flags |= Handler->OriginalFlags; 1247 1.4 jruoho 1248 1.4 jruoho /* 1249 1.4 jruoho * If the GPE was previously associated with a method and it was 1250 1.4 jruoho * enabled, it should be enabled at this point to restore the 1251 1.4 jruoho * post-initialization configuration. 1252 1.4 jruoho */ 1253 1.7 christos if (((ACPI_GPE_DISPATCH_TYPE (Handler->OriginalFlags) == 1254 1.7 christos ACPI_GPE_DISPATCH_METHOD) || 1255 1.7 christos (ACPI_GPE_DISPATCH_TYPE (Handler->OriginalFlags) == 1256 1.7 christos ACPI_GPE_DISPATCH_NOTIFY)) && 1257 1.4 jruoho Handler->OriginallyEnabled) 1258 1.1 jruoho { 1259 1.12 christos (void) AcpiEvAddGpeReference (GpeEventInfo, FALSE); 1260 1.10 christos if (ACPI_GPE_IS_POLLING_NEEDED (GpeEventInfo)) 1261 1.10 christos { 1262 1.10 christos /* Poll edge triggered GPEs to handle existing events */ 1263 1.10 christos 1264 1.10 christos AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 1265 1.10 christos (void) AcpiEvDetectGpe ( 1266 1.10 christos GpeDevice, GpeEventInfo, GpeNumber); 1267 1.10 christos Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 1268 1.10 christos } 1269 1.1 jruoho } 1270 1.1 jruoho 1271 1.6 christos AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 1272 1.6 christos (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 1273 1.6 christos 1274 1.6 christos /* Make sure all deferred GPE tasks are completed */ 1275 1.6 christos 1276 1.6 christos AcpiOsWaitEventsComplete (); 1277 1.6 christos 1278 1.1 jruoho /* Now we can free the handler object */ 1279 1.1 jruoho 1280 1.1 jruoho ACPI_FREE (Handler); 1281 1.6 christos return_ACPI_STATUS (Status); 1282 1.1 jruoho 1283 1.1 jruoho UnlockAndExit: 1284 1.4 jruoho AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 1285 1.1 jruoho (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 1286 1.1 jruoho return_ACPI_STATUS (Status); 1287 1.1 jruoho } 1288 1.1 jruoho 1289 1.1 jruoho ACPI_EXPORT_SYMBOL (AcpiRemoveGpeHandler) 1290 1.1 jruoho 1291 1.1 jruoho 1292 1.1 jruoho /******************************************************************************* 1293 1.1 jruoho * 1294 1.1 jruoho * FUNCTION: AcpiAcquireGlobalLock 1295 1.1 jruoho * 1296 1.1 jruoho * PARAMETERS: Timeout - How long the caller is willing to wait 1297 1.1 jruoho * Handle - Where the handle to the lock is returned 1298 1.1 jruoho * (if acquired) 1299 1.1 jruoho * 1300 1.1 jruoho * RETURN: Status 1301 1.1 jruoho * 1302 1.1 jruoho * DESCRIPTION: Acquire the ACPI Global Lock 1303 1.1 jruoho * 1304 1.1 jruoho * Note: Allows callers with the same thread ID to acquire the global lock 1305 1.1 jruoho * multiple times. In other words, externally, the behavior of the global lock 1306 1.1 jruoho * is identical to an AML mutex. On the first acquire, a new handle is 1307 1.1 jruoho * returned. On any subsequent calls to acquire by the same thread, the same 1308 1.1 jruoho * handle is returned. 1309 1.1 jruoho * 1310 1.1 jruoho ******************************************************************************/ 1311 1.1 jruoho 1312 1.1 jruoho ACPI_STATUS 1313 1.1 jruoho AcpiAcquireGlobalLock ( 1314 1.1 jruoho UINT16 Timeout, 1315 1.1 jruoho UINT32 *Handle) 1316 1.1 jruoho { 1317 1.1 jruoho ACPI_STATUS Status; 1318 1.1 jruoho 1319 1.1 jruoho 1320 1.1 jruoho if (!Handle) 1321 1.1 jruoho { 1322 1.1 jruoho return (AE_BAD_PARAMETER); 1323 1.1 jruoho } 1324 1.1 jruoho 1325 1.1 jruoho /* Must lock interpreter to prevent race conditions */ 1326 1.1 jruoho 1327 1.1 jruoho AcpiExEnterInterpreter (); 1328 1.1 jruoho 1329 1.1 jruoho Status = AcpiExAcquireMutexObject (Timeout, 1330 1.8 christos AcpiGbl_GlobalLockMutex, AcpiOsGetThreadId ()); 1331 1.1 jruoho 1332 1.1 jruoho if (ACPI_SUCCESS (Status)) 1333 1.1 jruoho { 1334 1.1 jruoho /* Return the global lock handle (updated in AcpiEvAcquireGlobalLock) */ 1335 1.1 jruoho 1336 1.1 jruoho *Handle = AcpiGbl_GlobalLockHandle; 1337 1.1 jruoho } 1338 1.1 jruoho 1339 1.1 jruoho AcpiExExitInterpreter (); 1340 1.1 jruoho return (Status); 1341 1.1 jruoho } 1342 1.1 jruoho 1343 1.1 jruoho ACPI_EXPORT_SYMBOL (AcpiAcquireGlobalLock) 1344 1.1 jruoho 1345 1.1 jruoho 1346 1.1 jruoho /******************************************************************************* 1347 1.1 jruoho * 1348 1.1 jruoho * FUNCTION: AcpiReleaseGlobalLock 1349 1.1 jruoho * 1350 1.1 jruoho * PARAMETERS: Handle - Returned from AcpiAcquireGlobalLock 1351 1.1 jruoho * 1352 1.1 jruoho * RETURN: Status 1353 1.1 jruoho * 1354 1.1 jruoho * DESCRIPTION: Release the ACPI Global Lock. The handle must be valid. 1355 1.1 jruoho * 1356 1.1 jruoho ******************************************************************************/ 1357 1.1 jruoho 1358 1.1 jruoho ACPI_STATUS 1359 1.1 jruoho AcpiReleaseGlobalLock ( 1360 1.1 jruoho UINT32 Handle) 1361 1.1 jruoho { 1362 1.1 jruoho ACPI_STATUS Status; 1363 1.1 jruoho 1364 1.1 jruoho 1365 1.1 jruoho if (!Handle || (Handle != AcpiGbl_GlobalLockHandle)) 1366 1.1 jruoho { 1367 1.1 jruoho return (AE_NOT_ACQUIRED); 1368 1.1 jruoho } 1369 1.1 jruoho 1370 1.1 jruoho Status = AcpiExReleaseMutexObject (AcpiGbl_GlobalLockMutex); 1371 1.1 jruoho return (Status); 1372 1.1 jruoho } 1373 1.1 jruoho 1374 1.1 jruoho ACPI_EXPORT_SYMBOL (AcpiReleaseGlobalLock) 1375 1.1 jruoho 1376 1.5 christos #endif /* !ACPI_REDUCED_HARDWARE */ 1377