1/****************************************************************************** 2 * 3 * Module Name: evgpe - General Purpose Event handling and dispatch |
4 * $Revision: 1.68 $ |
5 * 6 *****************************************************************************/ 7 8/****************************************************************************** 9 * 10 * 1. Copyright Notice 11 * |
12 * Some or all of this work - Copyright (c) 1999 - 2007, Intel Corp. |
13 * All rights reserved. 14 * 15 * 2. License 16 * 17 * 2.1. This is your license from Intel Corp. under its intellectual property 18 * rights. You may have additional license terms from the party that provided 19 * you this software, covering your right to use that party's intellectual 20 * property rights. --- 123 unchanged lines hidden (view full) --- 144ACPI_STATUS 145AcpiEvSetGpeType ( 146 ACPI_GPE_EVENT_INFO *GpeEventInfo, 147 UINT8 Type) 148{ 149 ACPI_STATUS Status; 150 151 |
152 ACPI_FUNCTION_TRACE (EvSetGpeType); |
153 154 155 /* Validate type and update register enable masks */ 156 157 switch (Type) 158 { 159 case ACPI_GPE_TYPE_WAKE: 160 case ACPI_GPE_TYPE_RUNTIME: --- 34 unchanged lines hidden (view full) --- 195AcpiEvUpdateGpeEnableMasks ( 196 ACPI_GPE_EVENT_INFO *GpeEventInfo, 197 UINT8 Type) 198{ 199 ACPI_GPE_REGISTER_INFO *GpeRegisterInfo; 200 UINT8 RegisterBit; 201 202 |
203 ACPI_FUNCTION_TRACE (EvUpdateGpeEnableMasks); |
204 205 206 GpeRegisterInfo = GpeEventInfo->RegisterInfo; 207 if (!GpeRegisterInfo) 208 { 209 return_ACPI_STATUS (AE_NOT_EXIST); 210 } |
211 RegisterBit = (UINT8) 212 (1 << (GpeEventInfo->GpeNumber - GpeRegisterInfo->BaseGpeNumber)); |
213 214 /* 1) Disable case. Simply clear all enable bits */ 215 216 if (Type == ACPI_GPE_DISABLE) 217 { 218 ACPI_CLEAR_BIT (GpeRegisterInfo->EnableForWake, RegisterBit); 219 ACPI_CLEAR_BIT (GpeRegisterInfo->EnableForRun, RegisterBit); 220 return_ACPI_STATUS (AE_OK); --- 43 unchanged lines hidden (view full) --- 264ACPI_STATUS 265AcpiEvEnableGpe ( 266 ACPI_GPE_EVENT_INFO *GpeEventInfo, 267 BOOLEAN WriteToHardware) 268{ 269 ACPI_STATUS Status; 270 271 |
272 ACPI_FUNCTION_TRACE (EvEnableGpe); |
273 274 275 /* Make sure HW enable masks are updated */ 276 277 Status = AcpiEvUpdateGpeEnableMasks (GpeEventInfo, ACPI_GPE_ENABLE); 278 if (ACPI_FAILURE (Status)) 279 { 280 return_ACPI_STATUS (Status); --- 56 unchanged lines hidden (view full) --- 337 338ACPI_STATUS 339AcpiEvDisableGpe ( 340 ACPI_GPE_EVENT_INFO *GpeEventInfo) 341{ 342 ACPI_STATUS Status; 343 344 |
345 ACPI_FUNCTION_TRACE (EvDisableGpe); |
346 347 348 if (!(GpeEventInfo->Flags & ACPI_GPE_ENABLE_MASK)) 349 { 350 return_ACPI_STATUS (AE_OK); 351 } 352 353 /* Make sure HW enable masks are updated */ --- 130 unchanged lines hidden (view full) --- 484{ 485 ACPI_STATUS Status; 486 ACPI_GPE_BLOCK_INFO *GpeBlock; 487 ACPI_GPE_REGISTER_INFO *GpeRegisterInfo; 488 UINT32 IntStatus = ACPI_INTERRUPT_NOT_HANDLED; 489 UINT8 EnabledStatusByte; 490 UINT32 StatusReg; 491 UINT32 EnableReg; |
492 ACPI_CPU_FLAGS Flags; |
493 ACPI_NATIVE_UINT i; 494 ACPI_NATIVE_UINT j; 495 496 |
497 ACPI_FUNCTION_NAME (EvGpeDetect); |
498 499 /* Check for the case where there are no GPEs */ 500 501 if (!GpeXruptList) 502 { 503 return (IntStatus); 504 } 505 |
506 /* 507 * We need to obtain the GPE lock for both the data structs and registers 508 * Note: Not necessary to obtain the hardware lock, since the GPE registers 509 * are owned by the GpeLock. 510 */ 511 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 512 |
513 /* Examine all GPE blocks attached to this interrupt level */ 514 |
515 GpeBlock = GpeXruptList->GpeBlockListHead; 516 while (GpeBlock) 517 { 518 /* 519 * Read all of the 8-bit GPE status and enable registers 520 * in this GPE block, saving all of them. 521 * Find all currently active GP events. 522 */ --- 36 unchanged lines hidden (view full) --- 559 } 560 561 /* Now look at the individual GPEs in this byte register */ 562 563 for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) 564 { 565 /* Examine one GPE bit */ 566 |
567 if (EnabledStatusByte & (1 << j)) |
568 { 569 /* 570 * Found an active GPE. Dispatch the event to a handler 571 * or method. 572 */ 573 IntStatus |= AcpiEvGpeDispatch ( 574 &GpeBlock->EventInfo[(i * ACPI_GPE_REGISTER_WIDTH) + j], 575 (UINT32) j + GpeRegisterInfo->BaseGpeNumber); --- 14 unchanged lines hidden (view full) --- 590/******************************************************************************* 591 * 592 * FUNCTION: AcpiEvAsynchExecuteGpeMethod 593 * 594 * PARAMETERS: Context (GpeEventInfo) - Info for this GPE 595 * 596 * RETURN: None 597 * |
598 * DESCRIPTION: Perform the actual execution of a GPE control method. This 599 * function is called from an invocation of AcpiOsExecute and 600 * therefore does NOT execute at interrupt level - so that |
601 * the control method itself is not executed in the context of 602 * an interrupt handler. 603 * 604 ******************************************************************************/ 605 606static void ACPI_SYSTEM_XFACE 607AcpiEvAsynchExecuteGpeMethod ( 608 void *Context) 609{ 610 ACPI_GPE_EVENT_INFO *GpeEventInfo = (void *) Context; |
611 ACPI_STATUS Status; 612 ACPI_GPE_EVENT_INFO LocalGpeEventInfo; |
613 ACPI_EVALUATE_INFO *Info; |
614 615 |
616 ACPI_FUNCTION_TRACE (EvAsynchExecuteGpeMethod); |
617 618 619 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 620 if (ACPI_FAILURE (Status)) 621 { 622 return_VOID; 623 } 624 --- 24 unchanged lines hidden (view full) --- 649 650 /* 651 * Must check for control method type dispatch one more 652 * time to avoid race with EvGpeInstallHandler 653 */ 654 if ((LocalGpeEventInfo.Flags & ACPI_GPE_DISPATCH_MASK) == 655 ACPI_GPE_DISPATCH_METHOD) 656 { |
657 /* Allocate the evaluation information block */ |
658 |
659 Info = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_EVALUATE_INFO)); 660 if (!Info) 661 { 662 Status = AE_NO_MEMORY; 663 } 664 else 665 { 666 /* 667 * Invoke the GPE Method (_Lxx, _Exx) i.e., evaluate the _Lxx/_Exx 668 * control method that corresponds to this GPE 669 */ 670 Info->PrefixNode = LocalGpeEventInfo.Dispatch.MethodNode; 671 Info->Parameters = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT *, GpeEventInfo); 672 Info->ParameterType = ACPI_PARAM_GPE; 673 Info->Flags = ACPI_IGNORE_RETURN_VALUE; 674 675 Status = AcpiNsEvaluate (Info); 676 ACPI_FREE (Info); 677 } 678 |
679 if (ACPI_FAILURE (Status)) 680 { |
681 ACPI_EXCEPTION ((AE_INFO, Status, 682 "while evaluating GPE method [%4.4s]", 683 AcpiUtGetNodeName (LocalGpeEventInfo.Dispatch.MethodNode))); |
684 } 685 } 686 687 if ((LocalGpeEventInfo.Flags & ACPI_GPE_XRUPT_TYPE_MASK) == 688 ACPI_GPE_LEVEL_TRIGGERED) 689 { 690 /* 691 * GPE is level-triggered, we clear the GPE status bit after --- 32 unchanged lines hidden (view full) --- 724UINT32 725AcpiEvGpeDispatch ( 726 ACPI_GPE_EVENT_INFO *GpeEventInfo, 727 UINT32 GpeNumber) 728{ 729 ACPI_STATUS Status; 730 731 |
732 ACPI_FUNCTION_TRACE (EvGpeDispatch); |
733 734 |
735 AcpiGpeCount++; 736 |
737 /* 738 * If edge-triggered, clear the GPE status bit now. Note that 739 * level-triggered events are cleared after the GPE is serviced. 740 */ 741 if ((GpeEventInfo->Flags & ACPI_GPE_XRUPT_TYPE_MASK) == 742 ACPI_GPE_EDGE_TRIGGERED) 743 { 744 Status = AcpiHwClearGpe (GpeEventInfo); 745 if (ACPI_FAILURE (Status)) 746 { |
747 ACPI_EXCEPTION ((AE_INFO, Status, 748 "Unable to clear GPE[%2X]", GpeNumber)); |
749 return_UINT32 (ACPI_INTERRUPT_NOT_HANDLED); 750 } 751 } 752 |
753 if (!AcpiGbl_SystemAwakeAndRunning) |
754 { |
755 /* 756 * We just woke up because of a wake GPE. Disable any further GPEs 757 * until we are fully up and running (Only wake GPEs should be enabled 758 * at this time, but we just brute-force disable them all.) 759 * 1) We must disable this particular wake GPE so it won't fire again 760 * 2) We want to disable all wake GPEs, since we are now awake 761 */ 762 (void) AcpiHwDisableAllGpes (); |
763 } |
764 765 /* |
766 * Dispatch the GPE to either an installed handler, or the control method 767 * associated with this GPE (_Lxx or _Exx). If a handler exists, we invoke 768 * it and do not attempt to run the method. If there is neither a handler 769 * nor a method, we disable this GPE to prevent further such pointless 770 * events from firing. |
771 */ 772 switch (GpeEventInfo->Flags & ACPI_GPE_DISPATCH_MASK) 773 { 774 case ACPI_GPE_DISPATCH_HANDLER: 775 776 /* 777 * Invoke the installed handler (at interrupt level) 778 * Ignore return status for now. TBD: leave GPE disabled on error? --- 4 unchanged lines hidden (view full) --- 783 /* It is now safe to clear level-triggered events. */ 784 785 if ((GpeEventInfo->Flags & ACPI_GPE_XRUPT_TYPE_MASK) == 786 ACPI_GPE_LEVEL_TRIGGERED) 787 { 788 Status = AcpiHwClearGpe (GpeEventInfo); 789 if (ACPI_FAILURE (Status)) 790 { |
791 ACPI_EXCEPTION ((AE_INFO, Status, 792 "Unable to clear GPE[%2X]", GpeNumber)); |
793 return_UINT32 (ACPI_INTERRUPT_NOT_HANDLED); 794 } 795 } 796 break; 797 798 case ACPI_GPE_DISPATCH_METHOD: 799 800 /* |
801 * Disable the GPE, so it doesn't keep firing before the method has a 802 * chance to run (it runs asynchronously with interrupts enabled). |
803 */ 804 Status = AcpiEvDisableGpe (GpeEventInfo); 805 if (ACPI_FAILURE (Status)) 806 { |
807 ACPI_EXCEPTION ((AE_INFO, Status, 808 "Unable to disable GPE[%2X]", GpeNumber)); |
809 return_UINT32 (ACPI_INTERRUPT_NOT_HANDLED); 810 } 811 812 /* 813 * Execute the method associated with the GPE 814 * NOTE: Level-triggered GPEs are cleared after the method completes. 815 */ |
816 Status = AcpiOsExecute (OSL_GPE_HANDLER, |
817 AcpiEvAsynchExecuteGpeMethod, GpeEventInfo); 818 if (ACPI_FAILURE (Status)) 819 { |
820 ACPI_EXCEPTION ((AE_INFO, Status, 821 "Unable to queue handler for GPE[%2X] - event disabled", 822 GpeNumber)); |
823 } 824 break; 825 826 default: 827 828 /* No handler or method to run! */ 829 |
830 ACPI_ERROR ((AE_INFO, 831 "No handler or method for GPE[%2X], disabling event", |
832 GpeNumber)); 833 834 /* |
835 * Disable the GPE. The GPE will remain disabled until the ACPI |
836 * Core Subsystem is restarted, or a handler is installed. 837 */ 838 Status = AcpiEvDisableGpe (GpeEventInfo); 839 if (ACPI_FAILURE (Status)) 840 { |
841 ACPI_EXCEPTION ((AE_INFO, Status, 842 "Unable to disable GPE[%2X]", GpeNumber)); |
843 return_UINT32 (ACPI_INTERRUPT_NOT_HANDLED); 844 } 845 break; 846 } 847 848 return_UINT32 (ACPI_INTERRUPT_HANDLED); 849} 850 |