hwsleep.c revision 126372
1101313Stjr 2101313Stjr/****************************************************************************** 3101313Stjr * 4101313Stjr * Name: hwsleep.c - ACPI Hardware Sleep/Wake Interface 5101313Stjr * $Revision: 65 $ 6101313Stjr * 7101313Stjr *****************************************************************************/ 8101313Stjr 9101313Stjr/****************************************************************************** 10101313Stjr * 11101313Stjr * 1. Copyright Notice 12101313Stjr * 13101313Stjr * Some or all of this work - Copyright (c) 1999 - 2004, Intel Corp. 14101313Stjr * All rights reserved. 15101313Stjr * 16101313Stjr * 2. License 17101313Stjr * 18101313Stjr * 2.1. This is your license from Intel Corp. under its intellectual property 19101313Stjr * rights. You may have additional license terms from the party that provided 20101313Stjr * you this software, covering your right to use that party's intellectual 21101313Stjr * property rights. 22101313Stjr * 23101313Stjr * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 24101313Stjr * copy of the source code appearing in this file ("Covered Code") an 25101313Stjr * irrevocable, perpetual, worldwide license under Intel's copyrights in the 26101313Stjr * base code distributed originally by Intel ("Original Intel Code") to copy, 27104402Stjr * make derivatives, distribute, use and display any portion of the Covered 28101313Stjr * Code in any form, with the right to sublicense such rights; and 29101313Stjr * 30101313Stjr * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 31107392Sru * license (with the right to sublicense), under only those claims of Intel 32101313Stjr * patents that are infringed by the Original Intel Code, to make, use, sell, 33101313Stjr * offer to sell, and import the Covered Code and derivative works thereof 34101313Stjr * solely to the minimum extent necessary to exercise the above copyright 35101313Stjr * license, and in no event shall the patent license extend to any additions 36101313Stjr * to or modifications of the Original Intel Code. No other license or right 37101313Stjr * is granted directly or by implication, estoppel or otherwise; 38101313Stjr * 39101313Stjr * The above copyright and patent license is granted only if the following 40101313Stjr * conditions are met: 41101313Stjr * 42101313Stjr * 3. Conditions 43101313Stjr * 44101313Stjr * 3.1. Redistribution of Source with Rights to Further Distribute Source. 45101313Stjr * Redistribution of source code of any substantial portion of the Covered 46101313Stjr * Code or modification with rights to further distribute source must include 47101313Stjr * the above Copyright Notice, the above License, this list of Conditions, 48101313Stjr * and the following Disclaimer and Export Compliance provision. In addition, 49101313Stjr * Licensee must cause all Covered Code to which Licensee contributes to 50101313Stjr * contain a file documenting the changes Licensee made to create that Covered 51101313Stjr * Code and the date of any change. Licensee must include in that file the 52107392Sru * documentation of any changes made by any predecessor Licensee. Licensee 53101313Stjr * must include a prominent statement that the modification is derived, 54101313Stjr * directly or indirectly, from Original Intel Code. 55101313Stjr * 56101313Stjr * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 57101313Stjr * Redistribution of source code of any substantial portion of the Covered 58101313Stjr * Code or modification without rights to further distribute source must 59101313Stjr * include the following Disclaimer and Export Compliance provision in the 60101313Stjr * documentation and/or other materials provided with distribution. In 61101313Stjr * addition, Licensee may not authorize further sublicense of source of any 62101313Stjr * portion of the Covered Code, and must include terms to the effect that the 63101313Stjr * license from Licensee to its licensee is limited to the intellectual 64101313Stjr * property embodied in the software Licensee provides to its licensee, and 65101313Stjr * not to intellectual property embodied in modifications its licensee may 66101313Stjr * make. 67101313Stjr * 68101313Stjr * 3.3. Redistribution of Executable. Redistribution in executable form of any 69101313Stjr * substantial portion of the Covered Code or modification must reproduce the 70101313Stjr * above Copyright Notice, and the following Disclaimer and Export Compliance 71101313Stjr * provision in the documentation and/or other materials provided with the 72101313Stjr * distribution. 73104402Stjr * 74104402Stjr * 3.4. Intel retains all right, title, and interest in and to the Original 75104402Stjr * Intel Code. 76104402Stjr * 77104402Stjr * 3.5. Neither the name Intel nor any other trademark owned or controlled by 78104402Stjr * Intel shall be used in advertising or otherwise to promote the sale, use or 79104402Stjr * other dealings in products derived from or relating to the Covered Code 80104402Stjr * without prior written authorization from Intel. 81104402Stjr * 82104402Stjr * 4. Disclaimer and Export Compliance 83104402Stjr * 84104402Stjr * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 85104402Stjr * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 86104402Stjr * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 87101313Stjr * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 88101313Stjr * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 89101313Stjr * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 90101313Stjr * PARTICULAR PURPOSE. 91101313Stjr * 92101313Stjr * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 93101313Stjr * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 94101313Stjr * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 95101313Stjr * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 96101313Stjr * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 97101313Stjr * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 98101313Stjr * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 99101313Stjr * LIMITED REMEDY. 100101313Stjr * 101101313Stjr * 4.3. Licensee shall not export, either directly or indirectly, any of this 102101313Stjr * software or system incorporating such software without first obtaining any 103101313Stjr * required license or other approval from the U. S. Department of Commerce or 104101313Stjr * any other agency or department of the United States Government. In the 105101313Stjr * event Licensee exports any such software from the United States or 106101313Stjr * re-exports any such software from a foreign destination, Licensee shall 107101313Stjr * ensure that the distribution and export/re-export of the software is in 108101313Stjr * compliance with all laws, regulations, orders, or other restrictions of the 109101313Stjr * U.S. Export Administration Regulations. Licensee agrees that neither it nor 110101313Stjr * any of its subsidiaries will export/re-export any technical data, process, 111101313Stjr * software, or service, directly or indirectly, to any country for which the 112101313Stjr * United States government or any agency thereof requires an export license, 113101313Stjr * other governmental approval, or letter of assurance, without first obtaining 114101313Stjr * such license, approval or letter. 115101313Stjr * 116101313Stjr *****************************************************************************/ 117101313Stjr 118101313Stjr#include "acpi.h" 119101313Stjr 120101313Stjr#define _COMPONENT ACPI_HARDWARE 121101313Stjr ACPI_MODULE_NAME ("hwsleep") 122101313Stjr 123 124#define METHOD_NAME__BFS "\\_BFS" 125#define METHOD_NAME__GTS "\\_GTS" 126#define METHOD_NAME__PTS "\\_PTS" 127#define METHOD_NAME__SST "\\_SI._SST" 128#define METHOD_NAME__WAK "\\_WAK" 129 130#define ACPI_SST_INDICATOR_OFF 0 131#define ACPI_SST_WORKING 1 132#define ACPI_SST_WAKING 2 133#define ACPI_SST_SLEEPING 3 134#define ACPI_SST_SLEEP_CONTEXT 4 135 136 137/****************************************************************************** 138 * 139 * FUNCTION: AcpiSetFirmwareWakingVector 140 * 141 * PARAMETERS: PhysicalAddress - Physical address of ACPI real mode 142 * entry point. 143 * 144 * RETURN: Status 145 * 146 * DESCRIPTION: Access function for dFirmwareWakingVector field in FACS 147 * 148 ******************************************************************************/ 149 150ACPI_STATUS 151AcpiSetFirmwareWakingVector ( 152 ACPI_PHYSICAL_ADDRESS PhysicalAddress) 153{ 154 155 ACPI_FUNCTION_TRACE ("AcpiSetFirmwareWakingVector"); 156 157 158 /* Set the vector */ 159 160 if (AcpiGbl_CommonFACS.VectorWidth == 32) 161 { 162 *(ACPI_CAST_PTR (UINT32, AcpiGbl_CommonFACS.FirmwareWakingVector)) 163 = (UINT32) PhysicalAddress; 164 } 165 else 166 { 167 *AcpiGbl_CommonFACS.FirmwareWakingVector 168 = PhysicalAddress; 169 } 170 171 return_ACPI_STATUS (AE_OK); 172} 173 174 175/****************************************************************************** 176 * 177 * FUNCTION: AcpiGetFirmwareWakingVector 178 * 179 * PARAMETERS: *PhysicalAddress - Output buffer where contents of 180 * the FirmwareWakingVector field of 181 * the FACS will be stored. 182 * 183 * RETURN: Status 184 * 185 * DESCRIPTION: Access function for FirmwareWakingVector field in FACS 186 * 187 ******************************************************************************/ 188 189ACPI_STATUS 190AcpiGetFirmwareWakingVector ( 191 ACPI_PHYSICAL_ADDRESS *PhysicalAddress) 192{ 193 194 ACPI_FUNCTION_TRACE ("AcpiGetFirmwareWakingVector"); 195 196 197 if (!PhysicalAddress) 198 { 199 return_ACPI_STATUS (AE_BAD_PARAMETER); 200 } 201 202 /* Get the vector */ 203 204 if (AcpiGbl_CommonFACS.VectorWidth == 32) 205 { 206 *PhysicalAddress = (ACPI_PHYSICAL_ADDRESS) 207 *(ACPI_CAST_PTR (UINT32, AcpiGbl_CommonFACS.FirmwareWakingVector)); 208 } 209 else 210 { 211 *PhysicalAddress = 212 *AcpiGbl_CommonFACS.FirmwareWakingVector; 213 } 214 215 return_ACPI_STATUS (AE_OK); 216} 217 218 219/****************************************************************************** 220 * 221 * FUNCTION: AcpiEnterSleepStatePrep 222 * 223 * PARAMETERS: SleepState - Which sleep state to enter 224 * 225 * RETURN: Status 226 * 227 * DESCRIPTION: Prepare to enter a system sleep state (see ACPI 2.0 spec p 231) 228 * This function must execute with interrupts enabled. 229 * We break sleeping into 2 stages so that OSPM can handle 230 * various OS-specific tasks between the two steps. 231 * 232 ******************************************************************************/ 233 234ACPI_STATUS 235AcpiEnterSleepStatePrep ( 236 UINT8 SleepState) 237{ 238 ACPI_STATUS Status; 239 ACPI_OBJECT_LIST ArgList; 240 ACPI_OBJECT Arg; 241 242 243 ACPI_FUNCTION_TRACE ("AcpiEnterSleepStatePrep"); 244 245 246 /* 247 * _PSW methods could be run here to enable wake-on keyboard, LAN, etc. 248 */ 249 Status = AcpiGetSleepTypeData (SleepState, 250 &AcpiGbl_SleepTypeA, &AcpiGbl_SleepTypeB); 251 if (ACPI_FAILURE (Status)) 252 { 253 return_ACPI_STATUS (Status); 254 } 255 256 /* Setup parameter object */ 257 258 ArgList.Count = 1; 259 ArgList.Pointer = &Arg; 260 261 Arg.Type = ACPI_TYPE_INTEGER; 262 Arg.Integer.Value = SleepState; 263 264 /* Run the _PTS and _GTS methods */ 265 266 Status = AcpiEvaluateObject (NULL, METHOD_NAME__PTS, &ArgList, NULL); 267 if (ACPI_FAILURE (Status) && Status != AE_NOT_FOUND) 268 { 269 return_ACPI_STATUS (Status); 270 } 271 272 Status = AcpiEvaluateObject (NULL, METHOD_NAME__GTS, &ArgList, NULL); 273 if (ACPI_FAILURE (Status) && Status != AE_NOT_FOUND) 274 { 275 return_ACPI_STATUS (Status); 276 } 277 278 /* Setup the argument to _SST */ 279 280 switch (SleepState) 281 { 282 case ACPI_STATE_S0: 283 Arg.Integer.Value = ACPI_SST_WORKING; 284 break; 285 286 case ACPI_STATE_S1: 287 case ACPI_STATE_S2: 288 case ACPI_STATE_S3: 289 Arg.Integer.Value = ACPI_SST_SLEEPING; 290 break; 291 292 case ACPI_STATE_S4: 293 Arg.Integer.Value = ACPI_SST_SLEEP_CONTEXT; 294 break; 295 296 default: 297 Arg.Integer.Value = ACPI_SST_INDICATOR_OFF; /* Default is indicator off */ 298 break; 299 } 300 301 /* Set the system indicators to show the desired sleep state. */ 302 303 Status = AcpiEvaluateObject (NULL, METHOD_NAME__SST, &ArgList, NULL); 304 if (ACPI_FAILURE (Status) && Status != AE_NOT_FOUND) 305 { 306 ACPI_REPORT_ERROR (("Method _SST failed, %s\n", AcpiFormatException (Status))); 307 } 308 309 return_ACPI_STATUS (AE_OK); 310} 311 312 313/****************************************************************************** 314 * 315 * FUNCTION: AcpiEnterSleepState 316 * 317 * PARAMETERS: SleepState - Which sleep state to enter 318 * 319 * RETURN: Status 320 * 321 * DESCRIPTION: Enter a system sleep state (see ACPI 2.0 spec p 231) 322 * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED 323 * 324 ******************************************************************************/ 325 326ACPI_STATUS 327AcpiEnterSleepState ( 328 UINT8 SleepState) 329{ 330 UINT32 PM1AControl; 331 UINT32 PM1BControl; 332 ACPI_BIT_REGISTER_INFO *SleepTypeRegInfo; 333 ACPI_BIT_REGISTER_INFO *SleepEnableRegInfo; 334 UINT32 InValue; 335 ACPI_STATUS Status; 336 337 338 ACPI_FUNCTION_TRACE ("AcpiEnterSleepState"); 339 340 341 if ((AcpiGbl_SleepTypeA > ACPI_SLEEP_TYPE_MAX) || 342 (AcpiGbl_SleepTypeB > ACPI_SLEEP_TYPE_MAX)) 343 { 344 ACPI_REPORT_ERROR (("Sleep values out of range: A=%X B=%X\n", 345 AcpiGbl_SleepTypeA, AcpiGbl_SleepTypeB)); 346 return_ACPI_STATUS (AE_AML_OPERAND_VALUE); 347 } 348 349 SleepTypeRegInfo = AcpiHwGetBitRegisterInfo (ACPI_BITREG_SLEEP_TYPE_A); 350 SleepEnableRegInfo = AcpiHwGetBitRegisterInfo (ACPI_BITREG_SLEEP_ENABLE); 351 352 if (SleepState != ACPI_STATE_S5) 353 { 354 /* Clear wake status */ 355 356 Status = AcpiSetRegister (ACPI_BITREG_WAKE_STATUS, 1, ACPI_MTX_DO_NOT_LOCK); 357 if (ACPI_FAILURE (Status)) 358 { 359 return_ACPI_STATUS (Status); 360 } 361 362 Status = AcpiHwClearAcpiStatus (ACPI_MTX_DO_NOT_LOCK); 363 if (ACPI_FAILURE (Status)) 364 { 365 return_ACPI_STATUS (Status); 366 } 367 368 /* Disable BM arbitration */ 369 370 Status = AcpiSetRegister (ACPI_BITREG_ARB_DISABLE, 1, ACPI_MTX_DO_NOT_LOCK); 371 if (ACPI_FAILURE (Status)) 372 { 373 return_ACPI_STATUS (Status); 374 } 375 } 376 377 Status = AcpiHwDisableNonWakeupGpes (); 378 if (ACPI_FAILURE (Status)) 379 { 380 return_ACPI_STATUS (Status); 381 } 382 383 /* Get current value of PM1A control */ 384 385 Status = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1_CONTROL, &PM1AControl); 386 if (ACPI_FAILURE (Status)) 387 { 388 return_ACPI_STATUS (Status); 389 } 390 ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "Entering sleep state [S%d]\n", SleepState)); 391 392 /* Clear SLP_EN and SLP_TYP fields */ 393 394 PM1AControl &= ~(SleepTypeRegInfo->AccessBitMask | SleepEnableRegInfo->AccessBitMask); 395 PM1BControl = PM1AControl; 396 397 /* Insert SLP_TYP bits */ 398 399 PM1AControl |= (AcpiGbl_SleepTypeA << SleepTypeRegInfo->BitPosition); 400 PM1BControl |= (AcpiGbl_SleepTypeB << SleepTypeRegInfo->BitPosition); 401 402 /* 403 * We split the writes of SLP_TYP and SLP_EN to workaround 404 * poorly implemented hardware. 405 */ 406 407 /* Write #1: fill in SLP_TYP data */ 408 409 Status = AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1A_CONTROL, PM1AControl); 410 if (ACPI_FAILURE (Status)) 411 { 412 return_ACPI_STATUS (Status); 413 } 414 415 Status = AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1B_CONTROL, PM1BControl); 416 if (ACPI_FAILURE (Status)) 417 { 418 return_ACPI_STATUS (Status); 419 } 420 421 /* Insert SLP_ENABLE bit */ 422 423 PM1AControl |= SleepEnableRegInfo->AccessBitMask; 424 PM1BControl |= SleepEnableRegInfo->AccessBitMask; 425 426 /* Write #2: SLP_TYP + SLP_EN */ 427 428 ACPI_FLUSH_CPU_CACHE (); 429 430 Status = AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1A_CONTROL, PM1AControl); 431 if (ACPI_FAILURE (Status)) 432 { 433 return_ACPI_STATUS (Status); 434 } 435 436 Status = AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1B_CONTROL, PM1BControl); 437 if (ACPI_FAILURE (Status)) 438 { 439 return_ACPI_STATUS (Status); 440 } 441 442 if (SleepState > ACPI_STATE_S3) 443 { 444 /* 445 * We wanted to sleep > S3, but it didn't happen (by virtue of the fact that 446 * we are still executing!) 447 * 448 * Wait ten seconds, then try again. This is to get S4/S5 to work on all machines. 449 * 450 * We wait so long to allow chipsets that poll this reg very slowly to 451 * still read the right value. Ideally, this block would go 452 * away entirely. 453 */ 454 AcpiOsStall (10000000); 455 456 Status = AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1_CONTROL, 457 SleepEnableRegInfo->AccessBitMask); 458 if (ACPI_FAILURE (Status)) 459 { 460 return_ACPI_STATUS (Status); 461 } 462 } 463 464 /* Wait until we enter sleep state */ 465 466 do 467 { 468 Status = AcpiGetRegister (ACPI_BITREG_WAKE_STATUS, &InValue, ACPI_MTX_DO_NOT_LOCK); 469 if (ACPI_FAILURE (Status)) 470 { 471 return_ACPI_STATUS (Status); 472 } 473 474 /* Spin until we wake */ 475 476 } while (!InValue); 477 478 return_ACPI_STATUS (AE_OK); 479} 480 481 482/****************************************************************************** 483 * 484 * FUNCTION: AcpiEnterSleepStateS4bios 485 * 486 * PARAMETERS: None 487 * 488 * RETURN: Status 489 * 490 * DESCRIPTION: Perform a S4 bios request. 491 * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED 492 * 493 ******************************************************************************/ 494 495ACPI_STATUS 496AcpiEnterSleepStateS4bios ( 497 void) 498{ 499 UINT32 InValue; 500 ACPI_STATUS Status; 501 502 503 ACPI_FUNCTION_TRACE ("AcpiEnterSleepStateS4bios"); 504 505 506 Status = AcpiSetRegister (ACPI_BITREG_WAKE_STATUS, 1, ACPI_MTX_DO_NOT_LOCK); 507 if (ACPI_FAILURE (Status)) 508 { 509 return_ACPI_STATUS (Status); 510 } 511 512 Status = AcpiHwClearAcpiStatus (ACPI_MTX_DO_NOT_LOCK); 513 if (ACPI_FAILURE (Status)) 514 { 515 return_ACPI_STATUS (Status); 516 } 517 518 Status = AcpiHwDisableNonWakeupGpes (); 519 if (ACPI_FAILURE (Status)) 520 { 521 return_ACPI_STATUS (Status); 522 } 523 524 ACPI_FLUSH_CPU_CACHE (); 525 526 Status = AcpiOsWritePort (AcpiGbl_FADT->SmiCmd, (UINT32) AcpiGbl_FADT->S4BiosReq, 8); 527 528 do { 529 AcpiOsStall(1000); 530 Status = AcpiGetRegister (ACPI_BITREG_WAKE_STATUS, &InValue, ACPI_MTX_DO_NOT_LOCK); 531 if (ACPI_FAILURE (Status)) 532 { 533 return_ACPI_STATUS (Status); 534 } 535 } while (!InValue); 536 537 return_ACPI_STATUS (AE_OK); 538} 539 540 541/****************************************************************************** 542 * 543 * FUNCTION: AcpiLeaveSleepState 544 * 545 * PARAMETERS: SleepState - Which sleep state we just exited 546 * 547 * RETURN: Status 548 * 549 * DESCRIPTION: Perform OS-independent ACPI cleanup after a sleep 550 * 551 ******************************************************************************/ 552 553ACPI_STATUS 554AcpiLeaveSleepState ( 555 UINT8 SleepState) 556{ 557 ACPI_OBJECT_LIST ArgList; 558 ACPI_OBJECT Arg; 559 ACPI_STATUS Status; 560 ACPI_BIT_REGISTER_INFO *SleepTypeRegInfo; 561 ACPI_BIT_REGISTER_INFO *SleepEnableRegInfo; 562 UINT32 PM1AControl; 563 UINT32 PM1BControl; 564 565 566 ACPI_FUNCTION_TRACE ("AcpiLeaveSleepState"); 567 568 569 /* 570 * Set SLP_TYPE and SLP_EN to state S0. 571 * This is unclear from the ACPI Spec, but it is required 572 * by some machines. 573 */ 574 Status = AcpiGetSleepTypeData (ACPI_STATE_S0, 575 &AcpiGbl_SleepTypeA, &AcpiGbl_SleepTypeB); 576 if (ACPI_SUCCESS (Status)) 577 { 578 SleepTypeRegInfo = AcpiHwGetBitRegisterInfo (ACPI_BITREG_SLEEP_TYPE_A); 579 SleepEnableRegInfo = AcpiHwGetBitRegisterInfo (ACPI_BITREG_SLEEP_ENABLE); 580 581 /* Get current value of PM1A control */ 582 583 Status = AcpiHwRegisterRead (ACPI_MTX_DO_NOT_LOCK, 584 ACPI_REGISTER_PM1_CONTROL, &PM1AControl); 585 if (ACPI_SUCCESS (Status)) 586 { 587 /* Clear SLP_EN and SLP_TYP fields */ 588 589 PM1AControl &= ~(SleepTypeRegInfo->AccessBitMask | 590 SleepEnableRegInfo->AccessBitMask); 591 PM1BControl = PM1AControl; 592 593 /* Insert SLP_TYP bits */ 594 595 PM1AControl |= (AcpiGbl_SleepTypeA << SleepTypeRegInfo->BitPosition); 596 PM1BControl |= (AcpiGbl_SleepTypeB << SleepTypeRegInfo->BitPosition); 597 598 /* Just ignore any errors */ 599 600 (void) AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, 601 ACPI_REGISTER_PM1A_CONTROL, PM1AControl); 602 (void) AcpiHwRegisterWrite (ACPI_MTX_DO_NOT_LOCK, 603 ACPI_REGISTER_PM1B_CONTROL, PM1BControl); 604 } 605 } 606 607 /* Ensure EnterSleepStatePrep -> EnterSleepState ordering */ 608 609 AcpiGbl_SleepTypeA = ACPI_SLEEP_TYPE_INVALID; 610 611 /* Setup parameter object */ 612 613 ArgList.Count = 1; 614 ArgList.Pointer = &Arg; 615 Arg.Type = ACPI_TYPE_INTEGER; 616 617 /* Ignore any errors from these methods */ 618 619 Arg.Integer.Value = ACPI_SST_WAKING; 620 Status = AcpiEvaluateObject (NULL, METHOD_NAME__SST, &ArgList, NULL); 621 if (ACPI_FAILURE (Status) && Status != AE_NOT_FOUND) 622 { 623 ACPI_REPORT_ERROR (("Method _SST failed, %s\n", AcpiFormatException (Status))); 624 } 625 626 Arg.Integer.Value = SleepState; 627 Status = AcpiEvaluateObject (NULL, METHOD_NAME__BFS, &ArgList, NULL); 628 if (ACPI_FAILURE (Status) && Status != AE_NOT_FOUND) 629 { 630 ACPI_REPORT_ERROR (("Method _BFS failed, %s\n", AcpiFormatException (Status))); 631 } 632 633 Status = AcpiEvaluateObject (NULL, METHOD_NAME__WAK, &ArgList, NULL); 634 if (ACPI_FAILURE (Status) && Status != AE_NOT_FOUND) 635 { 636 ACPI_REPORT_ERROR (("Method _WAK failed, %s\n", AcpiFormatException (Status))); 637 } 638 639 /* _WAK returns stuff - do we want to look at it? */ 640 641 Status = AcpiHwEnableNonWakeupGpes (); 642 if (ACPI_FAILURE (Status)) 643 { 644 return_ACPI_STATUS (Status); 645 } 646 647 /* Enable power button */ 648 649 AcpiSetRegister(AcpiGbl_FixedEventInfo[ACPI_EVENT_POWER_BUTTON].EnableRegisterId, 650 1, ACPI_MTX_DO_NOT_LOCK); 651 AcpiSetRegister(AcpiGbl_FixedEventInfo[ACPI_EVENT_POWER_BUTTON].StatusRegisterId, 652 1, ACPI_MTX_DO_NOT_LOCK); 653 654 /* Enable BM arbitration */ 655 656 Status = AcpiSetRegister (ACPI_BITREG_ARB_DISABLE, 0, ACPI_MTX_LOCK); 657 if (ACPI_FAILURE (Status)) 658 { 659 return_ACPI_STATUS (Status); 660 } 661 662 Arg.Integer.Value = ACPI_SST_WORKING; 663 Status = AcpiEvaluateObject (NULL, METHOD_NAME__SST, &ArgList, NULL); 664 if (ACPI_FAILURE (Status) && Status != AE_NOT_FOUND) 665 { 666 ACPI_REPORT_ERROR (("Method _SST failed, %s\n", AcpiFormatException (Status))); 667 } 668 669 return_ACPI_STATUS (Status); 670} 671