1 2 /****************************************************************************** 3 * 4 * Name: hwsleep.c - ACPI Hardware Sleep/Wake Interface 5 * $Revision: 1.89 $ 6 * 7 *****************************************************************************/ 8 9 /****************************************************************************** 10 * 11 * 1. Copyright Notice 12 * 13 * Some or all of this work - Copyright (c) 1999 - 2008, Intel Corp. 14 * All rights reserved. 15 * 16 * 2. License 17 * 18 * 2.1. This is your license from Intel Corp. under its intellectual property 19 * rights. You may have additional license terms from the party that provided 20 * you this software, covering your right to use that party's intellectual 21 * property rights. 22 * 23 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 24 * copy of the source code appearing in this file ("Covered Code") an 25 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 26 * base code distributed originally by Intel ("Original Intel Code") to copy, 27 * make derivatives, distribute, use and display any portion of the Covered 28 * Code in any form, with the right to sublicense such rights; and 29 * 30 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 31 * license (with the right to sublicense), under only those claims of Intel 32 * patents that are infringed by the Original Intel Code, to make, use, sell, 33 * offer to sell, and import the Covered Code and derivative works thereof 34 * solely to the minimum extent necessary to exercise the above copyright 35 * license, and in no event shall the patent license extend to any additions 36 * to or modifications of the Original Intel Code. No other license or right 37 * is granted directly or by implication, estoppel or otherwise; 38 * 39 * The above copyright and patent license is granted only if the following 40 * conditions are met: 41 * 42 * 3. Conditions 43 * 44 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 45 * Redistribution of source code of any substantial portion of the Covered 46 * Code or modification with rights to further distribute source must include 47 * the above Copyright Notice, the above License, this list of Conditions, 48 * and the following Disclaimer and Export Compliance provision. In addition, 49 * Licensee must cause all Covered Code to which Licensee contributes to 50 * contain a file documenting the changes Licensee made to create that Covered 51 * Code and the date of any change. Licensee must include in that file the 52 * documentation of any changes made by any predecessor Licensee. Licensee 53 * must include a prominent statement that the modification is derived, 54 * directly or indirectly, from Original Intel Code. 55 * 56 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 57 * Redistribution of source code of any substantial portion of the Covered 58 * Code or modification without rights to further distribute source must 59 * include the following Disclaimer and Export Compliance provision in the 60 * documentation and/or other materials provided with distribution. In 61 * addition, Licensee may not authorize further sublicense of source of any 62 * portion of the Covered Code, and must include terms to the effect that the 63 * license from Licensee to its licensee is limited to the intellectual 64 * property embodied in the software Licensee provides to its licensee, and 65 * not to intellectual property embodied in modifications its licensee may 66 * make. 67 * 68 * 3.3. Redistribution of Executable. Redistribution in executable form of any 69 * substantial portion of the Covered Code or modification must reproduce the 70 * above Copyright Notice, and the following Disclaimer and Export Compliance 71 * provision in the documentation and/or other materials provided with the 72 * distribution. 73 * 74 * 3.4. Intel retains all right, title, and interest in and to the Original 75 * Intel Code. 76 * 77 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 78 * Intel shall be used in advertising or otherwise to promote the sale, use or 79 * other dealings in products derived from or relating to the Covered Code 80 * without prior written authorization from Intel. 81 * 82 * 4. Disclaimer and Export Compliance 83 * 84 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 85 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 86 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 87 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 88 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 89 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 90 * PARTICULAR PURPOSE. 91 * 92 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 93 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 94 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 95 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 96 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 97 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 98 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 99 * LIMITED REMEDY. 100 * 101 * 4.3. Licensee shall not export, either directly or indirectly, any of this 102 * software or system incorporating such software without first obtaining any 103 * required license or other approval from the U. S. Department of Commerce or 104 * any other agency or department of the United States Government. In the 105 * event Licensee exports any such software from the United States or 106 * re-exports any such software from a foreign destination, Licensee shall 107 * ensure that the distribution and export/re-export of the software is in 108 * compliance with all laws, regulations, orders, or other restrictions of the 109 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 110 * any of its subsidiaries will export/re-export any technical data, process, 111 * software, or service, directly or indirectly, to any country for which the 112 * United States government or any agency thereof requires an export license, 113 * other governmental approval, or letter of assurance, without first obtaining 114 * such license, approval or letter. 115 * 116 *****************************************************************************/ 117 118 #include "acpi.h" 119 120 #define _COMPONENT ACPI_HARDWARE 121 ACPI_MODULE_NAME ("hwsleep") 122 123 124 /******************************************************************************* 125 * 126 * FUNCTION: AcpiSetFirmwareWakingVector 127 * 128 * PARAMETERS: PhysicalAddress - Physical address of ACPI real mode 129 * entry point. 130 * 131 * RETURN: Status 132 * 133 * DESCRIPTION: Access function for the FirmwareWakingVector field in FACS 134 * 135 ******************************************************************************/ 136 137 ACPI_STATUS 138 AcpiSetFirmwareWakingVector ( 139 ACPI_PHYSICAL_ADDRESS PhysicalAddress) 140 { 141 ACPI_TABLE_FACS *Facs; 142 ACPI_STATUS Status; 143 144 145 ACPI_FUNCTION_TRACE (AcpiSetFirmwareWakingVector); 146 147 /* Get the FACS */ 148 149 Status = AcpiGetTableByIndex (ACPI_TABLE_INDEX_FACS, 150 ACPI_CAST_INDIRECT_PTR (ACPI_TABLE_HEADER, &Facs)); 151 if (ACPI_FAILURE (Status)) 152 { 153 return_ACPI_STATUS (Status); 154 } 155 156 /* Set the vector */ 157 158 if ((Facs->Length < 32) || 159 (!(Facs->XFirmwareWakingVector))) 160 { 161 /* 162 * ACPI 1.0 FACS or short table or optional X_ field is zero 163 */ 164 Facs->FirmwareWakingVector = (UINT32) PhysicalAddress; 165 } 166 else 167 { 168 /* 169 * ACPI 2.0 FACS with valid X_ field 170 */ 171 Facs->XFirmwareWakingVector = PhysicalAddress; 172 } 173 174 return_ACPI_STATUS (AE_OK); 175 } 176 177 ACPI_EXPORT_SYMBOL (AcpiSetFirmwareWakingVector) 178 179 180 /******************************************************************************* 181 * 182 * FUNCTION: AcpiGetFirmwareWakingVector 183 * 184 * PARAMETERS: *PhysicalAddress - Where the contents of 185 * the FirmwareWakingVector field of 186 * the FACS will be returned. 187 * 188 * RETURN: Status, vector 189 * 190 * DESCRIPTION: Access function for the FirmwareWakingVector field in FACS 191 * 192 ******************************************************************************/ 193 194 ACPI_STATUS 195 AcpiGetFirmwareWakingVector ( 196 ACPI_PHYSICAL_ADDRESS *PhysicalAddress) 197 { 198 ACPI_TABLE_FACS *Facs; 199 ACPI_STATUS Status; 200 201 202 ACPI_FUNCTION_TRACE (AcpiGetFirmwareWakingVector); 203 204 205 if (!PhysicalAddress) 206 { 207 return_ACPI_STATUS (AE_BAD_PARAMETER); 208 } 209 210 /* Get the FACS */ 211 212 Status = AcpiGetTableByIndex (ACPI_TABLE_INDEX_FACS, 213 ACPI_CAST_INDIRECT_PTR (ACPI_TABLE_HEADER, &Facs)); 214 if (ACPI_FAILURE (Status)) 215 { 216 return_ACPI_STATUS (Status); 217 } 218 219 /* Get the vector */ 220 221 if ((Facs->Length < 32) || 222 (!(Facs->XFirmwareWakingVector))) 223 { 224 /* 225 * ACPI 1.0 FACS or short table or optional X_ field is zero 226 */ 227 *PhysicalAddress = 228 (ACPI_PHYSICAL_ADDRESS) Facs->FirmwareWakingVector; 229 } 230 else 231 { 232 /* 233 * ACPI 2.0 FACS with valid X_ field 234 */ 235 *PhysicalAddress = (ACPI_PHYSICAL_ADDRESS) Facs->XFirmwareWakingVector; 236 } 237 238 return_ACPI_STATUS (AE_OK); 239 } 240 241 ACPI_EXPORT_SYMBOL (AcpiGetFirmwareWakingVector) 242 243 244 /******************************************************************************* 245 * 246 * FUNCTION: AcpiEnterSleepStatePrep 247 * 248 * PARAMETERS: SleepState - Which sleep state to enter 249 * 250 * RETURN: Status 251 * 252 * DESCRIPTION: Prepare to enter a system sleep state (see ACPI 2.0 spec p 231) 253 * This function must execute with interrupts enabled. 254 * We break sleeping into 2 stages so that OSPM can handle 255 * various OS-specific tasks between the two steps. 256 * 257 ******************************************************************************/ 258 259 ACPI_STATUS 260 AcpiEnterSleepStatePrep ( 261 UINT8 SleepState) 262 { 263 ACPI_STATUS Status; 264 ACPI_OBJECT_LIST ArgList; 265 ACPI_OBJECT Arg; 266 267 268 ACPI_FUNCTION_TRACE (AcpiEnterSleepStatePrep); 269 270 271 /* 272 * _PSW methods could be run here to enable wake-on keyboard, LAN, etc. 273 */ 274 Status = AcpiGetSleepTypeData (SleepState, 275 &AcpiGbl_SleepTypeA, &AcpiGbl_SleepTypeB); 276 if (ACPI_FAILURE (Status)) 277 { 278 return_ACPI_STATUS (Status); 279 } 280 281 /* Execute the _PTS method (Prepare To Sleep) */ 282 283 ArgList.Count = 1; 284 ArgList.Pointer = &Arg; 285 Arg.Type = ACPI_TYPE_INTEGER; 286 Arg.Integer.Value = SleepState; 287 288 Status = AcpiEvaluateObject (NULL, METHOD_NAME__PTS, &ArgList, NULL); 289 if (ACPI_FAILURE (Status) && Status != AE_NOT_FOUND) 290 { 291 return_ACPI_STATUS (Status); 292 } 293 294 /* Setup the argument to the _SST method (System STatus) */ 295 296 switch (SleepState) 297 { 298 case ACPI_STATE_S0: 299 Arg.Integer.Value = ACPI_SST_WORKING; 300 break; 301 302 case ACPI_STATE_S1: 303 case ACPI_STATE_S2: 304 case ACPI_STATE_S3: 305 Arg.Integer.Value = ACPI_SST_SLEEPING; 306 break; 307 308 case ACPI_STATE_S4: 309 Arg.Integer.Value = ACPI_SST_SLEEP_CONTEXT; 310 break; 311 312 default: 313 Arg.Integer.Value = ACPI_SST_INDICATOR_OFF; /* Default is off */ 314 break; 315 } 316 317 /* 318 * Set the system indicators to show the desired sleep state. 319 * _SST is an optional method (return no error if not found) 320 */ 321 Status = AcpiEvaluateObject (NULL, METHOD_NAME__SST, &ArgList, NULL); 322 if (ACPI_FAILURE (Status) && Status != AE_NOT_FOUND) 323 { 324 ACPI_EXCEPTION ((AE_INFO, Status, "While executing method _SST")); 325 } 326 327 return_ACPI_STATUS (AE_OK); 328 } 329 330 ACPI_EXPORT_SYMBOL (AcpiEnterSleepStatePrep) 331 332 333 /******************************************************************************* 334 * 335 * FUNCTION: AcpiEnterSleepState 336 * 337 * PARAMETERS: SleepState - Which sleep state to enter 338 * 339 * RETURN: Status 340 * 341 * DESCRIPTION: Enter a system sleep state 342 * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED 343 * 344 ******************************************************************************/ 345 346 ACPI_STATUS 347 AcpiEnterSleepState ( 348 UINT8 SleepState) 349 { 350 UINT32 PM1AControl; 351 UINT32 PM1BControl; 352 ACPI_BIT_REGISTER_INFO *SleepTypeRegInfo; 353 ACPI_BIT_REGISTER_INFO *SleepEnableRegInfo; 354 UINT32 InValue; 355 ACPI_OBJECT_LIST ArgList; 356 ACPI_OBJECT Arg; 357 ACPI_STATUS Status; 358 359 360 ACPI_FUNCTION_TRACE (AcpiEnterSleepState); 361 362 363 if ((AcpiGbl_SleepTypeA > ACPI_SLEEP_TYPE_MAX) || 364 (AcpiGbl_SleepTypeB > ACPI_SLEEP_TYPE_MAX)) 365 { 366 ACPI_ERROR ((AE_INFO, "Sleep values out of range: A=%X B=%X", 367 AcpiGbl_SleepTypeA, AcpiGbl_SleepTypeB)); 368 return_ACPI_STATUS (AE_AML_OPERAND_VALUE); 369 } 370 371 SleepTypeRegInfo = AcpiHwGetBitRegisterInfo (ACPI_BITREG_SLEEP_TYPE_A); 372 SleepEnableRegInfo = AcpiHwGetBitRegisterInfo (ACPI_BITREG_SLEEP_ENABLE); 373 374 /* Clear wake status */ 375 376 Status = AcpiSetRegister (ACPI_BITREG_WAKE_STATUS, 1); 377 if (ACPI_FAILURE (Status)) 378 { 379 return_ACPI_STATUS (Status); 380 } 381 382 /* Clear all fixed and general purpose status bits */ 383 384 Status = AcpiHwClearAcpiStatus (); 385 if (ACPI_FAILURE (Status)) 386 { 387 return_ACPI_STATUS (Status); 388 } 389 390 if (SleepState != ACPI_STATE_S5) 391 { 392 /* Disable BM arbitration */ 393 394 Status = AcpiSetRegister (ACPI_BITREG_ARB_DISABLE, 1); 395 if (ACPI_FAILURE (Status)) 396 { 397 return_ACPI_STATUS (Status); 398 } 399 } 400 401 /* 402 * 1) Disable/Clear all GPEs 403 * 2) Enable all wakeup GPEs 404 */ 405 Status = AcpiHwDisableAllGpes (); 406 if (ACPI_FAILURE (Status)) 407 { 408 return_ACPI_STATUS (Status); 409 } 410 AcpiGbl_SystemAwakeAndRunning = FALSE; 411 412 Status = AcpiHwEnableAllWakeupGpes (); 413 if (ACPI_FAILURE (Status)) 414 { 415 return_ACPI_STATUS (Status); 416 } 417 418 /* Execute the _GTS method (Going To Sleep) */ 419 420 ArgList.Count = 1; 421 ArgList.Pointer = &Arg; 422 Arg.Type = ACPI_TYPE_INTEGER; 423 Arg.Integer.Value = SleepState; 424 425 Status = AcpiEvaluateObject (NULL, METHOD_NAME__GTS, &ArgList, NULL); 426 if (ACPI_FAILURE (Status) && Status != AE_NOT_FOUND) 427 { 428 return_ACPI_STATUS (Status); 429 } 430 431 /* Get current value of PM1A control */ 432 433 Status = AcpiHwRegisterRead (ACPI_REGISTER_PM1_CONTROL, 434 &PM1AControl); 435 if (ACPI_FAILURE (Status)) 436 { 437 return_ACPI_STATUS (Status); 438 } 439 ACPI_DEBUG_PRINT ((ACPI_DB_INIT, 440 "Entering sleep state [S%d]\n", SleepState)); 441 442 /* Clear SLP_EN and SLP_TYP fields */ 443 444 PM1AControl &= ~(SleepTypeRegInfo->AccessBitMask | 445 SleepEnableRegInfo->AccessBitMask); 446 PM1BControl = PM1AControl; 447 448 /* Insert SLP_TYP bits */ 449 450 PM1AControl |= (AcpiGbl_SleepTypeA << SleepTypeRegInfo->BitPosition); 451 PM1BControl |= (AcpiGbl_SleepTypeB << SleepTypeRegInfo->BitPosition); 452 453 /* 454 * We split the writes of SLP_TYP and SLP_EN to workaround 455 * poorly implemented hardware. 456 */ 457 458 /* Write #1: fill in SLP_TYP data */ 459 460 Status = AcpiHwRegisterWrite (ACPI_REGISTER_PM1A_CONTROL, 461 PM1AControl); 462 if (ACPI_FAILURE (Status)) 463 { 464 return_ACPI_STATUS (Status); 465 } 466 467 Status = AcpiHwRegisterWrite (ACPI_REGISTER_PM1B_CONTROL, 468 PM1BControl); 469 if (ACPI_FAILURE (Status)) 470 { 471 return_ACPI_STATUS (Status); 472 } 473 474 /* Insert SLP_ENABLE bit */ 475 476 PM1AControl |= SleepEnableRegInfo->AccessBitMask; 477 PM1BControl |= SleepEnableRegInfo->AccessBitMask; 478 479 /* Write #2: SLP_TYP + SLP_EN */ 480 481 ACPI_FLUSH_CPU_CACHE (); 482 483 Status = AcpiHwRegisterWrite (ACPI_REGISTER_PM1A_CONTROL, 484 PM1AControl); 485 if (ACPI_FAILURE (Status)) 486 { 487 return_ACPI_STATUS (Status); 488 } 489 490 Status = AcpiHwRegisterWrite (ACPI_REGISTER_PM1B_CONTROL, 491 PM1BControl); 492 if (ACPI_FAILURE (Status)) 493 { 494 return_ACPI_STATUS (Status); 495 } 496 497 if (SleepState > ACPI_STATE_S3) 498 { 499 /* 500 * We wanted to sleep > S3, but it didn't happen (by virtue of the 501 * fact that we are still executing!) 502 * 503 * Wait ten seconds, then try again. This is to get S4/S5 to work on 504 * all machines. 505 * 506 * We wait so long to allow chipsets that poll this reg very slowly to 507 * still read the right value. Ideally, this block would go 508 * away entirely. 509 */ 510 AcpiOsStall (10000000); 511 512 Status = AcpiHwRegisterWrite (ACPI_REGISTER_PM1_CONTROL, 513 SleepEnableRegInfo->AccessBitMask); 514 if (ACPI_FAILURE (Status)) 515 { 516 return_ACPI_STATUS (Status); 517 } 518 } 519 520 /* Wait until we enter sleep state */ 521 522 do 523 { 524 Status = AcpiGetRegister (ACPI_BITREG_WAKE_STATUS, &InValue); 525 if (ACPI_FAILURE (Status)) 526 { 527 return_ACPI_STATUS (Status); 528 } 529 530 /* Spin until we wake */ 531 532 } while (!InValue); 533 534 return_ACPI_STATUS (AE_OK); 535 } 536 537 ACPI_EXPORT_SYMBOL (AcpiEnterSleepState) 538 539 540 /******************************************************************************* 541 * 542 * FUNCTION: AcpiEnterSleepStateS4bios 543 * 544 * PARAMETERS: None 545 * 546 * RETURN: Status 547 * 548 * DESCRIPTION: Perform a S4 bios request. 549 * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED 550 * 551 ******************************************************************************/ 552 553 ACPI_STATUS 554 AcpiEnterSleepStateS4bios ( 555 void) 556 { 557 UINT32 InValue; 558 ACPI_STATUS Status; 559 560 561 ACPI_FUNCTION_TRACE (AcpiEnterSleepStateS4bios); 562 563 564 Status = AcpiSetRegister (ACPI_BITREG_WAKE_STATUS, 1); 565 if (ACPI_FAILURE (Status)) 566 { 567 return_ACPI_STATUS (Status); 568 } 569 570 Status = AcpiHwClearAcpiStatus (); 571 if (ACPI_FAILURE (Status)) 572 { 573 return_ACPI_STATUS (Status); 574 } 575 576 /* 577 * 1) Disable/Clear all GPEs 578 * 2) Enable all wakeup GPEs 579 */ 580 Status = AcpiHwDisableAllGpes (); 581 if (ACPI_FAILURE (Status)) 582 { 583 return_ACPI_STATUS (Status); 584 } 585 AcpiGbl_SystemAwakeAndRunning = FALSE; 586 587 Status = AcpiHwEnableAllWakeupGpes (); 588 if (ACPI_FAILURE (Status)) 589 { 590 return_ACPI_STATUS (Status); 591 } 592 593 ACPI_FLUSH_CPU_CACHE (); 594 595 Status = AcpiOsWritePort (AcpiGbl_FADT.SmiCommand, 596 (UINT32) AcpiGbl_FADT.S4BiosRequest, 8); 597 598 do { 599 AcpiOsStall(1000); 600 Status = AcpiGetRegister (ACPI_BITREG_WAKE_STATUS, &InValue); 601 if (ACPI_FAILURE (Status)) 602 { 603 return_ACPI_STATUS (Status); 604 } 605 } while (!InValue); 606 607 return_ACPI_STATUS (AE_OK); 608 } 609 610 ACPI_EXPORT_SYMBOL (AcpiEnterSleepStateS4bios) 611 612 613 /******************************************************************************* 614 * 615 * FUNCTION: AcpiLeaveSleepState 616 * 617 * PARAMETERS: SleepState - Which sleep state we just exited 618 * 619 * RETURN: Status 620 * 621 * DESCRIPTION: Perform OS-independent ACPI cleanup after a sleep 622 * Called with interrupts ENABLED. 623 * 624 ******************************************************************************/ 625 626 ACPI_STATUS 627 AcpiLeaveSleepState ( 628 UINT8 SleepState) 629 { 630 ACPI_OBJECT_LIST ArgList; 631 ACPI_OBJECT Arg; 632 ACPI_STATUS Status; 633 ACPI_BIT_REGISTER_INFO *SleepTypeRegInfo; 634 ACPI_BIT_REGISTER_INFO *SleepEnableRegInfo; 635 UINT32 PM1AControl; 636 UINT32 PM1BControl; 637 638 639 ACPI_FUNCTION_TRACE (AcpiLeaveSleepState); 640 641 642 /* 643 * Set SLP_TYPE and SLP_EN to state S0. 644 * This is unclear from the ACPI Spec, but it is required 645 * by some machines. 646 */ 647 Status = AcpiGetSleepTypeData (ACPI_STATE_S0, 648 &AcpiGbl_SleepTypeA, &AcpiGbl_SleepTypeB); 649 if (ACPI_SUCCESS (Status)) 650 { 651 SleepTypeRegInfo = AcpiHwGetBitRegisterInfo (ACPI_BITREG_SLEEP_TYPE_A); 652 SleepEnableRegInfo = AcpiHwGetBitRegisterInfo (ACPI_BITREG_SLEEP_ENABLE); 653 654 /* Get current value of PM1A control */ 655 656 Status = AcpiHwRegisterRead (ACPI_REGISTER_PM1_CONTROL, 657 &PM1AControl); 658 if (ACPI_SUCCESS (Status)) 659 { 660 /* Clear SLP_EN and SLP_TYP fields */ 661 662 PM1AControl &= ~(SleepTypeRegInfo->AccessBitMask | 663 SleepEnableRegInfo->AccessBitMask); 664 PM1BControl = PM1AControl; 665 666 /* Insert SLP_TYP bits */ 667 668 PM1AControl |= (AcpiGbl_SleepTypeA << SleepTypeRegInfo->BitPosition); 669 PM1BControl |= (AcpiGbl_SleepTypeB << SleepTypeRegInfo->BitPosition); 670 671 /* Just ignore any errors */ 672 673 (void) AcpiHwRegisterWrite (ACPI_REGISTER_PM1A_CONTROL, 674 PM1AControl); 675 (void) AcpiHwRegisterWrite (ACPI_REGISTER_PM1B_CONTROL, 676 PM1BControl); 677 } 678 } 679 680 /* Ensure EnterSleepStatePrep -> EnterSleepState ordering */ 681 682 AcpiGbl_SleepTypeA = ACPI_SLEEP_TYPE_INVALID; 683 684 /* Setup parameter object */ 685 686 ArgList.Count = 1; 687 ArgList.Pointer = &Arg; 688 Arg.Type = ACPI_TYPE_INTEGER; 689 690 /* Ignore any errors from these methods */ 691 692 Arg.Integer.Value = ACPI_SST_WAKING; 693 Status = AcpiEvaluateObject (NULL, METHOD_NAME__SST, &ArgList, NULL); 694 if (ACPI_FAILURE (Status) && Status != AE_NOT_FOUND) 695 { 696 ACPI_EXCEPTION ((AE_INFO, Status, "During Method _SST")); 697 } 698 699 Arg.Integer.Value = SleepState; 700 Status = AcpiEvaluateObject (NULL, METHOD_NAME__BFS, &ArgList, NULL); 701 if (ACPI_FAILURE (Status) && Status != AE_NOT_FOUND) 702 { 703 ACPI_EXCEPTION ((AE_INFO, Status, "During Method _BFS")); 704 } 705 706 Status = AcpiEvaluateObject (NULL, METHOD_NAME__WAK, &ArgList, NULL); 707 if (ACPI_FAILURE (Status) && Status != AE_NOT_FOUND) 708 { 709 ACPI_EXCEPTION ((AE_INFO, Status, "During Method _WAK")); 710 } 711 /* TBD: _WAK "sometimes" returns stuff - do we want to look at it? */ 712 713 /* 714 * Restore the GPEs: 715 * 1) Disable/Clear all GPEs 716 * 2) Enable all runtime GPEs 717 */ 718 Status = AcpiHwDisableAllGpes (); 719 if (ACPI_FAILURE (Status)) 720 { 721 return_ACPI_STATUS (Status); 722 } 723 AcpiGbl_SystemAwakeAndRunning = TRUE; 724 725 Status = AcpiHwEnableAllRuntimeGpes (); 726 if (ACPI_FAILURE (Status)) 727 { 728 return_ACPI_STATUS (Status); 729 } 730 731 /* Enable power button */ 732 733 (void) AcpiSetRegister( 734 AcpiGbl_FixedEventInfo[ACPI_EVENT_POWER_BUTTON].EnableRegisterId, 1); 735 736 (void) AcpiSetRegister( 737 AcpiGbl_FixedEventInfo[ACPI_EVENT_POWER_BUTTON].StatusRegisterId, 1); 738 739 /* Enable BM arbitration */ 740 741 Status = AcpiSetRegister (ACPI_BITREG_ARB_DISABLE, 0); 742 if (ACPI_FAILURE (Status)) 743 { 744 return_ACPI_STATUS (Status); 745 } 746 747 Arg.Integer.Value = ACPI_SST_WORKING; 748 Status = AcpiEvaluateObject (NULL, METHOD_NAME__SST, &ArgList, NULL); 749 if (ACPI_FAILURE (Status) && Status != AE_NOT_FOUND) 750 { 751 ACPI_EXCEPTION ((AE_INFO, Status, "During Method _SST")); 752 } 753 754 return_ACPI_STATUS (Status); 755 } 756 757 ACPI_EXPORT_SYMBOL (AcpiLeaveSleepState) 758 759