linux/drivers/acpi/sleep.c
<<
>>
Prefs
   1/*
   2 * sleep.c - ACPI sleep support.
   3 *
   4 * Copyright (c) 2005 Alexey Starikovskiy <alexey.y.starikovskiy@intel.com>
   5 * Copyright (c) 2004 David Shaohua Li <shaohua.li@intel.com>
   6 * Copyright (c) 2000-2003 Patrick Mochel
   7 * Copyright (c) 2003 Open Source Development Lab
   8 *
   9 * This file is released under the GPLv2.
  10 *
  11 */
  12
  13#include <linux/delay.h>
  14#include <linux/irq.h>
  15#include <linux/dmi.h>
  16#include <linux/device.h>
  17#include <linux/interrupt.h>
  18#include <linux/suspend.h>
  19#include <linux/reboot.h>
  20#include <linux/acpi.h>
  21#include <linux/module.h>
  22#include <linux/syscore_ops.h>
  23#include <asm/io.h>
  24#include <trace/events/power.h>
  25
  26#include "internal.h"
  27#include "sleep.h"
  28
  29static u8 sleep_states[ACPI_S_STATE_COUNT];
  30
  31static void acpi_sleep_tts_switch(u32 acpi_state)
  32{
  33        acpi_status status;
  34
  35        status = acpi_execute_simple_method(NULL, "\\_TTS", acpi_state);
  36        if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
  37                /*
  38                 * OS can't evaluate the _TTS object correctly. Some warning
  39                 * message will be printed. But it won't break anything.
  40                 */
  41                printk(KERN_NOTICE "Failure in evaluating _TTS object\n");
  42        }
  43}
  44
  45static int tts_notify_reboot(struct notifier_block *this,
  46                        unsigned long code, void *x)
  47{
  48        acpi_sleep_tts_switch(ACPI_STATE_S5);
  49        return NOTIFY_DONE;
  50}
  51
  52static struct notifier_block tts_notifier = {
  53        .notifier_call  = tts_notify_reboot,
  54        .next           = NULL,
  55        .priority       = 0,
  56};
  57
  58static int acpi_sleep_prepare(u32 acpi_state)
  59{
  60#ifdef CONFIG_ACPI_SLEEP
  61        /* do we have a wakeup address for S2 and S3? */
  62        if (acpi_state == ACPI_STATE_S3) {
  63                if (!acpi_wakeup_address)
  64                        return -EFAULT;
  65                acpi_set_waking_vector(acpi_wakeup_address);
  66
  67        }
  68        ACPI_FLUSH_CPU_CACHE();
  69#endif
  70        printk(KERN_INFO PREFIX "Preparing to enter system sleep state S%d\n",
  71                acpi_state);
  72        acpi_enable_wakeup_devices(acpi_state);
  73        acpi_enter_sleep_state_prep(acpi_state);
  74        return 0;
  75}
  76
  77static bool acpi_sleep_state_supported(u8 sleep_state)
  78{
  79        acpi_status status;
  80        u8 type_a, type_b;
  81
  82        status = acpi_get_sleep_type_data(sleep_state, &type_a, &type_b);
  83        return ACPI_SUCCESS(status) && (!acpi_gbl_reduced_hardware
  84                || (acpi_gbl_FADT.sleep_control.address
  85                        && acpi_gbl_FADT.sleep_status.address));
  86}
  87
  88#ifdef CONFIG_ACPI_SLEEP
  89static u32 acpi_target_sleep_state = ACPI_STATE_S0;
  90
  91u32 acpi_target_system_state(void)
  92{
  93        return acpi_target_sleep_state;
  94}
  95EXPORT_SYMBOL_GPL(acpi_target_system_state);
  96
  97static bool pwr_btn_event_pending;
  98
  99/*
 100 * The ACPI specification wants us to save NVS memory regions during hibernation
 101 * and to restore them during the subsequent resume.  Windows does that also for
 102 * suspend to RAM.  However, it is known that this mechanism does not work on
 103 * all machines, so we allow the user to disable it with the help of the
 104 * 'acpi_sleep=nonvs' kernel command line option.
 105 */
 106static bool nvs_nosave;
 107
 108void __init acpi_nvs_nosave(void)
 109{
 110        nvs_nosave = true;
 111}
 112
 113/*
 114 * The ACPI specification wants us to save NVS memory regions during hibernation
 115 * but says nothing about saving NVS during S3.  Not all versions of Windows
 116 * save NVS on S3 suspend either, and it is clear that not all systems need
 117 * NVS to be saved at S3 time.  To improve suspend/resume time, allow the
 118 * user to disable saving NVS on S3 if their system does not require it, but
 119 * continue to save/restore NVS for S4 as specified.
 120 */
 121static bool nvs_nosave_s3;
 122
 123void __init acpi_nvs_nosave_s3(void)
 124{
 125        nvs_nosave_s3 = true;
 126}
 127
 128/*
 129 * ACPI 1.0 wants us to execute _PTS before suspending devices, so we allow the
 130 * user to request that behavior by using the 'acpi_old_suspend_ordering'
 131 * kernel command line option that causes the following variable to be set.
 132 */
 133static bool old_suspend_ordering;
 134
 135void __init acpi_old_suspend_ordering(void)
 136{
 137        old_suspend_ordering = true;
 138}
 139
 140static int __init init_old_suspend_ordering(const struct dmi_system_id *d)
 141{
 142        acpi_old_suspend_ordering();
 143        return 0;
 144}
 145
 146static int __init init_nvs_nosave(const struct dmi_system_id *d)
 147{
 148        acpi_nvs_nosave();
 149        return 0;
 150}
 151
 152static struct dmi_system_id acpisleep_dmi_table[] __initdata = {
 153        {
 154        .callback = init_old_suspend_ordering,
 155        .ident = "Abit KN9 (nForce4 variant)",
 156        .matches = {
 157                DMI_MATCH(DMI_BOARD_VENDOR, "http://www.abit.com.tw/"),
 158                DMI_MATCH(DMI_BOARD_NAME, "KN9 Series(NF-CK804)"),
 159                },
 160        },
 161        {
 162        .callback = init_old_suspend_ordering,
 163        .ident = "HP xw4600 Workstation",
 164        .matches = {
 165                DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
 166                DMI_MATCH(DMI_PRODUCT_NAME, "HP xw4600 Workstation"),
 167                },
 168        },
 169        {
 170        .callback = init_old_suspend_ordering,
 171        .ident = "Asus Pundit P1-AH2 (M2N8L motherboard)",
 172        .matches = {
 173                DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTek Computer INC."),
 174                DMI_MATCH(DMI_BOARD_NAME, "M2N8L"),
 175                },
 176        },
 177        {
 178        .callback = init_old_suspend_ordering,
 179        .ident = "Panasonic CF51-2L",
 180        .matches = {
 181                DMI_MATCH(DMI_BOARD_VENDOR,
 182                                "Matsushita Electric Industrial Co.,Ltd."),
 183                DMI_MATCH(DMI_BOARD_NAME, "CF51-2L"),
 184                },
 185        },
 186        {
 187        .callback = init_nvs_nosave,
 188        .ident = "Sony Vaio VGN-FW41E_H",
 189        .matches = {
 190                DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
 191                DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FW41E_H"),
 192                },
 193        },
 194        {
 195        .callback = init_nvs_nosave,
 196        .ident = "Sony Vaio VGN-FW21E",
 197        .matches = {
 198                DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
 199                DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FW21E"),
 200                },
 201        },
 202        {
 203        .callback = init_nvs_nosave,
 204        .ident = "Sony Vaio VGN-FW21M",
 205        .matches = {
 206                DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
 207                DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FW21M"),
 208                },
 209        },
 210        {
 211        .callback = init_nvs_nosave,
 212        .ident = "Sony Vaio VPCEB17FX",
 213        .matches = {
 214                DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
 215                DMI_MATCH(DMI_PRODUCT_NAME, "VPCEB17FX"),
 216                },
 217        },
 218        {
 219        .callback = init_nvs_nosave,
 220        .ident = "Sony Vaio VGN-SR11M",
 221        .matches = {
 222                DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
 223                DMI_MATCH(DMI_PRODUCT_NAME, "VGN-SR11M"),
 224                },
 225        },
 226        {
 227        .callback = init_nvs_nosave,
 228        .ident = "Everex StepNote Series",
 229        .matches = {
 230                DMI_MATCH(DMI_SYS_VENDOR, "Everex Systems, Inc."),
 231                DMI_MATCH(DMI_PRODUCT_NAME, "Everex StepNote Series"),
 232                },
 233        },
 234        {
 235        .callback = init_nvs_nosave,
 236        .ident = "Sony Vaio VPCEB1Z1E",
 237        .matches = {
 238                DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
 239                DMI_MATCH(DMI_PRODUCT_NAME, "VPCEB1Z1E"),
 240                },
 241        },
 242        {
 243        .callback = init_nvs_nosave,
 244        .ident = "Sony Vaio VGN-NW130D",
 245        .matches = {
 246                DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
 247                DMI_MATCH(DMI_PRODUCT_NAME, "VGN-NW130D"),
 248                },
 249        },
 250        {
 251        .callback = init_nvs_nosave,
 252        .ident = "Sony Vaio VPCCW29FX",
 253        .matches = {
 254                DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
 255                DMI_MATCH(DMI_PRODUCT_NAME, "VPCCW29FX"),
 256                },
 257        },
 258        {
 259        .callback = init_nvs_nosave,
 260        .ident = "Averatec AV1020-ED2",
 261        .matches = {
 262                DMI_MATCH(DMI_SYS_VENDOR, "AVERATEC"),
 263                DMI_MATCH(DMI_PRODUCT_NAME, "1000 Series"),
 264                },
 265        },
 266        {
 267        .callback = init_old_suspend_ordering,
 268        .ident = "Asus A8N-SLI DELUXE",
 269        .matches = {
 270                DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
 271                DMI_MATCH(DMI_BOARD_NAME, "A8N-SLI DELUXE"),
 272                },
 273        },
 274        {
 275        .callback = init_old_suspend_ordering,
 276        .ident = "Asus A8N-SLI Premium",
 277        .matches = {
 278                DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
 279                DMI_MATCH(DMI_BOARD_NAME, "A8N-SLI Premium"),
 280                },
 281        },
 282        {
 283        .callback = init_nvs_nosave,
 284        .ident = "Sony Vaio VGN-SR26GN_P",
 285        .matches = {
 286                DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
 287                DMI_MATCH(DMI_PRODUCT_NAME, "VGN-SR26GN_P"),
 288                },
 289        },
 290        {
 291        .callback = init_nvs_nosave,
 292        .ident = "Sony Vaio VPCEB1S1E",
 293        .matches = {
 294                DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
 295                DMI_MATCH(DMI_PRODUCT_NAME, "VPCEB1S1E"),
 296                },
 297        },
 298        {
 299        .callback = init_nvs_nosave,
 300        .ident = "Sony Vaio VGN-FW520F",
 301        .matches = {
 302                DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
 303                DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FW520F"),
 304                },
 305        },
 306        {
 307        .callback = init_nvs_nosave,
 308        .ident = "Asus K54C",
 309        .matches = {
 310                DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
 311                DMI_MATCH(DMI_PRODUCT_NAME, "K54C"),
 312                },
 313        },
 314        {
 315        .callback = init_nvs_nosave,
 316        .ident = "Asus K54HR",
 317        .matches = {
 318                DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
 319                DMI_MATCH(DMI_PRODUCT_NAME, "K54HR"),
 320                },
 321        },
 322        {},
 323};
 324
 325static void __init acpi_sleep_dmi_check(void)
 326{
 327        int year;
 328
 329        if (dmi_get_date(DMI_BIOS_DATE, &year, NULL, NULL) && year >= 2012)
 330                acpi_nvs_nosave_s3();
 331
 332        dmi_check_system(acpisleep_dmi_table);
 333}
 334
 335/**
 336 * acpi_pm_freeze - Disable the GPEs and suspend EC transactions.
 337 */
 338static int acpi_pm_freeze(void)
 339{
 340        acpi_disable_all_gpes();
 341        acpi_os_wait_events_complete();
 342        acpi_ec_block_transactions();
 343        return 0;
 344}
 345
 346/**
 347 * acpi_pre_suspend - Enable wakeup devices, "freeze" EC and save NVS.
 348 */
 349static int acpi_pm_pre_suspend(void)
 350{
 351        acpi_pm_freeze();
 352        return suspend_nvs_save();
 353}
 354
 355/**
 356 *      __acpi_pm_prepare - Prepare the platform to enter the target state.
 357 *
 358 *      If necessary, set the firmware waking vector and do arch-specific
 359 *      nastiness to get the wakeup code to the waking vector.
 360 */
 361static int __acpi_pm_prepare(void)
 362{
 363        int error = acpi_sleep_prepare(acpi_target_sleep_state);
 364        if (error)
 365                acpi_target_sleep_state = ACPI_STATE_S0;
 366
 367        return error;
 368}
 369
 370/**
 371 *      acpi_pm_prepare - Prepare the platform to enter the target sleep
 372 *              state and disable the GPEs.
 373 */
 374static int acpi_pm_prepare(void)
 375{
 376        int error = __acpi_pm_prepare();
 377        if (!error)
 378                error = acpi_pm_pre_suspend();
 379
 380        return error;
 381}
 382
 383static int find_powerf_dev(struct device *dev, void *data)
 384{
 385        struct acpi_device *device = to_acpi_device(dev);
 386        const char *hid = acpi_device_hid(device);
 387
 388        return !strcmp(hid, ACPI_BUTTON_HID_POWERF);
 389}
 390
 391/**
 392 *      acpi_pm_finish - Instruct the platform to leave a sleep state.
 393 *
 394 *      This is called after we wake back up (or if entering the sleep state
 395 *      failed).
 396 */
 397static void acpi_pm_finish(void)
 398{
 399        struct device *pwr_btn_dev;
 400        u32 acpi_state = acpi_target_sleep_state;
 401
 402        acpi_ec_unblock_transactions();
 403        suspend_nvs_free();
 404
 405        if (acpi_state == ACPI_STATE_S0)
 406                return;
 407
 408        printk(KERN_INFO PREFIX "Waking up from system sleep state S%d\n",
 409                acpi_state);
 410        acpi_disable_wakeup_devices(acpi_state);
 411        acpi_leave_sleep_state(acpi_state);
 412
 413        /* reset firmware waking vector */
 414        acpi_set_waking_vector(0);
 415
 416        acpi_target_sleep_state = ACPI_STATE_S0;
 417
 418        acpi_resume_power_resources();
 419
 420        /* If we were woken with the fixed power button, provide a small
 421         * hint to userspace in the form of a wakeup event on the fixed power
 422         * button device (if it can be found).
 423         *
 424         * We delay the event generation til now, as the PM layer requires
 425         * timekeeping to be running before we generate events. */
 426        if (!pwr_btn_event_pending)
 427                return;
 428
 429        pwr_btn_event_pending = false;
 430        pwr_btn_dev = bus_find_device(&acpi_bus_type, NULL, NULL,
 431                                      find_powerf_dev);
 432        if (pwr_btn_dev) {
 433                pm_wakeup_event(pwr_btn_dev, 0);
 434                put_device(pwr_btn_dev);
 435        }
 436}
 437
 438/**
 439 * acpi_pm_start - Start system PM transition.
 440 */
 441static void acpi_pm_start(u32 acpi_state)
 442{
 443        acpi_target_sleep_state = acpi_state;
 444        acpi_sleep_tts_switch(acpi_target_sleep_state);
 445        acpi_scan_lock_acquire();
 446}
 447
 448/**
 449 * acpi_pm_end - Finish up system PM transition.
 450 */
 451static void acpi_pm_end(void)
 452{
 453        acpi_scan_lock_release();
 454        /*
 455         * This is necessary in case acpi_pm_finish() is not called during a
 456         * failing transition to a sleep state.
 457         */
 458        acpi_target_sleep_state = ACPI_STATE_S0;
 459        acpi_sleep_tts_switch(acpi_target_sleep_state);
 460}
 461#else /* !CONFIG_ACPI_SLEEP */
 462#define acpi_target_sleep_state ACPI_STATE_S0
 463static inline void acpi_sleep_dmi_check(void) {}
 464#endif /* CONFIG_ACPI_SLEEP */
 465
 466#ifdef CONFIG_SUSPEND
 467static u32 acpi_suspend_states[] = {
 468        [PM_SUSPEND_ON] = ACPI_STATE_S0,
 469        [PM_SUSPEND_STANDBY] = ACPI_STATE_S1,
 470        [PM_SUSPEND_MEM] = ACPI_STATE_S3,
 471        [PM_SUSPEND_MAX] = ACPI_STATE_S5
 472};
 473
 474/**
 475 *      acpi_suspend_begin - Set the target system sleep state to the state
 476 *              associated with given @pm_state, if supported.
 477 */
 478static int acpi_suspend_begin(suspend_state_t pm_state)
 479{
 480        u32 acpi_state = acpi_suspend_states[pm_state];
 481        int error;
 482
 483        error = (nvs_nosave || nvs_nosave_s3) ? 0 : suspend_nvs_alloc();
 484        if (error)
 485                return error;
 486
 487        if (!sleep_states[acpi_state]) {
 488                pr_err("ACPI does not support sleep state S%u\n", acpi_state);
 489                return -ENOSYS;
 490        }
 491        if (acpi_state > ACPI_STATE_S1)
 492                pm_set_suspend_via_firmware();
 493
 494        acpi_pm_start(acpi_state);
 495        return 0;
 496}
 497
 498/**
 499 *      acpi_suspend_enter - Actually enter a sleep state.
 500 *      @pm_state: ignored
 501 *
 502 *      Flush caches and go to sleep. For STR we have to call arch-specific
 503 *      assembly, which in turn call acpi_enter_sleep_state().
 504 *      It's unfortunate, but it works. Please fix if you're feeling frisky.
 505 */
 506static int acpi_suspend_enter(suspend_state_t pm_state)
 507{
 508        acpi_status status = AE_OK;
 509        u32 acpi_state = acpi_target_sleep_state;
 510        int error;
 511
 512        ACPI_FLUSH_CPU_CACHE();
 513
 514        trace_suspend_resume(TPS("acpi_suspend"), acpi_state, true);
 515        switch (acpi_state) {
 516        case ACPI_STATE_S1:
 517                barrier();
 518                status = acpi_enter_sleep_state(acpi_state);
 519                break;
 520
 521        case ACPI_STATE_S3:
 522                if (!acpi_suspend_lowlevel)
 523                        return -ENOSYS;
 524                error = acpi_suspend_lowlevel();
 525                if (error)
 526                        return error;
 527                pr_info(PREFIX "Low-level resume complete\n");
 528                pm_set_resume_via_firmware();
 529                break;
 530        }
 531        trace_suspend_resume(TPS("acpi_suspend"), acpi_state, false);
 532
 533        /* This violates the spec but is required for bug compatibility. */
 534        acpi_write_bit_register(ACPI_BITREG_SCI_ENABLE, 1);
 535
 536        /* Reprogram control registers */
 537        acpi_leave_sleep_state_prep(acpi_state);
 538
 539        /* ACPI 3.0 specs (P62) says that it's the responsibility
 540         * of the OSPM to clear the status bit [ implying that the
 541         * POWER_BUTTON event should not reach userspace ]
 542         *
 543         * However, we do generate a small hint for userspace in the form of
 544         * a wakeup event. We flag this condition for now and generate the
 545         * event later, as we're currently too early in resume to be able to
 546         * generate wakeup events.
 547         */
 548        if (ACPI_SUCCESS(status) && (acpi_state == ACPI_STATE_S3)) {
 549                acpi_event_status pwr_btn_status = ACPI_EVENT_FLAG_DISABLED;
 550
 551                acpi_get_event_status(ACPI_EVENT_POWER_BUTTON, &pwr_btn_status);
 552
 553                if (pwr_btn_status & ACPI_EVENT_FLAG_SET) {
 554                        acpi_clear_event(ACPI_EVENT_POWER_BUTTON);
 555                        /* Flag for later */
 556                        pwr_btn_event_pending = true;
 557                }
 558        }
 559
 560        /*
 561         * Disable and clear GPE status before interrupt is enabled. Some GPEs
 562         * (like wakeup GPE) haven't handler, this can avoid such GPE misfire.
 563         * acpi_leave_sleep_state will reenable specific GPEs later
 564         */
 565        acpi_disable_all_gpes();
 566        /* Allow EC transactions to happen. */
 567        acpi_ec_unblock_transactions_early();
 568
 569        suspend_nvs_restore();
 570
 571        return ACPI_SUCCESS(status) ? 0 : -EFAULT;
 572}
 573
 574static int acpi_suspend_state_valid(suspend_state_t pm_state)
 575{
 576        u32 acpi_state;
 577
 578        switch (pm_state) {
 579        case PM_SUSPEND_ON:
 580        case PM_SUSPEND_STANDBY:
 581        case PM_SUSPEND_MEM:
 582                acpi_state = acpi_suspend_states[pm_state];
 583
 584                return sleep_states[acpi_state];
 585        default:
 586                return 0;
 587        }
 588}
 589
 590static const struct platform_suspend_ops acpi_suspend_ops = {
 591        .valid = acpi_suspend_state_valid,
 592        .begin = acpi_suspend_begin,
 593        .prepare_late = acpi_pm_prepare,
 594        .enter = acpi_suspend_enter,
 595        .wake = acpi_pm_finish,
 596        .end = acpi_pm_end,
 597};
 598
 599/**
 600 *      acpi_suspend_begin_old - Set the target system sleep state to the
 601 *              state associated with given @pm_state, if supported, and
 602 *              execute the _PTS control method.  This function is used if the
 603 *              pre-ACPI 2.0 suspend ordering has been requested.
 604 */
 605static int acpi_suspend_begin_old(suspend_state_t pm_state)
 606{
 607        int error = acpi_suspend_begin(pm_state);
 608        if (!error)
 609                error = __acpi_pm_prepare();
 610
 611        return error;
 612}
 613
 614/*
 615 * The following callbacks are used if the pre-ACPI 2.0 suspend ordering has
 616 * been requested.
 617 */
 618static const struct platform_suspend_ops acpi_suspend_ops_old = {
 619        .valid = acpi_suspend_state_valid,
 620        .begin = acpi_suspend_begin_old,
 621        .prepare_late = acpi_pm_pre_suspend,
 622        .enter = acpi_suspend_enter,
 623        .wake = acpi_pm_finish,
 624        .end = acpi_pm_end,
 625        .recover = acpi_pm_finish,
 626};
 627
 628static int acpi_freeze_begin(void)
 629{
 630        acpi_scan_lock_acquire();
 631        return 0;
 632}
 633
 634static int acpi_freeze_prepare(void)
 635{
 636        acpi_enable_wakeup_devices(ACPI_STATE_S0);
 637        acpi_enable_all_wakeup_gpes();
 638        acpi_os_wait_events_complete();
 639        if (acpi_sci_irq_valid())
 640                enable_irq_wake(acpi_sci_irq);
 641        return 0;
 642}
 643
 644static void acpi_freeze_restore(void)
 645{
 646        acpi_disable_wakeup_devices(ACPI_STATE_S0);
 647        if (acpi_sci_irq_valid())
 648                disable_irq_wake(acpi_sci_irq);
 649        acpi_enable_all_runtime_gpes();
 650}
 651
 652static void acpi_freeze_end(void)
 653{
 654        acpi_scan_lock_release();
 655}
 656
 657static const struct platform_freeze_ops acpi_freeze_ops = {
 658        .begin = acpi_freeze_begin,
 659        .prepare = acpi_freeze_prepare,
 660        .restore = acpi_freeze_restore,
 661        .end = acpi_freeze_end,
 662};
 663
 664static void acpi_sleep_suspend_setup(void)
 665{
 666        int i;
 667
 668        for (i = ACPI_STATE_S1; i < ACPI_STATE_S4; i++)
 669                if (acpi_sleep_state_supported(i))
 670                        sleep_states[i] = 1;
 671
 672        suspend_set_ops(old_suspend_ordering ?
 673                &acpi_suspend_ops_old : &acpi_suspend_ops);
 674        freeze_set_ops(&acpi_freeze_ops);
 675}
 676
 677#else /* !CONFIG_SUSPEND */
 678static inline void acpi_sleep_suspend_setup(void) {}
 679#endif /* !CONFIG_SUSPEND */
 680
 681#ifdef CONFIG_PM_SLEEP
 682static u32 saved_bm_rld;
 683
 684static int  acpi_save_bm_rld(void)
 685{
 686        acpi_read_bit_register(ACPI_BITREG_BUS_MASTER_RLD, &saved_bm_rld);
 687        return 0;
 688}
 689
 690static void  acpi_restore_bm_rld(void)
 691{
 692        u32 resumed_bm_rld = 0;
 693
 694        acpi_read_bit_register(ACPI_BITREG_BUS_MASTER_RLD, &resumed_bm_rld);
 695        if (resumed_bm_rld == saved_bm_rld)
 696                return;
 697
 698        acpi_write_bit_register(ACPI_BITREG_BUS_MASTER_RLD, saved_bm_rld);
 699}
 700
 701static struct syscore_ops acpi_sleep_syscore_ops = {
 702        .suspend = acpi_save_bm_rld,
 703        .resume = acpi_restore_bm_rld,
 704};
 705
 706void acpi_sleep_syscore_init(void)
 707{
 708        register_syscore_ops(&acpi_sleep_syscore_ops);
 709}
 710#else
 711static inline void acpi_sleep_syscore_init(void) {}
 712#endif /* CONFIG_PM_SLEEP */
 713
 714#ifdef CONFIG_HIBERNATION
 715static unsigned long s4_hardware_signature;
 716static struct acpi_table_facs *facs;
 717static bool nosigcheck;
 718
 719void __init acpi_no_s4_hw_signature(void)
 720{
 721        nosigcheck = true;
 722}
 723
 724static int acpi_hibernation_begin(void)
 725{
 726        int error;
 727
 728        error = nvs_nosave ? 0 : suspend_nvs_alloc();
 729        if (!error)
 730                acpi_pm_start(ACPI_STATE_S4);
 731
 732        return error;
 733}
 734
 735static int acpi_hibernation_enter(void)
 736{
 737        acpi_status status = AE_OK;
 738
 739        ACPI_FLUSH_CPU_CACHE();
 740
 741        /* This shouldn't return.  If it returns, we have a problem */
 742        status = acpi_enter_sleep_state(ACPI_STATE_S4);
 743        /* Reprogram control registers */
 744        acpi_leave_sleep_state_prep(ACPI_STATE_S4);
 745
 746        return ACPI_SUCCESS(status) ? 0 : -EFAULT;
 747}
 748
 749static void acpi_hibernation_leave(void)
 750{
 751        pm_set_resume_via_firmware();
 752        /*
 753         * If ACPI is not enabled by the BIOS and the boot kernel, we need to
 754         * enable it here.
 755         */
 756        acpi_enable();
 757        /* Reprogram control registers */
 758        acpi_leave_sleep_state_prep(ACPI_STATE_S4);
 759        /* Check the hardware signature */
 760        if (facs && s4_hardware_signature != facs->hardware_signature)
 761                pr_crit("ACPI: Hardware changed while hibernated, success doubtful!\n");
 762        /* Restore the NVS memory area */
 763        suspend_nvs_restore();
 764        /* Allow EC transactions to happen. */
 765        acpi_ec_unblock_transactions_early();
 766}
 767
 768static void acpi_pm_thaw(void)
 769{
 770        acpi_ec_unblock_transactions();
 771        acpi_enable_all_runtime_gpes();
 772}
 773
 774static const struct platform_hibernation_ops acpi_hibernation_ops = {
 775        .begin = acpi_hibernation_begin,
 776        .end = acpi_pm_end,
 777        .pre_snapshot = acpi_pm_prepare,
 778        .finish = acpi_pm_finish,
 779        .prepare = acpi_pm_prepare,
 780        .enter = acpi_hibernation_enter,
 781        .leave = acpi_hibernation_leave,
 782        .pre_restore = acpi_pm_freeze,
 783        .restore_cleanup = acpi_pm_thaw,
 784};
 785
 786/**
 787 *      acpi_hibernation_begin_old - Set the target system sleep state to
 788 *              ACPI_STATE_S4 and execute the _PTS control method.  This
 789 *              function is used if the pre-ACPI 2.0 suspend ordering has been
 790 *              requested.
 791 */
 792static int acpi_hibernation_begin_old(void)
 793{
 794        int error;
 795        /*
 796         * The _TTS object should always be evaluated before the _PTS object.
 797         * When the old_suspended_ordering is true, the _PTS object is
 798         * evaluated in the acpi_sleep_prepare.
 799         */
 800        acpi_sleep_tts_switch(ACPI_STATE_S4);
 801
 802        error = acpi_sleep_prepare(ACPI_STATE_S4);
 803
 804        if (!error) {
 805                if (!nvs_nosave)
 806                        error = suspend_nvs_alloc();
 807                if (!error) {
 808                        acpi_target_sleep_state = ACPI_STATE_S4;
 809                        acpi_scan_lock_acquire();
 810                }
 811        }
 812        return error;
 813}
 814
 815/*
 816 * The following callbacks are used if the pre-ACPI 2.0 suspend ordering has
 817 * been requested.
 818 */
 819static const struct platform_hibernation_ops acpi_hibernation_ops_old = {
 820        .begin = acpi_hibernation_begin_old,
 821        .end = acpi_pm_end,
 822        .pre_snapshot = acpi_pm_pre_suspend,
 823        .prepare = acpi_pm_freeze,
 824        .finish = acpi_pm_finish,
 825        .enter = acpi_hibernation_enter,
 826        .leave = acpi_hibernation_leave,
 827        .pre_restore = acpi_pm_freeze,
 828        .restore_cleanup = acpi_pm_thaw,
 829        .recover = acpi_pm_finish,
 830};
 831
 832static void acpi_sleep_hibernate_setup(void)
 833{
 834        if (!acpi_sleep_state_supported(ACPI_STATE_S4))
 835                return;
 836
 837        hibernation_set_ops(old_suspend_ordering ?
 838                        &acpi_hibernation_ops_old : &acpi_hibernation_ops);
 839        sleep_states[ACPI_STATE_S4] = 1;
 840        if (nosigcheck)
 841                return;
 842
 843        acpi_get_table(ACPI_SIG_FACS, 1, (struct acpi_table_header **)&facs);
 844        if (facs)
 845                s4_hardware_signature = facs->hardware_signature;
 846}
 847#else /* !CONFIG_HIBERNATION */
 848static inline void acpi_sleep_hibernate_setup(void) {}
 849#endif /* !CONFIG_HIBERNATION */
 850
 851static void acpi_power_off_prepare(void)
 852{
 853        /* Prepare to power off the system */
 854        acpi_sleep_prepare(ACPI_STATE_S5);
 855        acpi_disable_all_gpes();
 856        acpi_os_wait_events_complete();
 857}
 858
 859static void acpi_power_off(void)
 860{
 861        /* acpi_sleep_prepare(ACPI_STATE_S5) should have already been called */
 862        printk(KERN_DEBUG "%s called\n", __func__);
 863        local_irq_disable();
 864        acpi_enter_sleep_state(ACPI_STATE_S5);
 865}
 866
 867int __init acpi_sleep_init(void)
 868{
 869        char supported[ACPI_S_STATE_COUNT * 3 + 1];
 870        char *pos = supported;
 871        int i;
 872
 873        acpi_sleep_dmi_check();
 874
 875        sleep_states[ACPI_STATE_S0] = 1;
 876
 877        acpi_sleep_syscore_init();
 878        acpi_sleep_suspend_setup();
 879        acpi_sleep_hibernate_setup();
 880
 881        if (acpi_sleep_state_supported(ACPI_STATE_S5)) {
 882                sleep_states[ACPI_STATE_S5] = 1;
 883                pm_power_off_prepare = acpi_power_off_prepare;
 884                pm_power_off = acpi_power_off;
 885        }
 886
 887        supported[0] = 0;
 888        for (i = 0; i < ACPI_S_STATE_COUNT; i++) {
 889                if (sleep_states[i])
 890                        pos += sprintf(pos, " S%d", i);
 891        }
 892        pr_info(PREFIX "(supports%s)\n", supported);
 893
 894        /*
 895         * Register the tts_notifier to reboot notifier list so that the _TTS
 896         * object can also be evaluated when the system enters S5.
 897         */
 898        register_reboot_notifier(&tts_notifier);
 899        return 0;
 900}
 901