1 /****************************************************************************** 2 * 3 * Module Name: hwgpe - Low level GPE enable/disable/clear functions 4 * 5 *****************************************************************************/ 6 7 /****************************************************************************** 8 * 9 * 1. Copyright Notice 10 * 11 * Some or all of this work - Copyright (c) 1999 - 2012, 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 #include "acpi.h" 117 #include "accommon.h" 118 #include "acevents.h" 119 120 #define _COMPONENT ACPI_HARDWARE 121 ACPI_MODULE_NAME ("hwgpe") 122 123 #if (!ACPI_REDUCED_HARDWARE) /* Entire module */ 124 125 /* Local prototypes */ 126 127 static ACPI_STATUS 128 AcpiHwEnableWakeupGpeBlock ( 129 ACPI_GPE_XRUPT_INFO *GpeXruptInfo, 130 ACPI_GPE_BLOCK_INFO *GpeBlock, 131 void *Context); 132 133 134 /****************************************************************************** 135 * 136 * FUNCTION: AcpiHwGetGpeRegisterBit 137 * 138 * PARAMETERS: GpeEventInfo - Info block for the GPE 139 * 140 * RETURN: Register mask with a one in the GPE bit position 141 * 142 * DESCRIPTION: Compute the register mask for this GPE. One bit is set in the 143 * correct position for the input GPE. 144 * 145 ******************************************************************************/ 146 147 UINT32 148 AcpiHwGetGpeRegisterBit ( 149 ACPI_GPE_EVENT_INFO *GpeEventInfo) 150 { 151 152 return ((UINT32) 1 << 153 (GpeEventInfo->GpeNumber - GpeEventInfo->RegisterInfo->BaseGpeNumber)); 154 } 155 156 157 /****************************************************************************** 158 * 159 * FUNCTION: AcpiHwLowSetGpe 160 * 161 * PARAMETERS: GpeEventInfo - Info block for the GPE to be disabled 162 * Action - Enable or disable 163 * 164 * RETURN: Status 165 * 166 * DESCRIPTION: Enable or disable a single GPE in the parent enable register. 167 * 168 ******************************************************************************/ 169 170 ACPI_STATUS 171 AcpiHwLowSetGpe ( 172 ACPI_GPE_EVENT_INFO *GpeEventInfo, 173 UINT32 Action) 174 { 175 ACPI_GPE_REGISTER_INFO *GpeRegisterInfo; 176 ACPI_STATUS Status; 177 UINT32 EnableMask; 178 UINT32 RegisterBit; 179 180 181 ACPI_FUNCTION_ENTRY (); 182 183 184 /* Get the info block for the entire GPE register */ 185 186 GpeRegisterInfo = GpeEventInfo->RegisterInfo; 187 if (!GpeRegisterInfo) 188 { 189 return (AE_NOT_EXIST); 190 } 191 192 /* Get current value of the enable register that contains this GPE */ 193 194 Status = AcpiHwRead (&EnableMask, &GpeRegisterInfo->EnableAddress); 195 if (ACPI_FAILURE (Status)) 196 { 197 return (Status); 198 } 199 200 /* Set or clear just the bit that corresponds to this GPE */ 201 202 RegisterBit = AcpiHwGetGpeRegisterBit (GpeEventInfo); 203 switch (Action) 204 { 205 case ACPI_GPE_CONDITIONAL_ENABLE: 206 207 /* Only enable if the EnableForRun bit is set */ 208 209 if (!(RegisterBit & GpeRegisterInfo->EnableForRun)) 210 { 211 return (AE_BAD_PARAMETER); 212 } 213 214 /*lint -fallthrough */ 215 216 case ACPI_GPE_ENABLE: 217 ACPI_SET_BIT (EnableMask, RegisterBit); 218 break; 219 220 case ACPI_GPE_DISABLE: 221 ACPI_CLEAR_BIT (EnableMask, RegisterBit); 222 break; 223 224 default: 225 ACPI_ERROR ((AE_INFO, "Invalid GPE Action, %u\n", Action)); 226 return (AE_BAD_PARAMETER); 227 } 228 229 /* Write the updated enable mask */ 230 231 Status = AcpiHwWrite (EnableMask, &GpeRegisterInfo->EnableAddress); 232 return (Status); 233 } 234 235 236 /****************************************************************************** 237 * 238 * FUNCTION: AcpiHwClearGpe 239 * 240 * PARAMETERS: GpeEventInfo - Info block for the GPE to be cleared 241 * 242 * RETURN: Status 243 * 244 * DESCRIPTION: Clear the status bit for a single GPE. 245 * 246 ******************************************************************************/ 247 248 ACPI_STATUS 249 AcpiHwClearGpe ( 250 ACPI_GPE_EVENT_INFO *GpeEventInfo) 251 { 252 ACPI_GPE_REGISTER_INFO *GpeRegisterInfo; 253 ACPI_STATUS Status; 254 UINT32 RegisterBit; 255 256 257 ACPI_FUNCTION_ENTRY (); 258 259 /* Get the info block for the entire GPE register */ 260 261 GpeRegisterInfo = GpeEventInfo->RegisterInfo; 262 if (!GpeRegisterInfo) 263 { 264 return (AE_NOT_EXIST); 265 } 266 267 /* 268 * Write a one to the appropriate bit in the status register to 269 * clear this GPE. 270 */ 271 RegisterBit = AcpiHwGetGpeRegisterBit (GpeEventInfo); 272 273 Status = AcpiHwWrite (RegisterBit, 274 &GpeRegisterInfo->StatusAddress); 275 276 return (Status); 277 } 278 279 280 /****************************************************************************** 281 * 282 * FUNCTION: AcpiHwGetGpeStatus 283 * 284 * PARAMETERS: GpeEventInfo - Info block for the GPE to queried 285 * EventStatus - Where the GPE status is returned 286 * 287 * RETURN: Status 288 * 289 * DESCRIPTION: Return the status of a single GPE. 290 * 291 ******************************************************************************/ 292 293 ACPI_STATUS 294 AcpiHwGetGpeStatus ( 295 ACPI_GPE_EVENT_INFO *GpeEventInfo, 296 ACPI_EVENT_STATUS *EventStatus) 297 { 298 UINT32 InByte; 299 UINT32 RegisterBit; 300 ACPI_GPE_REGISTER_INFO *GpeRegisterInfo; 301 ACPI_EVENT_STATUS LocalEventStatus = 0; 302 ACPI_STATUS Status; 303 304 305 ACPI_FUNCTION_ENTRY (); 306 307 308 if (!EventStatus) 309 { 310 return (AE_BAD_PARAMETER); 311 } 312 313 /* Get the info block for the entire GPE register */ 314 315 GpeRegisterInfo = GpeEventInfo->RegisterInfo; 316 317 /* Get the register bitmask for this GPE */ 318 319 RegisterBit = AcpiHwGetGpeRegisterBit (GpeEventInfo); 320 321 /* GPE currently enabled? (enabled for runtime?) */ 322 323 if (RegisterBit & GpeRegisterInfo->EnableForRun) 324 { 325 LocalEventStatus |= ACPI_EVENT_FLAG_ENABLED; 326 } 327 328 /* GPE enabled for wake? */ 329 330 if (RegisterBit & GpeRegisterInfo->EnableForWake) 331 { 332 LocalEventStatus |= ACPI_EVENT_FLAG_WAKE_ENABLED; 333 } 334 335 /* GPE currently active (status bit == 1)? */ 336 337 Status = AcpiHwRead (&InByte, &GpeRegisterInfo->StatusAddress); 338 if (ACPI_FAILURE (Status)) 339 { 340 return (Status); 341 } 342 343 if (RegisterBit & InByte) 344 { 345 LocalEventStatus |= ACPI_EVENT_FLAG_SET; 346 } 347 348 /* Set return value */ 349 350 (*EventStatus) = LocalEventStatus; 351 return (AE_OK); 352 } 353 354 355 /****************************************************************************** 356 * 357 * FUNCTION: AcpiHwDisableGpeBlock 358 * 359 * PARAMETERS: GpeXruptInfo - GPE Interrupt info 360 * GpeBlock - Gpe Block info 361 * 362 * RETURN: Status 363 * 364 * DESCRIPTION: Disable all GPEs within a single GPE block 365 * 366 ******************************************************************************/ 367 368 ACPI_STATUS 369 AcpiHwDisableGpeBlock ( 370 ACPI_GPE_XRUPT_INFO *GpeXruptInfo, 371 ACPI_GPE_BLOCK_INFO *GpeBlock, 372 void *Context) 373 { 374 UINT32 i; 375 ACPI_STATUS Status; 376 377 378 /* Examine each GPE Register within the block */ 379 380 for (i = 0; i < GpeBlock->RegisterCount; i++) 381 { 382 /* Disable all GPEs in this register */ 383 384 Status = AcpiHwWrite (0x00, &GpeBlock->RegisterInfo[i].EnableAddress); 385 if (ACPI_FAILURE (Status)) 386 { 387 return (Status); 388 } 389 } 390 391 return (AE_OK); 392 } 393 394 395 /****************************************************************************** 396 * 397 * FUNCTION: AcpiHwClearGpeBlock 398 * 399 * PARAMETERS: GpeXruptInfo - GPE Interrupt info 400 * GpeBlock - Gpe Block info 401 * 402 * RETURN: Status 403 * 404 * DESCRIPTION: Clear status bits for all GPEs within a single GPE block 405 * 406 ******************************************************************************/ 407 408 ACPI_STATUS 409 AcpiHwClearGpeBlock ( 410 ACPI_GPE_XRUPT_INFO *GpeXruptInfo, 411 ACPI_GPE_BLOCK_INFO *GpeBlock, 412 void *Context) 413 { 414 UINT32 i; 415 ACPI_STATUS Status; 416 417 418 /* Examine each GPE Register within the block */ 419 420 for (i = 0; i < GpeBlock->RegisterCount; i++) 421 { 422 /* Clear status on all GPEs in this register */ 423 424 Status = AcpiHwWrite (0xFF, &GpeBlock->RegisterInfo[i].StatusAddress); 425 if (ACPI_FAILURE (Status)) 426 { 427 return (Status); 428 } 429 } 430 431 return (AE_OK); 432 } 433 434 435 /****************************************************************************** 436 * 437 * FUNCTION: AcpiHwEnableRuntimeGpeBlock 438 * 439 * PARAMETERS: GpeXruptInfo - GPE Interrupt info 440 * GpeBlock - Gpe Block info 441 * 442 * RETURN: Status 443 * 444 * DESCRIPTION: Enable all "runtime" GPEs within a single GPE block. Includes 445 * combination wake/run GPEs. 446 * 447 ******************************************************************************/ 448 449 ACPI_STATUS 450 AcpiHwEnableRuntimeGpeBlock ( 451 ACPI_GPE_XRUPT_INFO *GpeXruptInfo, 452 ACPI_GPE_BLOCK_INFO *GpeBlock, 453 void *Context) 454 { 455 UINT32 i; 456 ACPI_STATUS Status; 457 458 459 /* NOTE: assumes that all GPEs are currently disabled */ 460 461 /* Examine each GPE Register within the block */ 462 463 for (i = 0; i < GpeBlock->RegisterCount; i++) 464 { 465 if (!GpeBlock->RegisterInfo[i].EnableForRun) 466 { 467 continue; 468 } 469 470 /* Enable all "runtime" GPEs in this register */ 471 472 Status = AcpiHwWrite (GpeBlock->RegisterInfo[i].EnableForRun, 473 &GpeBlock->RegisterInfo[i].EnableAddress); 474 if (ACPI_FAILURE (Status)) 475 { 476 return (Status); 477 } 478 } 479 480 return (AE_OK); 481 } 482 483 484 /****************************************************************************** 485 * 486 * FUNCTION: AcpiHwEnableWakeupGpeBlock 487 * 488 * PARAMETERS: GpeXruptInfo - GPE Interrupt info 489 * GpeBlock - Gpe Block info 490 * 491 * RETURN: Status 492 * 493 * DESCRIPTION: Enable all "wake" GPEs within a single GPE block. Includes 494 * combination wake/run GPEs. 495 * 496 ******************************************************************************/ 497 498 static ACPI_STATUS 499 AcpiHwEnableWakeupGpeBlock ( 500 ACPI_GPE_XRUPT_INFO *GpeXruptInfo, 501 ACPI_GPE_BLOCK_INFO *GpeBlock, 502 void *Context) 503 { 504 UINT32 i; 505 ACPI_STATUS Status; 506 507 508 /* Examine each GPE Register within the block */ 509 510 for (i = 0; i < GpeBlock->RegisterCount; i++) 511 { 512 if (!GpeBlock->RegisterInfo[i].EnableForWake) 513 { 514 continue; 515 } 516 517 /* Enable all "wake" GPEs in this register */ 518 519 Status = AcpiHwWrite (GpeBlock->RegisterInfo[i].EnableForWake, 520 &GpeBlock->RegisterInfo[i].EnableAddress); 521 if (ACPI_FAILURE (Status)) 522 { 523 return (Status); 524 } 525 } 526 527 return (AE_OK); 528 } 529 530 531 /****************************************************************************** 532 * 533 * FUNCTION: AcpiHwDisableAllGpes 534 * 535 * PARAMETERS: None 536 * 537 * RETURN: Status 538 * 539 * DESCRIPTION: Disable and clear all GPEs in all GPE blocks 540 * 541 ******************************************************************************/ 542 543 ACPI_STATUS 544 AcpiHwDisableAllGpes ( 545 void) 546 { 547 ACPI_STATUS Status; 548 549 550 ACPI_FUNCTION_TRACE (HwDisableAllGpes); 551 552 553 Status = AcpiEvWalkGpeList (AcpiHwDisableGpeBlock, NULL); 554 Status = AcpiEvWalkGpeList (AcpiHwClearGpeBlock, NULL); 555 return_ACPI_STATUS (Status); 556 } 557 558 559 /****************************************************************************** 560 * 561 * FUNCTION: AcpiHwEnableAllRuntimeGpes 562 * 563 * PARAMETERS: None 564 * 565 * RETURN: Status 566 * 567 * DESCRIPTION: Enable all "runtime" GPEs, in all GPE blocks 568 * 569 ******************************************************************************/ 570 571 ACPI_STATUS 572 AcpiHwEnableAllRuntimeGpes ( 573 void) 574 { 575 ACPI_STATUS Status; 576 577 578 ACPI_FUNCTION_TRACE (HwEnableAllRuntimeGpes); 579 580 581 Status = AcpiEvWalkGpeList (AcpiHwEnableRuntimeGpeBlock, NULL); 582 return_ACPI_STATUS (Status); 583 } 584 585 586 /****************************************************************************** 587 * 588 * FUNCTION: AcpiHwEnableAllWakeupGpes 589 * 590 * PARAMETERS: None 591 * 592 * RETURN: Status 593 * 594 * DESCRIPTION: Enable all "wakeup" GPEs, in all GPE blocks 595 * 596 ******************************************************************************/ 597 598 ACPI_STATUS 599 AcpiHwEnableAllWakeupGpes ( 600 void) 601 { 602 ACPI_STATUS Status; 603 604 605 ACPI_FUNCTION_TRACE (HwEnableAllWakeupGpes); 606 607 608 Status = AcpiEvWalkGpeList (AcpiHwEnableWakeupGpeBlock, NULL); 609 return_ACPI_STATUS (Status); 610 } 611 612 #endif /* !ACPI_REDUCED_HARDWARE */ 613