hwsleep.c revision 167802
1 2/****************************************************************************** 3 * 4 * Name: hwsleep.c - ACPI Hardware Sleep/Wake Interface 5 * $Revision: 1.87 $ 6 * 7 *****************************************************************************/ 8 9/****************************************************************************** 10 * 11 * 1. Copyright Notice 12 * 13 * Some or all of this work - Copyright (c) 1999 - 2007, 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 <contrib/dev/acpica/acpi.h> 119#include <contrib/dev/acpica/actables.h> 120 121#define _COMPONENT ACPI_HARDWARE 122 ACPI_MODULE_NAME ("hwsleep") 123 124 125/******************************************************************************* 126 * 127 * FUNCTION: AcpiSetFirmwareWakingVector 128 * 129 * PARAMETERS: PhysicalAddress - Physical address of ACPI real mode 130 * entry point. 131 * 132 * RETURN: Status 133 * 134 * DESCRIPTION: Access function for the FirmwareWakingVector field in FACS 135 * 136 ******************************************************************************/ 137 138ACPI_STATUS 139AcpiSetFirmwareWakingVector ( 140 ACPI_PHYSICAL_ADDRESS PhysicalAddress) 141{ 142 ACPI_TABLE_FACS *Facs; 143 ACPI_STATUS Status; 144 145 146 ACPI_FUNCTION_TRACE (AcpiSetFirmwareWakingVector); 147 148 /* Get the FACS */ 149 150 Status = AcpiGetTableByIndex (ACPI_TABLE_INDEX_FACS, (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 177ACPI_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 194ACPI_STATUS 195AcpiGetFirmwareWakingVector ( 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, (ACPI_TABLE_HEADER **) &Facs); 213 if (ACPI_FAILURE (Status)) 214 { 215 return_ACPI_STATUS (Status); 216 } 217 218 /* Get the vector */ 219 220 if ((Facs->Length < 32) || 221 (!(Facs->XFirmwareWakingVector))) 222 { 223 /* 224 * ACPI 1.0 FACS or short table or optional X_ field is zero 225 */ 226 *PhysicalAddress = 227 (ACPI_PHYSICAL_ADDRESS) Facs->FirmwareWakingVector; 228 } 229 else 230 { 231 /* 232 * ACPI 2.0 FACS with valid X_ field 233 */ 234 *PhysicalAddress = (ACPI_PHYSICAL_ADDRESS) Facs->XFirmwareWakingVector; 235 } 236 237 return_ACPI_STATUS (AE_OK); 238} 239 240ACPI_EXPORT_SYMBOL (AcpiGetFirmwareWakingVector) 241 242 243/******************************************************************************* 244 * 245 * FUNCTION: AcpiEnterSleepStatePrep 246 * 247 * PARAMETERS: SleepState - Which sleep state to enter 248 * 249 * RETURN: Status 250 * 251 * DESCRIPTION: Prepare to enter a system sleep state (see ACPI 2.0 spec p 231) 252 * This function must execute with interrupts enabled. 253 * We break sleeping into 2 stages so that OSPM can handle 254 * various OS-specific tasks between the two steps. 255 * 256 ******************************************************************************/ 257 258ACPI_STATUS 259AcpiEnterSleepStatePrep ( 260 UINT8 SleepState) 261{ 262 ACPI_STATUS Status; 263 ACPI_OBJECT_LIST ArgList; 264 ACPI_OBJECT Arg; 265 266 267 ACPI_FUNCTION_TRACE (AcpiEnterSleepStatePrep); 268 269 270 /* 271 * _PSW methods could be run here to enable wake-on keyboard, LAN, etc. 272 */ 273 Status = AcpiGetSleepTypeData (SleepState, 274 &AcpiGbl_SleepTypeA, &AcpiGbl_SleepTypeB); 275 if (ACPI_FAILURE (Status)) 276 { 277 return_ACPI_STATUS (Status); 278 } 279 280 /* Setup parameter object */ 281 282 ArgList.Count = 1; 283 ArgList.Pointer = &Arg; 284 285 Arg.Type = ACPI_TYPE_INTEGER; 286 Arg.Integer.Value = SleepState; 287 288 /* Run the _PTS and _GTS methods */ 289 290 Status = AcpiEvaluateObject (NULL, METHOD_NAME__PTS, &ArgList, NULL); 291 if (ACPI_FAILURE (Status) && Status != AE_NOT_FOUND) 292 { 293 return_ACPI_STATUS (Status); 294 } 295 296 Status = AcpiEvaluateObject (NULL, METHOD_NAME__GTS, &ArgList, NULL); 297 if (ACPI_FAILURE (Status) && Status != AE_NOT_FOUND) 298 { 299 return_ACPI_STATUS (Status); 300 } 301 302 /* Setup the argument to _SST */ 303 304 switch (SleepState) 305 { 306 case ACPI_STATE_S0: 307 Arg.Integer.Value = ACPI_SST_WORKING; 308 break; 309 310 case ACPI_STATE_S1: 311 case ACPI_STATE_S2: 312 case ACPI_STATE_S3: 313 Arg.Integer.Value = ACPI_SST_SLEEPING; 314 break; 315 316 case ACPI_STATE_S4: 317 Arg.Integer.Value = ACPI_SST_SLEEP_CONTEXT; 318 break; 319 320 default: 321 Arg.Integer.Value = ACPI_SST_INDICATOR_OFF; /* Default is off */ 322 break; 323 } 324 325 /* Set the system indicators to show the desired sleep state. */ 326 327 Status = AcpiEvaluateObject (NULL, METHOD_NAME__SST, &ArgList, NULL); 328 if (ACPI_FAILURE (Status) && Status != AE_NOT_FOUND) 329 { 330 ACPI_EXCEPTION ((AE_INFO, Status, "While executing method _SST")); 331 } 332 333 return_ACPI_STATUS (AE_OK); 334} 335 336ACPI_EXPORT_SYMBOL (AcpiEnterSleepStatePrep) 337 338 339/******************************************************************************* 340 * 341 * FUNCTION: AcpiEnterSleepState 342 * 343 * PARAMETERS: SleepState - Which sleep state to enter 344 * 345 * RETURN: Status 346 * 347 * DESCRIPTION: Enter a system sleep state (see ACPI 2.0 spec p 231) 348 * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED 349 * 350 ******************************************************************************/ 351 352ACPI_STATUS 353AcpiEnterSleepState ( 354 UINT8 SleepState) 355{ 356 UINT32 PM1AControl; 357 UINT32 PM1BControl; 358 ACPI_BIT_REGISTER_INFO *SleepTypeRegInfo; 359 ACPI_BIT_REGISTER_INFO *SleepEnableRegInfo; 360 UINT32 InValue; 361 ACPI_STATUS Status; 362 363 364 ACPI_FUNCTION_TRACE (AcpiEnterSleepState); 365 366 367 if ((AcpiGbl_SleepTypeA > ACPI_SLEEP_TYPE_MAX) || 368 (AcpiGbl_SleepTypeB > ACPI_SLEEP_TYPE_MAX)) 369 { 370 ACPI_ERROR ((AE_INFO, "Sleep values out of range: A=%X B=%X", 371 AcpiGbl_SleepTypeA, AcpiGbl_SleepTypeB)); 372 return_ACPI_STATUS (AE_AML_OPERAND_VALUE); 373 } 374 375 SleepTypeRegInfo = AcpiHwGetBitRegisterInfo (ACPI_BITREG_SLEEP_TYPE_A); 376 SleepEnableRegInfo = AcpiHwGetBitRegisterInfo (ACPI_BITREG_SLEEP_ENABLE); 377 378 /* Clear wake status */ 379 380 Status = AcpiSetRegister (ACPI_BITREG_WAKE_STATUS, 1); 381 if (ACPI_FAILURE (Status)) 382 { 383 return_ACPI_STATUS (Status); 384 } 385 386 /* Clear all fixed and general purpose status bits */ 387 388 Status = AcpiHwClearAcpiStatus (); 389 if (ACPI_FAILURE (Status)) 390 { 391 return_ACPI_STATUS (Status); 392 } 393 394 if (SleepState != ACPI_STATE_S5) 395 { 396 /* Disable BM arbitration */ 397 398 Status = AcpiSetRegister (ACPI_BITREG_ARB_DISABLE, 1); 399 if (ACPI_FAILURE (Status)) 400 { 401 return_ACPI_STATUS (Status); 402 } 403 } 404 405 /* 406 * 1) Disable/Clear all GPEs 407 * 2) Enable all wakeup GPEs 408 */ 409 Status = AcpiHwDisableAllGpes (); 410 if (ACPI_FAILURE (Status)) 411 { 412 return_ACPI_STATUS (Status); 413 } 414 AcpiGbl_SystemAwakeAndRunning = FALSE; 415 416 Status = AcpiHwEnableAllWakeupGpes (); 417 if (ACPI_FAILURE (Status)) 418 { 419 return_ACPI_STATUS (Status); 420 } 421 422 /* Get current value of PM1A control */ 423 424 Status = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK, 425 ACPI_REGISTER_PM1_CONTROL, &PM1AControl); 426 if (ACPI_FAILURE (Status)) 427 { 428 return_ACPI_STATUS (Status); 429 } 430 ACPI_DEBUG_PRINT ((ACPI_DB_INIT, 431 "Entering sleep state [S%d]\n", SleepState)); 432 433 /* Clear SLP_EN and SLP_TYP fields */ 434 435 PM1AControl &= ~(SleepTypeRegInfo->AccessBitMask | 436 SleepEnableRegInfo->AccessBitMask); 437 PM1BControl = PM1AControl; 438 439 /* Insert SLP_TYP bits */ 440 441 PM1AControl |= (AcpiGbl_SleepTypeA << SleepTypeRegInfo->BitPosition); 442 PM1BControl |= (AcpiGbl_SleepTypeB << SleepTypeRegInfo->BitPosition); 443 444 /* 445 * We split the writes of SLP_TYP and SLP_EN to workaround 446 * poorly implemented hardware. 447 */ 448 449 /* Write #1: fill in SLP_TYP data */ 450 451 Status = AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, 452 ACPI_REGISTER_PM1A_CONTROL, PM1AControl); 453 if (ACPI_FAILURE (Status)) 454 { 455 return_ACPI_STATUS (Status); 456 } 457 458 Status = AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, 459 ACPI_REGISTER_PM1B_CONTROL, PM1BControl); 460 if (ACPI_FAILURE (Status)) 461 { 462 return_ACPI_STATUS (Status); 463 } 464 465 /* Insert SLP_ENABLE bit */ 466 467 PM1AControl |= SleepEnableRegInfo->AccessBitMask; 468 PM1BControl |= SleepEnableRegInfo->AccessBitMask; 469 470 /* Write #2: SLP_TYP + SLP_EN */ 471 472 ACPI_FLUSH_CPU_CACHE (); 473 474 Status = AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, 475 ACPI_REGISTER_PM1A_CONTROL, PM1AControl); 476 if (ACPI_FAILURE (Status)) 477 { 478 return_ACPI_STATUS (Status); 479 } 480 481 Status = AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, 482 ACPI_REGISTER_PM1B_CONTROL, PM1BControl); 483 if (ACPI_FAILURE (Status)) 484 { 485 return_ACPI_STATUS (Status); 486 } 487 488 if (SleepState > ACPI_STATE_S3) 489 { 490 /* 491 * We wanted to sleep > S3, but it didn't happen (by virtue of the 492 * fact that we are still executing!) 493 * 494 * Wait ten seconds, then try again. This is to get S4/S5 to work on 495 * all machines. 496 * 497 * We wait so long to allow chipsets that poll this reg very slowly to 498 * still read the right value. Ideally, this block would go 499 * away entirely. 500 */ 501 AcpiOsStall (10000000); 502 503 Status = AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, 504 ACPI_REGISTER_PM1_CONTROL, 505 SleepEnableRegInfo->AccessBitMask); 506 if (ACPI_FAILURE (Status)) 507 { 508 return_ACPI_STATUS (Status); 509 } 510 } 511 512 /* Wait until we enter sleep state */ 513 514 do 515 { 516 Status = AcpiGetRegister (ACPI_BITREG_WAKE_STATUS, &InValue); 517 if (ACPI_FAILURE (Status)) 518 { 519 return_ACPI_STATUS (Status); 520 } 521 522 /* Spin until we wake */ 523 524 } while (!InValue); 525 526 return_ACPI_STATUS (AE_OK); 527} 528 529ACPI_EXPORT_SYMBOL (AcpiEnterSleepState) 530 531 532/******************************************************************************* 533 * 534 * FUNCTION: AcpiEnterSleepStateS4bios 535 * 536 * PARAMETERS: None 537 * 538 * RETURN: Status 539 * 540 * DESCRIPTION: Perform a S4 bios request. 541 * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED 542 * 543 ******************************************************************************/ 544 545ACPI_STATUS 546AcpiEnterSleepStateS4bios ( 547 void) 548{ 549 UINT32 InValue; 550 ACPI_STATUS Status; 551 552 553 ACPI_FUNCTION_TRACE (AcpiEnterSleepStateS4bios); 554 555 556 Status = AcpiSetRegister (ACPI_BITREG_WAKE_STATUS, 1); 557 if (ACPI_FAILURE (Status)) 558 { 559 return_ACPI_STATUS (Status); 560 } 561 562 Status = AcpiHwClearAcpiStatus (); 563 if (ACPI_FAILURE (Status)) 564 { 565 return_ACPI_STATUS (Status); 566 } 567 568 /* 569 * 1) Disable/Clear all GPEs 570 * 2) Enable all wakeup GPEs 571 */ 572 Status = AcpiHwDisableAllGpes (); 573 if (ACPI_FAILURE (Status)) 574 { 575 return_ACPI_STATUS (Status); 576 } 577 AcpiGbl_SystemAwakeAndRunning = FALSE; 578 579 Status = AcpiHwEnableAllWakeupGpes (); 580 if (ACPI_FAILURE (Status)) 581 { 582 return_ACPI_STATUS (Status); 583 } 584 585 ACPI_FLUSH_CPU_CACHE (); 586 587 Status = AcpiOsWritePort (AcpiGbl_FADT.SmiCommand, 588 (UINT32) AcpiGbl_FADT.S4BiosRequest, 8); 589 590 do { 591 AcpiOsStall(1000); 592 Status = AcpiGetRegister (ACPI_BITREG_WAKE_STATUS, &InValue); 593 if (ACPI_FAILURE (Status)) 594 { 595 return_ACPI_STATUS (Status); 596 } 597 } while (!InValue); 598 599 return_ACPI_STATUS (AE_OK); 600} 601 602ACPI_EXPORT_SYMBOL (AcpiEnterSleepStateS4bios) 603 604 605/******************************************************************************* 606 * 607 * FUNCTION: AcpiLeaveSleepState 608 * 609 * PARAMETERS: SleepState - Which sleep state we just exited 610 * 611 * RETURN: Status 612 * 613 * DESCRIPTION: Perform OS-independent ACPI cleanup after a sleep 614 * Called with interrupts ENABLED. 615 * 616 ******************************************************************************/ 617 618ACPI_STATUS 619AcpiLeaveSleepState ( 620 UINT8 SleepState) 621{ 622 ACPI_OBJECT_LIST ArgList; 623 ACPI_OBJECT Arg; 624 ACPI_STATUS Status; 625 ACPI_BIT_REGISTER_INFO *SleepTypeRegInfo; 626 ACPI_BIT_REGISTER_INFO *SleepEnableRegInfo; 627 UINT32 PM1AControl; 628 UINT32 PM1BControl; 629 630 631 ACPI_FUNCTION_TRACE (AcpiLeaveSleepState); 632 633 634 /* 635 * Set SLP_TYPE and SLP_EN to state S0. 636 * This is unclear from the ACPI Spec, but it is required 637 * by some machines. 638 */ 639 Status = AcpiGetSleepTypeData (ACPI_STATE_S0, 640 &AcpiGbl_SleepTypeA, &AcpiGbl_SleepTypeB); 641 if (ACPI_SUCCESS (Status)) 642 { 643 SleepTypeRegInfo = AcpiHwGetBitRegisterInfo (ACPI_BITREG_SLEEP_TYPE_A); 644 SleepEnableRegInfo = AcpiHwGetBitRegisterInfo (ACPI_BITREG_SLEEP_ENABLE); 645 646 /* Get current value of PM1A control */ 647 648 Status = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK, 649 ACPI_REGISTER_PM1_CONTROL, &PM1AControl); 650 if (ACPI_SUCCESS (Status)) 651 { 652 /* Clear SLP_EN and SLP_TYP fields */ 653 654 PM1AControl &= ~(SleepTypeRegInfo->AccessBitMask | 655 SleepEnableRegInfo->AccessBitMask); 656 PM1BControl = PM1AControl; 657 658 /* Insert SLP_TYP bits */ 659 660 PM1AControl |= (AcpiGbl_SleepTypeA << SleepTypeRegInfo->BitPosition); 661 PM1BControl |= (AcpiGbl_SleepTypeB << SleepTypeRegInfo->BitPosition); 662 663 /* Just ignore any errors */ 664 665 (void) AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, 666 ACPI_REGISTER_PM1A_CONTROL, PM1AControl); 667 (void) AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, 668 ACPI_REGISTER_PM1B_CONTROL, PM1BControl); 669 } 670 } 671 672 /* Ensure EnterSleepStatePrep -> EnterSleepState ordering */ 673 674 AcpiGbl_SleepTypeA = ACPI_SLEEP_TYPE_INVALID; 675 676 /* Setup parameter object */ 677 678 ArgList.Count = 1; 679 ArgList.Pointer = &Arg; 680 Arg.Type = ACPI_TYPE_INTEGER; 681 682 /* Ignore any errors from these methods */ 683 684 Arg.Integer.Value = ACPI_SST_WAKING; 685 Status = AcpiEvaluateObject (NULL, METHOD_NAME__SST, &ArgList, NULL); 686 if (ACPI_FAILURE (Status) && Status != AE_NOT_FOUND) 687 { 688 ACPI_EXCEPTION ((AE_INFO, Status, "During Method _SST")); 689 } 690 691 Arg.Integer.Value = SleepState; 692 Status = AcpiEvaluateObject (NULL, METHOD_NAME__BFS, &ArgList, NULL); 693 if (ACPI_FAILURE (Status) && Status != AE_NOT_FOUND) 694 { 695 ACPI_EXCEPTION ((AE_INFO, Status, "During Method _BFS")); 696 } 697 698 Status = AcpiEvaluateObject (NULL, METHOD_NAME__WAK, &ArgList, NULL); 699 if (ACPI_FAILURE (Status) && Status != AE_NOT_FOUND) 700 { 701 ACPI_EXCEPTION ((AE_INFO, Status, "During Method _WAK")); 702 } 703 /* TBD: _WAK "sometimes" returns stuff - do we want to look at it? */ 704 705 /* 706 * Restore the GPEs: 707 * 1) Disable/Clear all GPEs 708 * 2) Enable all runtime GPEs 709 */ 710 Status = AcpiHwDisableAllGpes (); 711 if (ACPI_FAILURE (Status)) 712 { 713 return_ACPI_STATUS (Status); 714 } 715 AcpiGbl_SystemAwakeAndRunning = TRUE; 716 717 Status = AcpiHwEnableAllRuntimeGpes (); 718 if (ACPI_FAILURE (Status)) 719 { 720 return_ACPI_STATUS (Status); 721 } 722 723 /* Enable power button */ 724 725 (void) AcpiSetRegister( 726 AcpiGbl_FixedEventInfo[ACPI_EVENT_POWER_BUTTON].EnableRegisterId, 1); 727 728 (void) AcpiSetRegister( 729 AcpiGbl_FixedEventInfo[ACPI_EVENT_POWER_BUTTON].StatusRegisterId, 1); 730 731 /* Enable BM arbitration */ 732 733 Status = AcpiSetRegister (ACPI_BITREG_ARB_DISABLE, 0); 734 if (ACPI_FAILURE (Status)) 735 { 736 return_ACPI_STATUS (Status); 737 } 738 739 Arg.Integer.Value = ACPI_SST_WORKING; 740 Status = AcpiEvaluateObject (NULL, METHOD_NAME__SST, &ArgList, NULL); 741 if (ACPI_FAILURE (Status) && Status != AE_NOT_FOUND) 742 { 743 ACPI_EXCEPTION ((AE_INFO, Status, "During Method _SST")); 744 } 745 746 return_ACPI_STATUS (Status); 747} 748 749ACPI_EXPORT_SYMBOL (AcpiLeaveSleepState) 750 751