1 /****************************************************************************** 2 * 3 * Module Name: evxfgpe - External Interfaces for General Purpose Events (GPEs) 4 * 5 *****************************************************************************/ 6 7 /****************************************************************************** 8 * 9 * 1. Copyright Notice 10 * 11 * Some or all of this work - Copyright (c) 1999 - 2022, Intel Corp. 12 * All rights reserved. 13 * 14 * 2. License 15 * 16 * 2.1. This is your license from Intel Corp. under its intellectual property 17 * rights. You may have additional license terms from the party that provided 18 * you this software, covering your right to use that party's intellectual 19 * property rights. 20 * 21 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 22 * copy of the source code appearing in this file ("Covered Code") an 23 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 24 * base code distributed originally by Intel ("Original Intel Code") to copy, 25 * make derivatives, distribute, use and display any portion of the Covered 26 * Code in any form, with the right to sublicense such rights; and 27 * 28 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 29 * license (with the right to sublicense), under only those claims of Intel 30 * patents that are infringed by the Original Intel Code, to make, use, sell, 31 * offer to sell, and import the Covered Code and derivative works thereof 32 * solely to the minimum extent necessary to exercise the above copyright 33 * license, and in no event shall the patent license extend to any additions 34 * to or modifications of the Original Intel Code. No other license or right 35 * is granted directly or by implication, estoppel or otherwise; 36 * 37 * The above copyright and patent license is granted only if the following 38 * conditions are met: 39 * 40 * 3. Conditions 41 * 42 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 43 * Redistribution of source code of any substantial portion of the Covered 44 * Code or modification with rights to further distribute source must include 45 * the above Copyright Notice, the above License, this list of Conditions, 46 * and the following Disclaimer and Export Compliance provision. In addition, 47 * Licensee must cause all Covered Code to which Licensee contributes to 48 * contain a file documenting the changes Licensee made to create that Covered 49 * Code and the date of any change. Licensee must include in that file the 50 * documentation of any changes made by any predecessor Licensee. Licensee 51 * must include a prominent statement that the modification is derived, 52 * directly or indirectly, from Original Intel Code. 53 * 54 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 55 * Redistribution of source code of any substantial portion of the Covered 56 * Code or modification without rights to further distribute source must 57 * include the following Disclaimer and Export Compliance provision in the 58 * documentation and/or other materials provided with distribution. In 59 * addition, Licensee may not authorize further sublicense of source of any 60 * portion of the Covered Code, and must include terms to the effect that the 61 * license from Licensee to its licensee is limited to the intellectual 62 * property embodied in the software Licensee provides to its licensee, and 63 * not to intellectual property embodied in modifications its licensee may 64 * make. 65 * 66 * 3.3. Redistribution of Executable. Redistribution in executable form of any 67 * substantial portion of the Covered Code or modification must reproduce the 68 * above Copyright Notice, and the following Disclaimer and Export Compliance 69 * provision in the documentation and/or other materials provided with the 70 * distribution. 71 * 72 * 3.4. Intel retains all right, title, and interest in and to the Original 73 * Intel Code. 74 * 75 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 76 * Intel shall be used in advertising or otherwise to promote the sale, use or 77 * other dealings in products derived from or relating to the Covered Code 78 * without prior written authorization from Intel. 79 * 80 * 4. Disclaimer and Export Compliance 81 * 82 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 83 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 84 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 85 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 86 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 87 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 88 * PARTICULAR PURPOSE. 89 * 90 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 91 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 92 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 93 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 94 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 95 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 96 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 97 * LIMITED REMEDY. 98 * 99 * 4.3. Licensee shall not export, either directly or indirectly, any of this 100 * software or system incorporating such software without first obtaining any 101 * required license or other approval from the U. S. Department of Commerce or 102 * any other agency or department of the United States Government. In the 103 * event Licensee exports any such software from the United States or 104 * re-exports any such software from a foreign destination, Licensee shall 105 * ensure that the distribution and export/re-export of the software is in 106 * compliance with all laws, regulations, orders, or other restrictions of the 107 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 108 * any of its subsidiaries will export/re-export any technical data, process, 109 * software, or service, directly or indirectly, to any country for which the 110 * United States government or any agency thereof requires an export license, 111 * other governmental approval, or letter of assurance, without first obtaining 112 * such license, approval or letter. 113 * 114 ***************************************************************************** 115 * 116 * Alternatively, you may choose to be licensed under the terms of the 117 * following license: 118 * 119 * Redistribution and use in source and binary forms, with or without 120 * modification, are permitted provided that the following conditions 121 * are met: 122 * 1. Redistributions of source code must retain the above copyright 123 * notice, this list of conditions, and the following disclaimer, 124 * without modification. 125 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 126 * substantially similar to the "NO WARRANTY" disclaimer below 127 * ("Disclaimer") and any redistribution must be conditioned upon 128 * including a substantially similar Disclaimer requirement for further 129 * binary redistribution. 130 * 3. Neither the names of the above-listed copyright holders nor the names 131 * of any contributors may be used to endorse or promote products derived 132 * from this software without specific prior written permission. 133 * 134 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 135 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 136 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 137 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 138 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 139 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 140 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 141 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 142 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 143 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 144 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 145 * 146 * Alternatively, you may choose to be licensed under the terms of the 147 * GNU General Public License ("GPL") version 2 as published by the Free 148 * Software Foundation. 149 * 150 *****************************************************************************/ 151 152 #define EXPORT_ACPI_INTERFACES 153 154 #include <contrib/dev/acpica/include/acpi.h> 155 #include <contrib/dev/acpica/include/accommon.h> 156 #include <contrib/dev/acpica/include/acevents.h> 157 #include <contrib/dev/acpica/include/acnamesp.h> 158 159 #define _COMPONENT ACPI_EVENTS 160 ACPI_MODULE_NAME ("evxfgpe") 161 162 163 #if (!ACPI_REDUCED_HARDWARE) /* Entire module */ 164 /******************************************************************************* 165 * 166 * FUNCTION: AcpiUpdateAllGpes 167 * 168 * PARAMETERS: None 169 * 170 * RETURN: Status 171 * 172 * DESCRIPTION: Complete GPE initialization and enable all GPEs that have 173 * associated _Lxx or _Exx methods and are not pointed to by any 174 * device _PRW methods (this indicates that these GPEs are 175 * generally intended for system or device wakeup. Such GPEs 176 * have to be enabled directly when the devices whose _PRW 177 * methods point to them are set up for wakeup signaling.) 178 * 179 * NOTE: Should be called after any GPEs are added to the system. Primarily, 180 * after the system _PRW methods have been run, but also after a GPE Block 181 * Device has been added or if any new GPE methods have been added via a 182 * dynamic table load. 183 * 184 ******************************************************************************/ 185 186 ACPI_STATUS 187 AcpiUpdateAllGpes ( 188 void) 189 { 190 ACPI_STATUS Status; 191 BOOLEAN IsPollingNeeded = FALSE; 192 193 194 ACPI_FUNCTION_TRACE (AcpiUpdateAllGpes); 195 196 197 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 198 if (ACPI_FAILURE (Status)) 199 { 200 return_ACPI_STATUS (Status); 201 } 202 203 if (AcpiGbl_AllGpesInitialized) 204 { 205 goto UnlockAndExit; 206 } 207 208 Status = AcpiEvWalkGpeList (AcpiEvInitializeGpeBlock, 209 &IsPollingNeeded); 210 if (ACPI_SUCCESS (Status)) 211 { 212 AcpiGbl_AllGpesInitialized = TRUE; 213 } 214 215 UnlockAndExit: 216 (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 217 218 if (IsPollingNeeded && AcpiGbl_AllGpesInitialized) 219 { 220 /* Poll GPEs to handle already triggered events */ 221 222 AcpiEvGpeDetect (AcpiGbl_GpeXruptListHead); 223 } 224 return_ACPI_STATUS (Status); 225 } 226 227 ACPI_EXPORT_SYMBOL (AcpiUpdateAllGpes) 228 229 230 /******************************************************************************* 231 * 232 * FUNCTION: AcpiEnableGpe 233 * 234 * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1 235 * GpeNumber - GPE level within the GPE block 236 * 237 * RETURN: Status 238 * 239 * DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is 240 * hardware-enabled. 241 * 242 ******************************************************************************/ 243 244 ACPI_STATUS 245 AcpiEnableGpe ( 246 ACPI_HANDLE GpeDevice, 247 UINT32 GpeNumber) 248 { 249 ACPI_STATUS Status = AE_BAD_PARAMETER; 250 ACPI_GPE_EVENT_INFO *GpeEventInfo; 251 ACPI_CPU_FLAGS Flags; 252 253 254 ACPI_FUNCTION_TRACE (AcpiEnableGpe); 255 256 257 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 258 259 /* 260 * Ensure that we have a valid GPE number and that there is some way 261 * of handling the GPE (handler or a GPE method). In other words, we 262 * won't allow a valid GPE to be enabled if there is no way to handle it. 263 */ 264 GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 265 if (GpeEventInfo) 266 { 267 if (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) != 268 ACPI_GPE_DISPATCH_NONE) 269 { 270 Status = AcpiEvAddGpeReference (GpeEventInfo, TRUE); 271 if (ACPI_SUCCESS (Status) && 272 ACPI_GPE_IS_POLLING_NEEDED (GpeEventInfo)) 273 { 274 /* Poll edge-triggered GPEs to handle existing events */ 275 276 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 277 (void) AcpiEvDetectGpe ( 278 GpeDevice, GpeEventInfo, GpeNumber); 279 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 280 } 281 } 282 else 283 { 284 Status = AE_NO_HANDLER; 285 } 286 } 287 288 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 289 return_ACPI_STATUS (Status); 290 } 291 292 ACPI_EXPORT_SYMBOL (AcpiEnableGpe) 293 294 295 /******************************************************************************* 296 * 297 * FUNCTION: AcpiDisableGpe 298 * 299 * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1 300 * GpeNumber - GPE level within the GPE block 301 * 302 * RETURN: Status 303 * 304 * DESCRIPTION: Remove a reference to a GPE. When the last reference is 305 * removed, only then is the GPE disabled (for runtime GPEs), or 306 * the GPE mask bit disabled (for wake GPEs) 307 * 308 ******************************************************************************/ 309 310 ACPI_STATUS 311 AcpiDisableGpe ( 312 ACPI_HANDLE GpeDevice, 313 UINT32 GpeNumber) 314 { 315 ACPI_STATUS Status = AE_BAD_PARAMETER; 316 ACPI_GPE_EVENT_INFO *GpeEventInfo; 317 ACPI_CPU_FLAGS Flags; 318 319 320 ACPI_FUNCTION_TRACE (AcpiDisableGpe); 321 322 323 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 324 325 /* Ensure that we have a valid GPE number */ 326 327 GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 328 if (GpeEventInfo) 329 { 330 Status = AcpiEvRemoveGpeReference (GpeEventInfo); 331 } 332 333 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 334 return_ACPI_STATUS (Status); 335 } 336 337 ACPI_EXPORT_SYMBOL (AcpiDisableGpe) 338 339 340 /******************************************************************************* 341 * 342 * FUNCTION: AcpiSetGpe 343 * 344 * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1 345 * GpeNumber - GPE level within the GPE block 346 * Action - ACPI_GPE_ENABLE or ACPI_GPE_DISABLE 347 * 348 * RETURN: Status 349 * 350 * DESCRIPTION: Enable or disable an individual GPE. This function bypasses 351 * the reference count mechanism used in the AcpiEnableGpe(), 352 * AcpiDisableGpe() interfaces. 353 * This API is typically used by the GPE raw handler mode driver 354 * to switch between the polling mode and the interrupt mode after 355 * the driver has enabled the GPE. 356 * The APIs should be invoked in this order: 357 * AcpiEnableGpe() <- Ensure the reference count > 0 358 * AcpiSetGpe(ACPI_GPE_DISABLE) <- Enter polling mode 359 * AcpiSetGpe(ACPI_GPE_ENABLE) <- Leave polling mode 360 * AcpiDisableGpe() <- Decrease the reference count 361 * 362 * Note: If a GPE is shared by 2 silicon components, then both the drivers 363 * should support GPE polling mode or disabling the GPE for long period 364 * for one driver may break the other. So use it with care since all 365 * firmware _Lxx/_Exx handlers currently rely on the GPE interrupt mode. 366 * 367 ******************************************************************************/ 368 369 ACPI_STATUS 370 AcpiSetGpe ( 371 ACPI_HANDLE GpeDevice, 372 UINT32 GpeNumber, 373 UINT8 Action) 374 { 375 ACPI_GPE_EVENT_INFO *GpeEventInfo; 376 ACPI_STATUS Status; 377 ACPI_CPU_FLAGS Flags; 378 379 380 ACPI_FUNCTION_TRACE (AcpiSetGpe); 381 382 383 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 384 385 /* Ensure that we have a valid GPE number */ 386 387 GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 388 if (!GpeEventInfo) 389 { 390 Status = AE_BAD_PARAMETER; 391 goto UnlockAndExit; 392 } 393 394 /* Perform the action */ 395 396 switch (Action) 397 { 398 case ACPI_GPE_ENABLE: 399 400 Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_ENABLE); 401 GpeEventInfo->DisableForDispatch = FALSE; 402 break; 403 404 case ACPI_GPE_DISABLE: 405 406 Status = AcpiHwLowSetGpe (GpeEventInfo, ACPI_GPE_DISABLE); 407 GpeEventInfo->DisableForDispatch = TRUE; 408 break; 409 410 default: 411 412 Status = AE_BAD_PARAMETER; 413 break; 414 } 415 416 UnlockAndExit: 417 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 418 return_ACPI_STATUS (Status); 419 } 420 421 ACPI_EXPORT_SYMBOL (AcpiSetGpe) 422 423 424 /******************************************************************************* 425 * 426 * FUNCTION: AcpiMaskGpe 427 * 428 * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1 429 * GpeNumber - GPE level within the GPE block 430 * IsMasked - Whether the GPE is masked or not 431 * 432 * RETURN: Status 433 * 434 * DESCRIPTION: Unconditionally mask/unmask the an individual GPE, ex., to 435 * prevent a GPE flooding. 436 * 437 ******************************************************************************/ 438 439 ACPI_STATUS 440 AcpiMaskGpe ( 441 ACPI_HANDLE GpeDevice, 442 UINT32 GpeNumber, 443 BOOLEAN IsMasked) 444 { 445 ACPI_GPE_EVENT_INFO *GpeEventInfo; 446 ACPI_STATUS Status; 447 ACPI_CPU_FLAGS Flags; 448 449 450 ACPI_FUNCTION_TRACE (AcpiMaskGpe); 451 452 453 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 454 455 /* Ensure that we have a valid GPE number */ 456 457 GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 458 if (!GpeEventInfo) 459 { 460 Status = AE_BAD_PARAMETER; 461 goto UnlockAndExit; 462 } 463 464 Status = AcpiEvMaskGpe (GpeEventInfo, IsMasked); 465 466 UnlockAndExit: 467 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 468 return_ACPI_STATUS (Status); 469 } 470 471 ACPI_EXPORT_SYMBOL (AcpiMaskGpe) 472 473 474 /******************************************************************************* 475 * 476 * FUNCTION: AcpiMarkGpeForWake 477 * 478 * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1 479 * GpeNumber - GPE level within the GPE block 480 * 481 * RETURN: Status 482 * 483 * DESCRIPTION: Mark a GPE as having the ability to wake the system. Simply 484 * sets the ACPI_GPE_CAN_WAKE flag. 485 * 486 * Some potential callers of AcpiSetupGpeForWake may know in advance that 487 * there won't be any notify handlers installed for device wake notifications 488 * from the given GPE (one example is a button GPE in Linux). For these cases, 489 * AcpiMarkGpeForWake should be used instead of AcpiSetupGpeForWake. 490 * This will set the ACPI_GPE_CAN_WAKE flag for the GPE without trying to 491 * setup implicit wake notification for it (since there's no handler method). 492 * 493 ******************************************************************************/ 494 495 ACPI_STATUS 496 AcpiMarkGpeForWake ( 497 ACPI_HANDLE GpeDevice, 498 UINT32 GpeNumber) 499 { 500 ACPI_GPE_EVENT_INFO *GpeEventInfo; 501 ACPI_STATUS Status = AE_BAD_PARAMETER; 502 ACPI_CPU_FLAGS Flags; 503 504 505 ACPI_FUNCTION_TRACE (AcpiMarkGpeForWake); 506 507 508 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 509 510 /* Ensure that we have a valid GPE number */ 511 512 GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 513 if (GpeEventInfo) 514 { 515 /* Mark the GPE as a possible wake event */ 516 517 GpeEventInfo->Flags |= ACPI_GPE_CAN_WAKE; 518 Status = AE_OK; 519 } 520 521 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 522 return_ACPI_STATUS (Status); 523 } 524 525 ACPI_EXPORT_SYMBOL (AcpiMarkGpeForWake) 526 527 528 /******************************************************************************* 529 * 530 * FUNCTION: AcpiSetupGpeForWake 531 * 532 * PARAMETERS: WakeDevice - Device associated with the GPE (via _PRW) 533 * GpeDevice - Parent GPE Device. NULL for GPE0/GPE1 534 * GpeNumber - GPE level within the GPE block 535 * 536 * RETURN: Status 537 * 538 * DESCRIPTION: Mark a GPE as having the ability to wake the system. This 539 * interface is intended to be used as the host executes the 540 * _PRW methods (Power Resources for Wake) in the system tables. 541 * Each _PRW appears under a Device Object (The WakeDevice), and 542 * contains the info for the wake GPE associated with the 543 * WakeDevice. 544 * 545 ******************************************************************************/ 546 547 ACPI_STATUS 548 AcpiSetupGpeForWake ( 549 ACPI_HANDLE WakeDevice, 550 ACPI_HANDLE GpeDevice, 551 UINT32 GpeNumber) 552 { 553 ACPI_STATUS Status; 554 ACPI_GPE_EVENT_INFO *GpeEventInfo; 555 ACPI_NAMESPACE_NODE *DeviceNode; 556 ACPI_GPE_NOTIFY_INFO *Notify; 557 ACPI_GPE_NOTIFY_INFO *NewNotify; 558 ACPI_CPU_FLAGS Flags; 559 560 561 ACPI_FUNCTION_TRACE (AcpiSetupGpeForWake); 562 563 564 /* Parameter Validation */ 565 566 if (!WakeDevice) 567 { 568 /* 569 * By forcing WakeDevice to be valid, we automatically enable the 570 * implicit notify feature on all hosts. 571 */ 572 return_ACPI_STATUS (AE_BAD_PARAMETER); 573 } 574 575 /* Handle root object case */ 576 577 if (WakeDevice == ACPI_ROOT_OBJECT) 578 { 579 DeviceNode = AcpiGbl_RootNode; 580 } 581 else 582 { 583 DeviceNode = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, WakeDevice); 584 } 585 586 /* Validate WakeDevice is of type Device */ 587 588 if (DeviceNode->Type != ACPI_TYPE_DEVICE) 589 { 590 return_ACPI_STATUS (AE_BAD_PARAMETER); 591 } 592 593 /* 594 * Allocate a new notify object up front, in case it is needed. 595 * Memory allocation while holding a spinlock is a big no-no 596 * on some hosts. 597 */ 598 NewNotify = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_GPE_NOTIFY_INFO)); 599 if (!NewNotify) 600 { 601 return_ACPI_STATUS (AE_NO_MEMORY); 602 } 603 604 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 605 606 /* Ensure that we have a valid GPE number */ 607 608 GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 609 if (!GpeEventInfo) 610 { 611 Status = AE_BAD_PARAMETER; 612 goto UnlockAndExit; 613 } 614 615 /* 616 * If there is no method or handler for this GPE, then the 617 * WakeDevice will be notified whenever this GPE fires. This is 618 * known as an "implicit notify". Note: The GPE is assumed to be 619 * level-triggered (for windows compatibility). 620 */ 621 if (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) == 622 ACPI_GPE_DISPATCH_NONE) 623 { 624 /* 625 * This is the first device for implicit notify on this GPE. 626 * Just set the flags here, and enter the NOTIFY block below. 627 */ 628 GpeEventInfo->Flags = 629 (ACPI_GPE_DISPATCH_NOTIFY | ACPI_GPE_LEVEL_TRIGGERED); 630 } 631 else if (GpeEventInfo->Flags & ACPI_GPE_AUTO_ENABLED) 632 { 633 /* 634 * A reference to this GPE has been added during the GPE block 635 * initialization, so drop it now to prevent the GPE from being 636 * permanently enabled and clear its ACPI_GPE_AUTO_ENABLED flag. 637 */ 638 (void) AcpiEvRemoveGpeReference (GpeEventInfo); 639 GpeEventInfo->Flags &= ~~ACPI_GPE_AUTO_ENABLED; 640 } 641 642 /* 643 * If we already have an implicit notify on this GPE, add 644 * this device to the notify list. 645 */ 646 if (ACPI_GPE_DISPATCH_TYPE (GpeEventInfo->Flags) == 647 ACPI_GPE_DISPATCH_NOTIFY) 648 { 649 /* Ensure that the device is not already in the list */ 650 651 Notify = GpeEventInfo->Dispatch.NotifyList; 652 while (Notify) 653 { 654 if (Notify->DeviceNode == DeviceNode) 655 { 656 Status = AE_ALREADY_EXISTS; 657 goto UnlockAndExit; 658 } 659 Notify = Notify->Next; 660 } 661 662 /* Add this device to the notify list for this GPE */ 663 664 NewNotify->DeviceNode = DeviceNode; 665 NewNotify->Next = GpeEventInfo->Dispatch.NotifyList; 666 GpeEventInfo->Dispatch.NotifyList = NewNotify; 667 NewNotify = NULL; 668 } 669 670 /* Mark the GPE as a possible wake event */ 671 672 GpeEventInfo->Flags |= ACPI_GPE_CAN_WAKE; 673 Status = AE_OK; 674 675 676 UnlockAndExit: 677 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 678 679 /* Delete the notify object if it was not used above */ 680 681 if (NewNotify) 682 { 683 ACPI_FREE (NewNotify); 684 } 685 return_ACPI_STATUS (Status); 686 } 687 688 ACPI_EXPORT_SYMBOL (AcpiSetupGpeForWake) 689 690 691 /******************************************************************************* 692 * 693 * FUNCTION: AcpiSetGpeWakeMask 694 * 695 * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1 696 * GpeNumber - GPE level within the GPE block 697 * Action - Enable or Disable 698 * 699 * RETURN: Status 700 * 701 * DESCRIPTION: Set or clear the GPE's wakeup enable mask bit. The GPE must 702 * already be marked as a WAKE GPE. 703 * 704 ******************************************************************************/ 705 706 ACPI_STATUS 707 AcpiSetGpeWakeMask ( 708 ACPI_HANDLE GpeDevice, 709 UINT32 GpeNumber, 710 UINT8 Action) 711 { 712 ACPI_STATUS Status = AE_OK; 713 ACPI_GPE_EVENT_INFO *GpeEventInfo; 714 ACPI_GPE_REGISTER_INFO *GpeRegisterInfo; 715 ACPI_CPU_FLAGS Flags; 716 UINT32 RegisterBit; 717 718 719 ACPI_FUNCTION_TRACE (AcpiSetGpeWakeMask); 720 721 722 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 723 724 /* 725 * Ensure that we have a valid GPE number and that this GPE is in 726 * fact a wake GPE 727 */ 728 GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 729 if (!GpeEventInfo) 730 { 731 Status = AE_BAD_PARAMETER; 732 goto UnlockAndExit; 733 } 734 735 if (!(GpeEventInfo->Flags & ACPI_GPE_CAN_WAKE)) 736 { 737 Status = AE_TYPE; 738 goto UnlockAndExit; 739 } 740 741 GpeRegisterInfo = GpeEventInfo->RegisterInfo; 742 if (!GpeRegisterInfo) 743 { 744 Status = AE_NOT_EXIST; 745 goto UnlockAndExit; 746 } 747 748 RegisterBit = AcpiHwGetGpeRegisterBit (GpeEventInfo); 749 750 /* Perform the action */ 751 752 switch (Action) 753 { 754 case ACPI_GPE_ENABLE: 755 756 ACPI_SET_BIT (GpeRegisterInfo->EnableForWake, (UINT8) RegisterBit); 757 break; 758 759 case ACPI_GPE_DISABLE: 760 761 ACPI_CLEAR_BIT (GpeRegisterInfo->EnableForWake, (UINT8) RegisterBit); 762 break; 763 764 default: 765 766 ACPI_ERROR ((AE_INFO, "%u, Invalid action", Action)); 767 Status = AE_BAD_PARAMETER; 768 break; 769 } 770 771 UnlockAndExit: 772 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 773 return_ACPI_STATUS (Status); 774 } 775 776 ACPI_EXPORT_SYMBOL (AcpiSetGpeWakeMask) 777 778 779 /******************************************************************************* 780 * 781 * FUNCTION: AcpiClearGpe 782 * 783 * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1 784 * GpeNumber - GPE level within the GPE block 785 * 786 * RETURN: Status 787 * 788 * DESCRIPTION: Clear an ACPI event (general purpose) 789 * 790 ******************************************************************************/ 791 792 ACPI_STATUS 793 AcpiClearGpe ( 794 ACPI_HANDLE GpeDevice, 795 UINT32 GpeNumber) 796 { 797 ACPI_STATUS Status = AE_OK; 798 ACPI_GPE_EVENT_INFO *GpeEventInfo; 799 ACPI_CPU_FLAGS Flags; 800 801 802 ACPI_FUNCTION_TRACE (AcpiClearGpe); 803 804 805 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 806 807 /* Ensure that we have a valid GPE number */ 808 809 GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 810 if (!GpeEventInfo) 811 { 812 Status = AE_BAD_PARAMETER; 813 goto UnlockAndExit; 814 } 815 816 Status = AcpiHwClearGpe (GpeEventInfo); 817 818 UnlockAndExit: 819 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 820 return_ACPI_STATUS (Status); 821 } 822 823 ACPI_EXPORT_SYMBOL (AcpiClearGpe) 824 825 826 /******************************************************************************* 827 * 828 * FUNCTION: AcpiGetGpeStatus 829 * 830 * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1 831 * GpeNumber - GPE level within the GPE block 832 * EventStatus - Where the current status of the event 833 * will be returned 834 * 835 * RETURN: Status 836 * 837 * DESCRIPTION: Get the current status of a GPE (signalled/not_signalled) 838 * 839 ******************************************************************************/ 840 841 ACPI_STATUS 842 AcpiGetGpeStatus ( 843 ACPI_HANDLE GpeDevice, 844 UINT32 GpeNumber, 845 ACPI_EVENT_STATUS *EventStatus) 846 { 847 ACPI_STATUS Status = AE_OK; 848 ACPI_GPE_EVENT_INFO *GpeEventInfo; 849 ACPI_CPU_FLAGS Flags; 850 851 852 ACPI_FUNCTION_TRACE (AcpiGetGpeStatus); 853 854 855 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 856 857 /* Ensure that we have a valid GPE number */ 858 859 GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 860 if (!GpeEventInfo) 861 { 862 Status = AE_BAD_PARAMETER; 863 goto UnlockAndExit; 864 } 865 866 /* Obtain status on the requested GPE number */ 867 868 Status = AcpiHwGetGpeStatus (GpeEventInfo, EventStatus); 869 870 UnlockAndExit: 871 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 872 return_ACPI_STATUS (Status); 873 } 874 875 ACPI_EXPORT_SYMBOL (AcpiGetGpeStatus) 876 877 878 /******************************************************************************* 879 * 880 * FUNCTION: AcpiDispatchGpe 881 * 882 * PARAMETERS: GpeDevice - Parent GPE Device. NULL for GPE0/GPE1 883 * GpeNumber - GPE level within the GPE block 884 * 885 * RETURN: INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED 886 * 887 * DESCRIPTION: Detect and dispatch a General Purpose Event to either a function 888 * (e.g. EC) or method (e.g. _Lxx/_Exx) handler. 889 * 890 ******************************************************************************/ 891 892 UINT32 893 AcpiDispatchGpe( 894 ACPI_HANDLE GpeDevice, 895 UINT32 GpeNumber) 896 { 897 ACPI_FUNCTION_TRACE(acpi_dispatch_gpe); 898 899 return (AcpiEvDetectGpe (GpeDevice, NULL, GpeNumber)); 900 } 901 902 ACPI_EXPORT_SYMBOL (AcpiDispatchGpe) 903 904 905 /******************************************************************************* 906 * 907 * FUNCTION: AcpiFinishGpe 908 * 909 * PARAMETERS: GpeDevice - Namespace node for the GPE Block 910 * (NULL for FADT defined GPEs) 911 * GpeNumber - GPE level within the GPE block 912 * 913 * RETURN: Status 914 * 915 * DESCRIPTION: Clear and conditionally re-enable a GPE. This completes the GPE 916 * processing. Intended for use by asynchronous host-installed 917 * GPE handlers. The GPE is only re-enabled if the EnableForRun bit 918 * is set in the GPE info. 919 * 920 ******************************************************************************/ 921 922 ACPI_STATUS 923 AcpiFinishGpe ( 924 ACPI_HANDLE GpeDevice, 925 UINT32 GpeNumber) 926 { 927 ACPI_GPE_EVENT_INFO *GpeEventInfo; 928 ACPI_STATUS Status; 929 ACPI_CPU_FLAGS Flags; 930 931 932 ACPI_FUNCTION_TRACE (AcpiFinishGpe); 933 934 935 Flags = AcpiOsAcquireLock (AcpiGbl_GpeLock); 936 937 /* Ensure that we have a valid GPE number */ 938 939 GpeEventInfo = AcpiEvGetGpeEventInfo (GpeDevice, GpeNumber); 940 if (!GpeEventInfo) 941 { 942 Status = AE_BAD_PARAMETER; 943 goto UnlockAndExit; 944 } 945 946 Status = AcpiEvFinishGpe (GpeEventInfo); 947 948 UnlockAndExit: 949 AcpiOsReleaseLock (AcpiGbl_GpeLock, Flags); 950 return_ACPI_STATUS (Status); 951 } 952 953 ACPI_EXPORT_SYMBOL (AcpiFinishGpe) 954 955 956 /****************************************************************************** 957 * 958 * FUNCTION: AcpiDisableAllGpes 959 * 960 * PARAMETERS: None 961 * 962 * RETURN: Status 963 * 964 * DESCRIPTION: Disable and clear all GPEs in all GPE blocks 965 * 966 ******************************************************************************/ 967 968 ACPI_STATUS 969 AcpiDisableAllGpes ( 970 void) 971 { 972 ACPI_STATUS Status; 973 974 975 ACPI_FUNCTION_TRACE (AcpiDisableAllGpes); 976 977 978 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 979 if (ACPI_FAILURE (Status)) 980 { 981 return_ACPI_STATUS (Status); 982 } 983 984 Status = AcpiHwDisableAllGpes (); 985 (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 986 987 return_ACPI_STATUS (Status); 988 } 989 990 ACPI_EXPORT_SYMBOL (AcpiDisableAllGpes) 991 992 993 /****************************************************************************** 994 * 995 * FUNCTION: AcpiEnableAllRuntimeGpes 996 * 997 * PARAMETERS: None 998 * 999 * RETURN: Status 1000 * 1001 * DESCRIPTION: Enable all "runtime" GPEs, in all GPE blocks 1002 * 1003 ******************************************************************************/ 1004 1005 ACPI_STATUS 1006 AcpiEnableAllRuntimeGpes ( 1007 void) 1008 { 1009 ACPI_STATUS Status; 1010 1011 1012 ACPI_FUNCTION_TRACE (AcpiEnableAllRuntimeGpes); 1013 1014 1015 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 1016 if (ACPI_FAILURE (Status)) 1017 { 1018 return_ACPI_STATUS (Status); 1019 } 1020 1021 Status = AcpiHwEnableAllRuntimeGpes (); 1022 (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 1023 1024 return_ACPI_STATUS (Status); 1025 } 1026 1027 ACPI_EXPORT_SYMBOL (AcpiEnableAllRuntimeGpes) 1028 1029 1030 /****************************************************************************** 1031 * 1032 * FUNCTION: AcpiEnableAllWakeupGpes 1033 * 1034 * PARAMETERS: None 1035 * 1036 * RETURN: Status 1037 * 1038 * DESCRIPTION: Enable all "wakeup" GPEs and disable all of the other GPEs, in 1039 * all GPE blocks. 1040 * 1041 ******************************************************************************/ 1042 1043 ACPI_STATUS 1044 AcpiEnableAllWakeupGpes ( 1045 void) 1046 { 1047 ACPI_STATUS Status; 1048 1049 1050 ACPI_FUNCTION_TRACE (AcpiEnableAllWakeupGpes); 1051 1052 1053 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 1054 if (ACPI_FAILURE (Status)) 1055 { 1056 return_ACPI_STATUS (Status); 1057 } 1058 1059 Status = AcpiHwEnableAllWakeupGpes (); 1060 (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 1061 1062 return_ACPI_STATUS (Status); 1063 } 1064 1065 ACPI_EXPORT_SYMBOL (AcpiEnableAllWakeupGpes) 1066 1067 1068 /****************************************************************************** 1069 * 1070 * FUNCTION: AcpiAnyGpeStatusSet 1071 * 1072 * PARAMETERS: None 1073 * 1074 * RETURN: Whether or not the status bit is set for any GPE 1075 * 1076 * DESCRIPTION: Check the status bits of all enabled GPEs and return TRUE if any 1077 * of them is set or FALSE otherwise. 1078 * 1079 ******************************************************************************/ 1080 1081 UINT32 1082 AcpiAnyGpeStatusSet ( 1083 void) 1084 { 1085 ACPI_STATUS Status; 1086 UINT8 Ret; 1087 1088 1089 ACPI_FUNCTION_TRACE (AcpiAnyGpeStatusSet); 1090 1091 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 1092 if (ACPI_FAILURE (Status)) 1093 { 1094 return (FALSE); 1095 } 1096 1097 Ret = AcpiHwCheckAllGpes (); 1098 (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 1099 1100 return (Ret); 1101 } 1102 1103 ACPI_EXPORT_SYMBOL(AcpiAnyGpeStatusSet) 1104 1105 1106 /******************************************************************************* 1107 * 1108 * FUNCTION: AcpiInstallGpeBlock 1109 * 1110 * PARAMETERS: GpeDevice - Handle to the parent GPE Block Device 1111 * GpeBlockAddress - Address and SpaceID 1112 * RegisterCount - Number of GPE register pairs in the block 1113 * InterruptNumber - H/W interrupt for the block 1114 * 1115 * RETURN: Status 1116 * 1117 * DESCRIPTION: Create and Install a block of GPE registers. The GPEs are not 1118 * enabled here. 1119 * 1120 ******************************************************************************/ 1121 1122 ACPI_STATUS 1123 AcpiInstallGpeBlock ( 1124 ACPI_HANDLE GpeDevice, 1125 ACPI_GENERIC_ADDRESS *GpeBlockAddress, 1126 UINT32 RegisterCount, 1127 UINT32 InterruptNumber) 1128 { 1129 ACPI_STATUS Status; 1130 ACPI_OPERAND_OBJECT *ObjDesc; 1131 ACPI_NAMESPACE_NODE *Node; 1132 ACPI_GPE_BLOCK_INFO *GpeBlock; 1133 1134 1135 ACPI_FUNCTION_TRACE (AcpiInstallGpeBlock); 1136 1137 1138 if ((!GpeDevice) || 1139 (!GpeBlockAddress) || 1140 (!RegisterCount)) 1141 { 1142 return_ACPI_STATUS (AE_BAD_PARAMETER); 1143 } 1144 1145 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 1146 if (ACPI_FAILURE (Status)) 1147 { 1148 return_ACPI_STATUS (Status); 1149 } 1150 1151 Node = AcpiNsValidateHandle (GpeDevice); 1152 if (!Node) 1153 { 1154 Status = AE_BAD_PARAMETER; 1155 goto UnlockAndExit; 1156 } 1157 1158 /* Validate the parent device */ 1159 1160 if (Node->Type != ACPI_TYPE_DEVICE) 1161 { 1162 Status = AE_TYPE; 1163 goto UnlockAndExit; 1164 } 1165 1166 if (Node->Object) 1167 { 1168 Status = AE_ALREADY_EXISTS; 1169 goto UnlockAndExit; 1170 } 1171 1172 /* 1173 * For user-installed GPE Block Devices, the GpeBlockBaseNumber 1174 * is always zero 1175 */ 1176 Status = AcpiEvCreateGpeBlock (Node, GpeBlockAddress->Address, 1177 GpeBlockAddress->SpaceId, RegisterCount, 1178 0, InterruptNumber, &GpeBlock); 1179 if (ACPI_FAILURE (Status)) 1180 { 1181 goto UnlockAndExit; 1182 } 1183 1184 /* Install block in the DeviceObject attached to the node */ 1185 1186 ObjDesc = AcpiNsGetAttachedObject (Node); 1187 if (!ObjDesc) 1188 { 1189 /* 1190 * No object, create a new one (Device nodes do not always have 1191 * an attached object) 1192 */ 1193 ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_DEVICE); 1194 if (!ObjDesc) 1195 { 1196 Status = AE_NO_MEMORY; 1197 goto UnlockAndExit; 1198 } 1199 1200 Status = AcpiNsAttachObject (Node, ObjDesc, ACPI_TYPE_DEVICE); 1201 1202 /* Remove local reference to the object */ 1203 1204 AcpiUtRemoveReference (ObjDesc); 1205 if (ACPI_FAILURE (Status)) 1206 { 1207 goto UnlockAndExit; 1208 } 1209 } 1210 1211 /* Now install the GPE block in the DeviceObject */ 1212 1213 ObjDesc->Device.GpeBlock = GpeBlock; 1214 1215 1216 UnlockAndExit: 1217 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 1218 return_ACPI_STATUS (Status); 1219 } 1220 1221 ACPI_EXPORT_SYMBOL (AcpiInstallGpeBlock) 1222 1223 1224 /******************************************************************************* 1225 * 1226 * FUNCTION: AcpiRemoveGpeBlock 1227 * 1228 * PARAMETERS: GpeDevice - Handle to the parent GPE Block Device 1229 * 1230 * RETURN: Status 1231 * 1232 * DESCRIPTION: Remove a previously installed block of GPE registers 1233 * 1234 ******************************************************************************/ 1235 1236 ACPI_STATUS 1237 AcpiRemoveGpeBlock ( 1238 ACPI_HANDLE GpeDevice) 1239 { 1240 ACPI_OPERAND_OBJECT *ObjDesc; 1241 ACPI_STATUS Status; 1242 ACPI_NAMESPACE_NODE *Node; 1243 1244 1245 ACPI_FUNCTION_TRACE (AcpiRemoveGpeBlock); 1246 1247 1248 if (!GpeDevice) 1249 { 1250 return_ACPI_STATUS (AE_BAD_PARAMETER); 1251 } 1252 1253 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 1254 if (ACPI_FAILURE (Status)) 1255 { 1256 return_ACPI_STATUS (Status); 1257 } 1258 1259 Node = AcpiNsValidateHandle (GpeDevice); 1260 if (!Node) 1261 { 1262 Status = AE_BAD_PARAMETER; 1263 goto UnlockAndExit; 1264 } 1265 1266 /* Validate the parent device */ 1267 1268 if (Node->Type != ACPI_TYPE_DEVICE) 1269 { 1270 Status = AE_TYPE; 1271 goto UnlockAndExit; 1272 } 1273 1274 /* Get the DeviceObject attached to the node */ 1275 1276 ObjDesc = AcpiNsGetAttachedObject (Node); 1277 if (!ObjDesc || 1278 !ObjDesc->Device.GpeBlock) 1279 { 1280 return_ACPI_STATUS (AE_NULL_OBJECT); 1281 } 1282 1283 /* Delete the GPE block (but not the DeviceObject) */ 1284 1285 Status = AcpiEvDeleteGpeBlock (ObjDesc->Device.GpeBlock); 1286 if (ACPI_SUCCESS (Status)) 1287 { 1288 ObjDesc->Device.GpeBlock = NULL; 1289 } 1290 1291 UnlockAndExit: 1292 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 1293 return_ACPI_STATUS (Status); 1294 } 1295 1296 ACPI_EXPORT_SYMBOL (AcpiRemoveGpeBlock) 1297 1298 1299 /******************************************************************************* 1300 * 1301 * FUNCTION: AcpiGetGpeDevice 1302 * 1303 * PARAMETERS: Index - System GPE index (0-CurrentGpeCount) 1304 * GpeDevice - Where the parent GPE Device is returned 1305 * 1306 * RETURN: Status 1307 * 1308 * DESCRIPTION: Obtain the GPE device associated with the input index. A NULL 1309 * gpe device indicates that the gpe number is contained in one of 1310 * the FADT-defined gpe blocks. Otherwise, the GPE block device. 1311 * 1312 ******************************************************************************/ 1313 1314 ACPI_STATUS 1315 AcpiGetGpeDevice ( 1316 UINT32 Index, 1317 ACPI_HANDLE *GpeDevice) 1318 { 1319 ACPI_GPE_DEVICE_INFO Info; 1320 ACPI_STATUS Status; 1321 1322 1323 ACPI_FUNCTION_TRACE (AcpiGetGpeDevice); 1324 1325 1326 if (!GpeDevice) 1327 { 1328 return_ACPI_STATUS (AE_BAD_PARAMETER); 1329 } 1330 1331 if (Index >= AcpiCurrentGpeCount) 1332 { 1333 return_ACPI_STATUS (AE_NOT_EXIST); 1334 } 1335 1336 /* Setup and walk the GPE list */ 1337 1338 Info.Index = Index; 1339 Info.Status = AE_NOT_EXIST; 1340 Info.GpeDevice = NULL; 1341 Info.NextBlockBaseIndex = 0; 1342 1343 Status = AcpiEvWalkGpeList (AcpiEvGetGpeDevice, &Info); 1344 if (ACPI_FAILURE (Status)) 1345 { 1346 return_ACPI_STATUS (Status); 1347 } 1348 1349 *GpeDevice = ACPI_CAST_PTR (ACPI_HANDLE, Info.GpeDevice); 1350 return_ACPI_STATUS (Info.Status); 1351 } 1352 1353 ACPI_EXPORT_SYMBOL (AcpiGetGpeDevice) 1354 1355 #endif /* !ACPI_REDUCED_HARDWARE */ 1356