![]() |
|
|||
File indexing completed on 2025-05-11 08:24:02
0001 /****************************************************************************** 0002 * 0003 * Module Name: evgpe - General Purpose Event handling and dispatch 0004 * 0005 *****************************************************************************/ 0006 0007 /****************************************************************************** 0008 * 0009 * 1. Copyright Notice 0010 * 0011 * Some or all of this work - Copyright (c) 1999 - 2024, Intel Corp. 0012 * All rights reserved. 0013 * 0014 * 2. License 0015 * 0016 * 2.1. This is your license from Intel Corp. under its intellectual property 0017 * rights. You may have additional license terms from the party that provided 0018 * you this software, covering your right to use that party's intellectual 0019 * property rights. 0020 * 0021 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 0022 * copy of the source code appearing in this file ("Covered Code") an 0023 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 0024 * base code distributed originally by Intel ("Original Intel Code") to copy, 0025 * make derivatives, distribute, use and display any portion of the Covered 0026 * Code in any form, with the right to sublicense such rights; and 0027 * 0028 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 0029 * license (with the right to sublicense), under only those claims of Intel 0030 * patents that are infringed by the Original Intel Code, to make, use, sell, 0031 * offer to sell, and import the Covered Code and derivative works thereof 0032 * solely to the minimum extent necessary to exercise the above copyright 0033 * license, and in no event shall the patent license extend to any additions 0034 * to or modifications of the Original Intel Code. No other license or right 0035 * is granted directly or by implication, estoppel or otherwise; 0036 * 0037 * The above copyright and patent license is granted only if the following 0038 * conditions are met: 0039 * 0040 * 3. Conditions 0041 * 0042 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 0043 * Redistribution of source code of any substantial portion of the Covered 0044 * Code or modification with rights to further distribute source must include 0045 * the above Copyright Notice, the above License, this list of Conditions, 0046 * and the following Disclaimer and Export Compliance provision. In addition, 0047 * Licensee must cause all Covered Code to which Licensee contributes to 0048 * contain a file documenting the changes Licensee made to create that Covered 0049 * Code and the date of any change. Licensee must include in that file the 0050 * documentation of any changes made by any predecessor Licensee. Licensee 0051 * must include a prominent statement that the modification is derived, 0052 * directly or indirectly, from Original Intel Code. 0053 * 0054 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 0055 * Redistribution of source code of any substantial portion of the Covered 0056 * Code or modification without rights to further distribute source must 0057 * include the following Disclaimer and Export Compliance provision in the 0058 * documentation and/or other materials provided with distribution. In 0059 * addition, Licensee may not authorize further sublicense of source of any 0060 * portion of the Covered Code, and must include terms to the effect that the 0061 * license from Licensee to its licensee is limited to the intellectual 0062 * property embodied in the software Licensee provides to its licensee, and 0063 * not to intellectual property embodied in modifications its licensee may 0064 * make. 0065 * 0066 * 3.3. Redistribution of Executable. Redistribution in executable form of any 0067 * substantial portion of the Covered Code or modification must reproduce the 0068 * above Copyright Notice, and the following Disclaimer and Export Compliance 0069 * provision in the documentation and/or other materials provided with the 0070 * distribution. 0071 * 0072 * 3.4. Intel retains all right, title, and interest in and to the Original 0073 * Intel Code. 0074 * 0075 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 0076 * Intel shall be used in advertising or otherwise to promote the sale, use or 0077 * other dealings in products derived from or relating to the Covered Code 0078 * without prior written authorization from Intel. 0079 * 0080 * 4. Disclaimer and Export Compliance 0081 * 0082 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 0083 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 0084 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 0085 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 0086 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 0087 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 0088 * PARTICULAR PURPOSE. 0089 * 0090 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 0091 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 0092 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 0093 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 0094 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 0095 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 0096 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 0097 * LIMITED REMEDY. 0098 * 0099 * 4.3. Licensee shall not export, either directly or indirectly, any of this 0100 * software or system incorporating such software without first obtaining any 0101 * required license or other approval from the U. S. Department of Commerce or 0102 * any other agency or department of the United States Government. In the 0103 * event Licensee exports any such software from the United States or 0104 * re-exports any such software from a foreign destination, Licensee shall 0105 * ensure that the distribution and export/re-export of the software is in 0106 * compliance with all laws, regulations, orders, or other restrictions of the 0107 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 0108 * any of its subsidiaries will export/re-export any technical data, process, 0109 * software, or service, directly or indirectly, to any country for which the 0110 * United States government or any agency thereof requires an export license, 0111 * other governmental approval, or letter of assurance, without first obtaining 0112 * such license, approval or letter. 0113 * 0114 ***************************************************************************** 0115 * 0116 * Alternatively, you may choose to be licensed under the terms of the 0117 * following license: 0118 * 0119 * Redistribution and use in source and binary forms, with or without 0120 * modification, are permitted provided that the following conditions 0121 * are met: 0122 * 1. Redistributions of source code must retain the above copyright 0123 * notice, this list of conditions, and the following disclaimer, 0124 * without modification. 0125 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 0126 * substantially similar to the "NO WARRANTY" disclaimer below 0127 * ("Disclaimer") and any redistribution must be conditioned upon 0128 * including a substantially similar Disclaimer requirement for further 0129 * binary redistribution. 0130 * 3. Neither the names of the above-listed copyright holders nor the names 0131 * of any contributors may be used to endorse or promote products derived 0132 * from this software without specific prior written permission. 0133 * 0134 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 0135 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 0136 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 0137 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 0138 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 0139 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 0140 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 0141 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 0142 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 0143 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 0144 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 0145 * 0146 * Alternatively, you may choose to be licensed under the terms of the 0147 * GNU General Public License ("GPL") version 2 as published by the Free 0148 * Software Foundation. 0149 * 0150 *****************************************************************************/ 0151 0152 #include "acpi.h" 0153 #include "accommon.h" 0154 #include "acevents.h" 0155 #include "acnamesp.h" 0156 0157 #define _COMPONENT ACPI_EVENTS 0158 ACPI_MODULE_NAME ("evgpe") 0159 0160 #if (!ACPI_REDUCED_HARDWARE) /* Entire module */ 0161 0162 /* Local prototypes */ 0163 0164 static void ACPI_SYSTEM_XFACE 0165 AcpiEvAsynchExecuteGpeMethod ( 0166 void *Context); 0167 0168 static void ACPI_SYSTEM_XFACE 0169 AcpiEvAsynchEnableGpe ( 0170 void *Context); 0171 0172 0173 /******************************************************************************* 0174 * 0175 * FUNCTION: AcpiEvUpdateGpeEnableMask 0176 * 0177 * PARAMETERS: GpeEventInfo - GPE to update 0178 * 0179 * RETURN: Status 0180 * 0181 * DESCRIPTION: Updates GPE register enable mask based upon whether there are 0182 * runtime references to this GPE 0183 * 0184 ******************************************************************************/ 0185 0186 ACPI_STATUS 0187 AcpiEvUpdateGpeEnableMask ( 0188 ACPI_GPE_EVENT_INFO *GpeEventInfo) 0189 { 0190 ACPI_GPE_REGISTER_INFO *GpeRegisterInfo; 0191 UINT32 RegisterBit; 0192 0193 0194 ACPI_FUNCTION_TRACE (EvUpdateGpeEnableMask); 0195 0196 0197 GpeRegisterInfo = GpeEventInfo->RegisterInfo; 0198 if (!GpeRegisterInfo) 0199 { 0200 return_ACPI_STATUS (AE_NOT_EXIST); 0201 } 0202 0203 RegisterBit = AcpiHwGetGpeRegisterBit (GpeEventInfo); 0204 0205 /* Clear the run bit up front */ 0206 0207 ACPI_CLEAR_BIT (GpeRegisterInfo->EnableForRun, RegisterBit); 0208 0209 /* Set the mask bit only if there are references to this GPE */ 0210 0211 if (GpeEventInfo->RuntimeCount) 0212 { 0213 ACPI_SET_BIT (GpeRegisterInfo->EnableForRun, (UINT8) RegisterBit); 0214 } 0215 0216 GpeRegisterInfo->EnableMask = GpeRegisterInfo->EnableForRun; 0217 return_ACPI_STATUS (AE_OK); 0218 } 0219 0220 0221 /******************************************************************************* 0222 * 0223 * FUNCTION: AcpiEvEnableGpe 0224 * 0225 * PARAMETERS: GpeEventInfo - GPE to enable 0226 * 0227 * RETURN: Status 0228 * 0229 * DESCRIPTION: Enable a GPE. 0230 * 0231 ******************************************************************************/ 0232 0233 ACPI_STATUS 0234 AcpiEvEnableGpe ( 0235 ACPI_GPE_EVENT_INFO *GpeEventInfo) 0236 { 0237 ACPI_STATUS Status; 0238 0239 0240 ACPI_FUNCTION_TRACE (EvEnableGpe); 0241 0242 0243 /* Enable the requested GPE */ 0244 0245 Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_ENABLE); 0246 return_ACPI_STATUS (Status); 0247 } 0248 0249 0250 /******************************************************************************* 0251 * 0252 * FUNCTION: AcpiEvMaskGpe 0253 * 0254 * PARAMETERS: GpeEventInfo - GPE to be blocked/unblocked 0255 * IsMasked - Whether the GPE is masked or not 0256 * 0257 * RETURN: Status 0258 * 0259 * DESCRIPTION: Unconditionally mask/unmask a GPE during runtime. 0260 * 0261 ******************************************************************************/ 0262 0263 ACPI_STATUS 0264 AcpiEvMaskGpe ( 0265 ACPI_GPE_EVENT_INFO *GpeEventInfo, 0266 BOOLEAN IsMasked) 0267 { 0268 ACPI_GPE_REGISTER_INFO *GpeRegisterInfo; 0269 UINT32 RegisterBit; 0270 0271 0272 ACPI_FUNCTION_TRACE (EvMaskGpe); 0273 0274 0275 GpeRegisterInfo = GpeEventInfo->RegisterInfo; 0276 if (!GpeRegisterInfo) 0277 { 0278 return_ACPI_STATUS (AE_NOT_EXIST); 0279 } 0280 0281 RegisterBit = AcpiHwGetGpeRegisterBit (GpeEventInfo); 0282 0283 /* Perform the action */ 0284 0285 if (IsMasked) 0286 { 0287 if (RegisterBit & GpeRegisterInfo->MaskForRun) 0288 { 0289 return_ACPI_STATUS (AE_BAD_PARAMETER); 0290 } 0291 0292 (void) AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_DISABLE); 0293 ACPI_SET_BIT (GpeRegisterInfo->MaskForRun, (UINT8) RegisterBit); 0294 } 0295 else 0296 { 0297 if (!(RegisterBit & GpeRegisterInfo->MaskForRun)) 0298 { 0299 return_ACPI_STATUS (AE_BAD_PARAMETER); 0300 } 0301 0302 ACPI_CLEAR_BIT (GpeRegisterInfo->MaskForRun, (UINT8) RegisterBit); 0303 if (GpeEventInfo->RuntimeCount && 0304 !GpeEventInfo->DisableForDispatch) 0305 { 0306 (void) AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_ENABLE); 0307 } 0308 } 0309 0310 return_ACPI_STATUS (AE_OK); 0311 } 0312 0313 0314 /******************************************************************************* 0315 * 0316 * FUNCTION: AcpiEvAddGpeReference 0317 * 0318 * PARAMETERS: GpeEventInfo - Add a reference to this GPE 0319 * ClearOnEnable - Clear GPE status before enabling it 0320 * 0321 * RETURN: Status 0322 * 0323 * DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is 0324 * hardware-enabled. 0325 * 0326 ******************************************************************************/ 0327 0328 ACPI_STATUS 0329 AcpiEvAddGpeReference ( 0330 ACPI_GPE_EVENT_INFO *GpeEventInfo, 0331 BOOLEAN ClearOnEnable) 0332 { 0333 ACPI_STATUS Status = AE_OK; 0334 0335 0336 ACPI_FUNCTION_TRACE (EvAddGpeReference); 0337 0338 0339 if (GpeEventInfo->RuntimeCount == ACPI_UINT8_MAX) 0340 { 0341 return_ACPI_STATUS (AE_LIMIT); 0342 } 0343 0344 GpeEventInfo->RuntimeCount++; 0345 if (GpeEventInfo->RuntimeCount == 1) 0346 { 0347 /* Enable on first reference */ 0348 0349 if (ClearOnEnable) 0350 { 0351 (void) AcpiHwClearGpe (GpeEventInfo); 0352 } 0353 0354 Status = AcpiEvUpdateGpeEnableMask (GpeEventInfo); 0355 if (ACPI_SUCCESS (Status)) 0356 { 0357 Status = AcpiEvEnableGpe (GpeEventInfo); 0358 } 0359 0360 if (ACPI_FAILURE (Status)) 0361 { 0362 GpeEventInfo->RuntimeCount--; 0363 } 0364 } 0365 0366 return_ACPI_STATUS (Status); 0367 } 0368 0369 0370 /******************************************************************************* 0371 * 0372 * FUNCTION: AcpiEvRemoveGpeReference 0373 * 0374 * PARAMETERS: GpeEventInfo - Remove a reference to this GPE 0375 * 0376 * RETURN: Status 0377 * 0378 * DESCRIPTION: Remove a reference to a GPE. When the last reference is 0379 * removed, the GPE is hardware-disabled. 0380 * 0381 ******************************************************************************/ 0382 0383 ACPI_STATUS 0384 AcpiEvRemoveGpeReference ( 0385 ACPI_GPE_EVENT_INFO *GpeEventInfo) 0386 { 0387 ACPI_STATUS Status = AE_OK; 0388 0389 0390 ACPI_FUNCTION_TRACE (EvRemoveGpeReference); 0391 0392 0393 if (!GpeEventInfo->RuntimeCount) 0394 { 0395 return_ACPI_STATUS (AE_LIMIT); 0396 } 0397 0398 GpeEventInfo->RuntimeCount--; 0399 if (!GpeEventInfo->RuntimeCount) 0400 { 0401 /* Disable on last reference */ 0402 0403 Status = AcpiEvUpdateGpeEnableMask (GpeEventInfo); 0404 if (ACPI_SUCCESS (Status)) 0405 { 0406 Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_DISABLE); 0407 } 0408 0409 if (ACPI_FAILURE (Status)) 0410 { 0411 GpeEventInfo->RuntimeCount++; 0412 } 0413 } 0414 0415 return_ACPI_STATUS (Status); 0416 } 0417 0418 0419 /******************************************************************************* 0420 * 0421 * FUNCTION: AcpiEvLowGetGpeInfo 0422 * 0423 * PARAMETERS: GpeNumber - Raw GPE number 0424 * GpeBlock - A GPE info block 0425 * 0426 * RETURN: A GPE EventInfo struct. NULL if not a valid GPE (The GpeNumber 0427 * is not within the specified GPE block) 0428 * 0429 * DESCRIPTION: Returns the EventInfo struct associated with this GPE. This is 0430 * the low-level implementation of EvGetGpeEventInfo. 0431 * 0432 ******************************************************************************/ 0433 0434 ACPI_GPE_EVENT_INFO * 0435 AcpiEvLowGetGpeInfo ( 0436 UINT32 GpeNumber, 0437 ACPI_GPE_BLOCK_INFO *GpeBlock) 0438 { 0439 UINT32 GpeIndex; 0440 0441 0442 /* 0443 * Validate that the GpeNumber is within the specified GpeBlock. 0444 * (Two steps) 0445 */ 0446 if (!GpeBlock || 0447 (GpeNumber < GpeBlock->BlockBaseNumber)) 0448 { 0449 return (NULL); 0450 } 0451 0452 GpeIndex = GpeNumber - GpeBlock->BlockBaseNumber; 0453 if (GpeIndex >= GpeBlock->GpeCount) 0454 { 0455 return (NULL); 0456 } 0457 0458 return (&GpeBlock->EventInfo[GpeIndex]); 0459 } 0460 0461 0462 /******************************************************************************* 0463 * 0464 * FUNCTION: AcpiEvGetGpeEventInfo 0465 * 0466 * PARAMETERS: GpeDevice - Device node. NULL for GPE0/GPE1 0467 * GpeNumber - Raw GPE number 0468 * 0469 * RETURN: A GPE EventInfo struct. NULL if not a valid GPE 0470 * 0471 * DESCRIPTION: Returns the EventInfo struct associated with this GPE. 0472 * Validates the GpeBlock and the GpeNumber 0473 * 0474 * Should be called only when the GPE lists are semaphore locked 0475 * and not subject to change. 0476 * 0477 ******************************************************************************/ 0478 0479 ACPI_GPE_EVENT_INFO * 0480 AcpiEvGetGpeEventInfo ( 0481 ACPI_HANDLE GpeDevice, 0482 UINT32 GpeNumber) 0483 { 0484 ACPI_OPERAND_OBJECT *ObjDesc; 0485 ACPI_GPE_EVENT_INFO *GpeInfo; 0486 UINT32 i; 0487 0488 0489 ACPI_FUNCTION_ENTRY (); 0490 0491 0492 /* A NULL GpeDevice means use the FADT-defined GPE block(s) */ 0493 0494 if (!GpeDevice) 0495 { 0496 /* Examine GPE Block 0 and 1 (These blocks are permanent) */ 0497 0498 for (i = 0; i < ACPI_MAX_GPE_BLOCKS; i++) 0499 { 0500 GpeInfo = AcpiEvLowGetGpeInfo (GpeNumber, 0501 AcpiGbl_GpeFadtBlocks[i]); 0502 if (GpeInfo) 0503 { 0504 return (GpeInfo); 0505 } 0506 } 0507 0508 /* The GpeNumber was not in the range of either FADT GPE block */ 0509 0510 return (NULL); 0511 } 0512 0513 /* A Non-NULL GpeDevice means this is a GPE Block Device */ 0514 0515 ObjDesc = AcpiNsGetAttachedObject ((ACPI_NAMESPACE_NODE *) GpeDevice); 0516 if (!ObjDesc || 0517 !ObjDesc->Device.GpeBlock) 0518 { 0519 return (NULL); 0520 } 0521 0522 return (AcpiEvLowGetGpeInfo (GpeNumber, ObjDesc->Device.GpeBlock)); 0523 } 0524 0525 0526 /******************************************************************************* 0527 * 0528 * FUNCTION: AcpiEvGpeDetect 0529 * 0530 * PARAMETERS: GpeXruptList - Interrupt block for this interrupt. 0531 * Can have multiple GPE blocks attached. 0532 * 0533 * RETURN: INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED 0534 * 0535 * DESCRIPTION: Detect if any GP events have occurred. This function is 0536 * executed at interrupt level. 0537 * 0538 ******************************************************************************/ 0539 0540 UINT32 0541 AcpiEvGpeDetect ( 0542 ACPI_GPE_XRUPT_INFO *GpeXruptList) 0543 { 0544 ACPI_GPE_BLOCK_INFO *GpeBlock; 0545 ACPI_NAMESPACE_NODE *GpeDevice; 0546 ACPI_GPE_REGISTER_INFO *GpeRegisterInfo; 0547 ACPI_GPE_EVENT_INFO *GpeEventInfo; 0548 UINT32 GpeNumber; 0549 UINT32 IntStatus = ACPI_INTERRUPT_NOT_HANDLED; 0550 ACPI_CPU_FLAGS Flags; 0551 UINT32 i; 0552 UINT32 j; 0553 0554 0555 ACPI_FUNCTION_NAME (EvGpeDetect); 0556 0557 /* Check for the case where there are no GPEs */ 0558 0559 if (!GpeXruptList) 0560 { 0561 return (IntStatus); 0562 } 0563 0564 /* 0565 * We need to obtain the GPE lock for both the data structs and registers 0566 * Note: Not necessary to obtain the hardware lock, since the GPE 0567 * registers are owned by the GpeLock. 0568 */ 0569 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 0570 0571 /* Examine all GPE blocks attached to this interrupt level */ 0572 0573 GpeBlock = GpeXruptList->GpeBlockListHead; 0574 while (GpeBlock) 0575 { 0576 GpeDevice = GpeBlock->Node; 0577 0578 /* 0579 * Read all of the 8-bit GPE status and enable registers in this GPE 0580 * block, saving all of them. Find all currently active GP events. 0581 */ 0582 for (i = 0; i < GpeBlock->RegisterCount; i++) 0583 { 0584 /* Get the next status/enable pair */ 0585 0586 GpeRegisterInfo = &GpeBlock->RegisterInfo[i]; 0587 0588 /* 0589 * Optimization: If there are no GPEs enabled within this 0590 * register, we can safely ignore the entire register. 0591 */ 0592 if (!(GpeRegisterInfo->EnableForRun | 0593 GpeRegisterInfo->EnableForWake)) 0594 { 0595 ACPI_DEBUG_PRINT ((ACPI_DB_INTERRUPTS, 0596 "Ignore disabled registers for GPE %02X-%02X: " 0597 "RunEnable=%02X, WakeEnable=%02X\n", 0598 GpeRegisterInfo->BaseGpeNumber, 0599 GpeRegisterInfo->BaseGpeNumber + (ACPI_GPE_REGISTER_WIDTH - 1), 0600 GpeRegisterInfo->EnableForRun, 0601 GpeRegisterInfo->EnableForWake)); 0602 continue; 0603 } 0604 0605 /* Now look at the individual GPEs in this byte register */ 0606 0607 for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) 0608 { 0609 /* Detect and dispatch one GPE bit */ 0610 0611 GpeEventInfo = &GpeBlock->EventInfo[((ACPI_SIZE) i * 0612 ACPI_GPE_REGISTER_WIDTH) + j]; 0613 GpeNumber = j + GpeRegisterInfo->BaseGpeNumber; 0614 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 0615 IntStatus |= AcpiEvDetectGpe ( 0616 GpeDevice, GpeEventInfo, GpeNumber); 0617 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 0618 } 0619 } 0620 0621 GpeBlock = GpeBlock->Next; 0622 } 0623 0624 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 0625 return (IntStatus); 0626 } 0627 0628 0629 /******************************************************************************* 0630 * 0631 * FUNCTION: AcpiEvAsynchExecuteGpeMethod 0632 * 0633 * PARAMETERS: Context (GpeEventInfo) - Info for this GPE 0634 * 0635 * RETURN: None 0636 * 0637 * DESCRIPTION: Perform the actual execution of a GPE control method. This 0638 * function is called from an invocation of AcpiOsExecute and 0639 * therefore does NOT execute at interrupt level - so that 0640 * the control method itself is not executed in the context of 0641 * an interrupt handler. 0642 * 0643 ******************************************************************************/ 0644 0645 static void ACPI_SYSTEM_XFACE 0646 AcpiEvAsynchExecuteGpeMethod ( 0647 void *Context) 0648 { 0649 ACPI_GPE_EVENT_INFO *GpeEventInfo = Context; 0650 ACPI_STATUS Status = AE_OK; 0651 ACPI_EVALUATE_INFO *Info; 0652 ACPI_GPE_NOTIFY_INFO *Notify; 0653 0654 0655 ACPI_FUNCTION_TRACE (EvAsynchExecuteGpeMethod); 0656 0657 0658 /* Do the correct dispatch - normal method or implicit notify */ 0659 0660 switch (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags)) 0661 { 0662 case ACPI_GPE_DISPATCH_NOTIFY: 0663 /* 0664 * Implicit notify. 0665 * Dispatch a DEVICE_WAKE notify to the appropriate handler. 0666 * NOTE: the request is queued for execution after this method 0667 * completes. The notify handlers are NOT invoked synchronously 0668 * from this thread -- because handlers may in turn run other 0669 * control methods. 0670 * 0671 * June 2012: Expand implicit notify mechanism to support 0672 * notifies on multiple device objects. 0673 */ 0674 Notify = GpeEventInfo->Dispatch.NotifyList; 0675 while (ACPI_SUCCESS (Status) && Notify) 0676 { 0677 Status = AcpiEvQueueNotifyRequest ( 0678 Notify->DeviceNode, ACPI_NOTIFY_DEVICE_WAKE); 0679 0680 Notify = Notify->Next; 0681 } 0682 break; 0683 0684 case ACPI_GPE_DISPATCH_METHOD: 0685 0686 /* Allocate the evaluation information block */ 0687 0688 Info = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO)); 0689 if (!Info) 0690 { 0691 Status = AE_NO_MEMORY; 0692 } 0693 else 0694 { 0695 /* 0696 * Invoke the GPE Method (_Lxx, _Exx) i.e., evaluate the 0697 * _Lxx/_Exx control method that corresponds to this GPE 0698 */ 0699 Info->PrefixNode = GpeEventInfo->Dispatch.MethodNode; 0700 Info->Flags = ACPI_IGNORE_RETURN_VALUE; 0701 0702 Status = AcpiNsEvaluate (Info); 0703 ACPI_FREE (Info); 0704 } 0705 0706 if (ACPI_FAILURE (Status)) 0707 { 0708 ACPI_EXCEPTION ((AE_INFO, Status, 0709 "while evaluating GPE method [%4.4s]", 0710 AcpiUtGetNodeName (GpeEventInfo->Dispatch.MethodNode))); 0711 } 0712 break; 0713 0714 default: 0715 0716 goto ErrorExit; /* Should never happen */ 0717 } 0718 0719 /* Defer enabling of GPE until all notify handlers are done */ 0720 0721 Status = AcpiOsExecute (OSL_NOTIFY_HANDLER, 0722 AcpiEvAsynchEnableGpe, GpeEventInfo); 0723 if (ACPI_SUCCESS (Status)) 0724 { 0725 return_VOID; 0726 } 0727 0728 ErrorExit: 0729 AcpiEvAsynchEnableGpe (GpeEventInfo); 0730 return_VOID; 0731 } 0732 0733 0734 /******************************************************************************* 0735 * 0736 * FUNCTION: AcpiEvAsynchEnableGpe 0737 * 0738 * PARAMETERS: Context (GpeEventInfo) - Info for this GPE 0739 * Callback from AcpiOsExecute 0740 * 0741 * RETURN: None 0742 * 0743 * DESCRIPTION: Asynchronous clear/enable for GPE. This allows the GPE to 0744 * complete (i.e., finish execution of Notify) 0745 * 0746 ******************************************************************************/ 0747 0748 static void ACPI_SYSTEM_XFACE 0749 AcpiEvAsynchEnableGpe ( 0750 void *Context) 0751 { 0752 ACPI_GPE_EVENT_INFO *GpeEventInfo = Context; 0753 ACPI_CPU_FLAGS Flags; 0754 0755 0756 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 0757 (void) AcpiEvFinishGpe (GpeEventInfo); 0758 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 0759 0760 return; 0761 } 0762 0763 0764 /******************************************************************************* 0765 * 0766 * FUNCTION: AcpiEvFinishGpe 0767 * 0768 * PARAMETERS: GpeEventInfo - Info for this GPE 0769 * 0770 * RETURN: Status 0771 * 0772 * DESCRIPTION: Clear/Enable a GPE. Common code that is used after execution 0773 * of a GPE method or a synchronous or asynchronous GPE handler. 0774 * 0775 ******************************************************************************/ 0776 0777 ACPI_STATUS 0778 AcpiEvFinishGpe ( 0779 ACPI_GPE_EVENT_INFO *GpeEventInfo) 0780 { 0781 ACPI_STATUS Status; 0782 0783 0784 if ((GpeEventInfo->Flags & ACPI_GPE_XRUPT_TYPE_MASK) == 0785 ACPI_GPE_LEVEL_TRIGGERED) 0786 { 0787 /* 0788 * GPE is level-triggered, we clear the GPE status bit after 0789 * handling the event. 0790 */ 0791 Status = AcpiHwClearGpe (GpeEventInfo); 0792 if (ACPI_FAILURE (Status)) 0793 { 0794 return (Status); 0795 } 0796 } 0797 0798 /* 0799 * Enable this GPE, conditionally. This means that the GPE will 0800 * only be physically enabled if the EnableMask bit is set 0801 * in the EventInfo. 0802 */ 0803 (void) AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_CONDITIONAL_ENABLE); 0804 GpeEventInfo->DisableForDispatch = FALSE; 0805 return (AE_OK); 0806 } 0807 0808 0809 /******************************************************************************* 0810 * 0811 * FUNCTION: AcpiEvDetectGpe 0812 * 0813 * PARAMETERS: GpeDevice - Device node. NULL for GPE0/GPE1 0814 * GpeEventInfo - Info for this GPE 0815 * GpeNumber - Number relative to the parent GPE block 0816 * 0817 * RETURN: INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED 0818 * 0819 * DESCRIPTION: Detect and dispatch a General Purpose Event to either a function 0820 * (e.g. EC) or method (e.g. _Lxx/_Exx) handler. 0821 * NOTE: GPE is W1C, so it is possible to handle a single GPE from both 0822 * task and irq context in parallel as long as the process to 0823 * detect and mask the GPE is atomic. 0824 * However the atomicity of ACPI_GPE_DISPATCH_RAW_HANDLER is 0825 * dependent on the raw handler itself. 0826 * 0827 ******************************************************************************/ 0828 0829 UINT32 0830 AcpiEvDetectGpe ( 0831 ACPI_NAMESPACE_NODE *GpeDevice, 0832 ACPI_GPE_EVENT_INFO *GpeEventInfo, 0833 UINT32 GpeNumber) 0834 { 0835 UINT32 IntStatus = ACPI_INTERRUPT_NOT_HANDLED; 0836 UINT8 EnabledStatusByte; 0837 UINT64 StatusReg; 0838 UINT64 EnableReg; 0839 UINT32 RegisterBit; 0840 ACPI_GPE_REGISTER_INFO *GpeRegisterInfo; 0841 ACPI_GPE_HANDLER_INFO *GpeHandlerInfo; 0842 ACPI_CPU_FLAGS Flags; 0843 ACPI_STATUS Status; 0844 0845 0846 ACPI_FUNCTION_TRACE (EvGpeDetect); 0847 0848 0849 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 0850 0851 if (!GpeEventInfo) 0852 { 0853 GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 0854 if (!GpeEventInfo) 0855 { 0856 goto ErrorExit; 0857 } 0858 } 0859 0860 /* Get the info block for the entire GPE register */ 0861 0862 GpeRegisterInfo = GpeEventInfo->RegisterInfo; 0863 0864 /* Get the register bitmask for this GPE */ 0865 0866 RegisterBit = AcpiHwGetGpeRegisterBit (GpeEventInfo); 0867 0868 /* GPE currently enabled (enable bit == 1)? */ 0869 0870 Status = AcpiHwRead (&EnableReg, &GpeRegisterInfo->EnableAddress); 0871 if (ACPI_FAILURE (Status)) 0872 { 0873 goto ErrorExit; 0874 } 0875 0876 /* GPE currently active (status bit == 1)? */ 0877 0878 Status = AcpiHwRead (&StatusReg, &GpeRegisterInfo->StatusAddress); 0879 if (ACPI_FAILURE (Status)) 0880 { 0881 goto ErrorExit; 0882 } 0883 0884 /* Check if there is anything active at all in this GPE */ 0885 0886 ACPI_DEBUG_PRINT ((ACPI_DB_INTERRUPTS, 0887 "Read registers for GPE %02X: Status=%02X, Enable=%02X, " 0888 "RunEnable=%02X, WakeEnable=%02X\n", 0889 GpeNumber, 0890 (UINT32) (StatusReg & RegisterBit), 0891 (UINT32) (EnableReg & RegisterBit), 0892 GpeRegisterInfo->EnableForRun, 0893 GpeRegisterInfo->EnableForWake)); 0894 0895 EnabledStatusByte = (UINT8) (StatusReg & EnableReg); 0896 if (!(EnabledStatusByte & RegisterBit)) 0897 { 0898 goto ErrorExit; 0899 } 0900 0901 /* Invoke global event handler if present */ 0902 0903 AcpiGpeCount++; 0904 if (AcpiGbl_GlobalEventHandler) 0905 { 0906 AcpiGbl_GlobalEventHandler (ACPI_EVENT_TYPE_GPE, 0907 GpeDevice, GpeNumber, 0908 AcpiGbl_GlobalEventHandlerContext); 0909 } 0910 0911 /* Found an active GPE */ 0912 0913 if (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) == 0914 ACPI_GPE_DISPATCH_RAW_HANDLER) 0915 { 0916 /* Dispatch the event to a raw handler */ 0917 0918 GpeHandlerInfo = GpeEventInfo->Dispatch.Handler; 0919 0920 /* 0921 * There is no protection around the namespace node 0922 * and the GPE handler to ensure a safe destruction 0923 * because: 0924 * 1. The namespace node is expected to always 0925 * exist after loading a table. 0926 * 2. The GPE handler is expected to be flushed by 0927 * AcpiOsWaitEventsComplete() before the 0928 * destruction. 0929 */ 0930 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 0931 IntStatus |= GpeHandlerInfo->Address ( 0932 GpeDevice, GpeNumber, GpeHandlerInfo->Context); 0933 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 0934 } 0935 else 0936 { 0937 /* Dispatch the event to a standard handler or method. */ 0938 0939 IntStatus |= AcpiEvGpeDispatch (GpeDevice, 0940 GpeEventInfo, GpeNumber); 0941 } 0942 0943 ErrorExit: 0944 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 0945 return (IntStatus); 0946 } 0947 0948 0949 /******************************************************************************* 0950 * 0951 * FUNCTION: AcpiEvGpeDispatch 0952 * 0953 * PARAMETERS: GpeDevice - Device node. NULL for GPE0/GPE1 0954 * GpeEventInfo - Info for this GPE 0955 * GpeNumber - Number relative to the parent GPE block 0956 * 0957 * RETURN: INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED 0958 * 0959 * DESCRIPTION: Dispatch a General Purpose Event to either a function (e.g. EC) 0960 * or method (e.g. _Lxx/_Exx) handler. 0961 * 0962 ******************************************************************************/ 0963 0964 UINT32 0965 AcpiEvGpeDispatch ( 0966 ACPI_NAMESPACE_NODE *GpeDevice, 0967 ACPI_GPE_EVENT_INFO *GpeEventInfo, 0968 UINT32 GpeNumber) 0969 { 0970 ACPI_STATUS Status; 0971 UINT32 ReturnValue; 0972 0973 0974 ACPI_FUNCTION_TRACE (EvGpeDispatch); 0975 0976 0977 /* 0978 * Always disable the GPE so that it does not keep firing before 0979 * any asynchronous activity completes (either from the execution 0980 * of a GPE method or an asynchronous GPE handler.) 0981 * 0982 * If there is no handler or method to run, just disable the 0983 * GPE and leave it disabled permanently to prevent further such 0984 * pointless events from firing. 0985 */ 0986 Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_DISABLE); 0987 if (ACPI_FAILURE (Status)) 0988 { 0989 ACPI_EXCEPTION ((AE_INFO, Status, 0990 "Unable to disable GPE %02X", GpeNumber)); 0991 return_UINT32 (ACPI_INTERRUPT_NOT_HANDLED); 0992 } 0993 0994 /* 0995 * If edge-triggered, clear the GPE status bit now. Note that 0996 * level-triggered events are cleared after the GPE is serviced. 0997 */ 0998 if ((GpeEventInfo->Flags & ACPI_GPE_XRUPT_TYPE_MASK) == 0999 ACPI_GPE_EDGE_TRIGGERED) 1000 { 1001 Status = AcpiHwClearGpe (GpeEventInfo); 1002 if (ACPI_FAILURE (Status)) 1003 { 1004 ACPI_EXCEPTION ((AE_INFO, Status, 1005 "Unable to clear GPE %02X", GpeNumber)); 1006 (void) AcpiHwLowSetGpe ( 1007 GpeEventInfo, ACPI_GPE_CONDITIONAL_ENABLE); 1008 return_UINT32 (ACPI_INTERRUPT_NOT_HANDLED); 1009 } 1010 } 1011 1012 GpeEventInfo->DisableForDispatch = TRUE; 1013 1014 /* 1015 * Dispatch the GPE to either an installed handler or the control 1016 * method associated with this GPE (_Lxx or _Exx). If a handler 1017 * exists, we invoke it and do not attempt to run the method. 1018 * If there is neither a handler nor a method, leave the GPE 1019 * disabled. 1020 */ 1021 switch (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags)) 1022 { 1023 case ACPI_GPE_DISPATCH_HANDLER: 1024 1025 /* Invoke the installed handler (at interrupt level) */ 1026 1027 ReturnValue = GpeEventInfo->Dispatch.Handler->Address ( 1028 GpeDevice, GpeNumber, 1029 GpeEventInfo->Dispatch.Handler->Context); 1030 1031 /* If requested, clear (if level-triggered) and re-enable the GPE */ 1032 1033 if (ReturnValue & ACPI_REENABLE_GPE) 1034 { 1035 (void) AcpiEvFinishGpe (GpeEventInfo); 1036 } 1037 break; 1038 1039 case ACPI_GPE_DISPATCH_METHOD: 1040 case ACPI_GPE_DISPATCH_NOTIFY: 1041 /* 1042 * Execute the method associated with the GPE 1043 * NOTE: Level-triggered GPEs are cleared after the method completes. 1044 */ 1045 Status = AcpiOsExecute (OSL_GPE_HANDLER, 1046 AcpiEvAsynchExecuteGpeMethod, GpeEventInfo); 1047 if (ACPI_FAILURE (Status)) 1048 { 1049 ACPI_EXCEPTION ((AE_INFO, Status, 1050 "Unable to queue handler for GPE %02X - event disabled", 1051 GpeNumber)); 1052 } 1053 break; 1054 1055 default: 1056 /* 1057 * No handler or method to run! 1058 * 03/2010: This case should no longer be possible. We will not allow 1059 * a GPE to be enabled if it has no handler or method. 1060 */ 1061 ACPI_ERROR ((AE_INFO, 1062 "No handler or method for GPE %02X, disabling event", 1063 GpeNumber)); 1064 break; 1065 } 1066 1067 return_UINT32 (ACPI_INTERRUPT_HANDLED); 1068 } 1069 1070 #endif /* !ACPI_REDUCED_HARDWARE */
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
![]() ![]() |