static int acpi_shutdown(struct sys_device *x) { switch (system_state) { case SYSTEM_POWER_OFF: /* Prepare to power off the system */ return acpi_sleep_prepare(ACPI_STATE_S5); case SYSTEM_SUSPEND_DISK: /* Prepare to suspend the system to disk */ return acpi_sleep_prepare(ACPI_STATE_S4); default: return 0; } }
/** * __acpi_pm_prepare - Prepare the platform to enter the target state. * * If necessary, set the firmware waking vector and do arch-specific * nastiness to get the wakeup code to the waking vector. */ static int __acpi_pm_prepare(void) { int error = acpi_sleep_prepare(acpi_target_sleep_state); if (error) acpi_target_sleep_state = ACPI_STATE_S0; return error; }
/** * acpi_hibernation_begin_old - Set the target system sleep state to * ACPI_STATE_S4 and execute the _PTS control method. This * function is used if the pre-ACPI 2.0 suspend ordering has been * requested. */ static int acpi_hibernation_begin_old(void) { int error = acpi_sleep_prepare(ACPI_STATE_S4); if (!error) acpi_target_sleep_state = ACPI_STATE_S4; return error; }
static int acpi_pm_prepare(suspend_state_t pm_state) { u32 acpi_state = acpi_suspend_states[pm_state]; if (!sleep_states[acpi_state]) { printk("acpi_pm_prepare does not support %d \n", pm_state); return -EPERM; } return acpi_sleep_prepare(acpi_state); }
static int acpi_pm_prepare(void) { int error = acpi_sleep_prepare(acpi_target_sleep_state); if (error) { acpi_target_sleep_state = ACPI_STATE_S0; return error; } return ACPI_SUCCESS(acpi_hw_disable_all_gpes()) ? 0 : -EFAULT; }
/* Main interface to do xen specific suspend/resume */ static int enter_state(u32 state) { unsigned long flags; int error; unsigned long cr4; if ( (state <= ACPI_STATE_S0) || (state > ACPI_S_STATES_MAX) ) return -EINVAL; if ( !spin_trylock(&pm_lock) ) return -EBUSY; BUG_ON(system_state != SYS_STATE_active); system_state = SYS_STATE_suspend; printk(XENLOG_INFO "Preparing system for ACPI S%d state.\n", state); freeze_domains(); acpi_dmar_reinstate(); if ( (error = disable_nonboot_cpus()) ) { system_state = SYS_STATE_resume; goto enable_cpu; } cpufreq_del_cpu(0); hvm_cpu_down(); acpi_sleep_prepare(state); console_start_sync(); printk("Entering ACPI S%d state.\n", state); local_irq_save(flags); spin_debug_disable(); if ( (error = device_power_down()) ) { printk(XENLOG_ERR "Some devices failed to power down."); system_state = SYS_STATE_resume; goto done; } ACPI_FLUSH_CPU_CACHE(); switch ( state ) { case ACPI_STATE_S3: do_suspend_lowlevel(); system_reset_counter++; error = tboot_s3_resume(); break; case ACPI_STATE_S5: acpi_enter_sleep_state(ACPI_STATE_S5); break; default: error = -EINVAL; break; } system_state = SYS_STATE_resume; /* Restore CR4 and EFER from cached values. */ cr4 = read_cr4(); write_cr4(cr4 & ~X86_CR4_MCE); write_efer(read_efer()); device_power_up(); mcheck_init(&boot_cpu_data, 0); write_cr4(cr4); printk(XENLOG_INFO "Finishing wakeup from ACPI S%d state.\n", state); if ( (state == ACPI_STATE_S3) && error ) tboot_s3_error(error); done: spin_debug_enable(); local_irq_restore(flags); console_end_sync(); acpi_sleep_post(state); if ( hvm_cpu_up() ) BUG(); enable_cpu: cpufreq_add_cpu(0); microcode_resume_cpu(0); rcu_barrier(); mtrr_aps_sync_begin(); enable_nonboot_cpus(); mtrr_aps_sync_end(); adjust_vtd_irq_affinities(); acpi_dmar_zap(); thaw_domains(); system_state = SYS_STATE_active; spin_unlock(&pm_lock); return error; }
/* Main interface to do xen specific suspend/resume */ static int enter_state(u32 state) { unsigned long flags; int error; if ( (state <= ACPI_STATE_S0) || (state > ACPI_S_STATES_MAX) ) return -EINVAL; if ( !spin_trylock(&pm_lock) ) return -EBUSY; printk(XENLOG_INFO "Preparing system for ACPI S%d state.", state); freeze_domains(); disable_nonboot_cpus(); if ( num_online_cpus() != 1 ) { error = -EBUSY; goto enable_cpu; } cpufreq_del_cpu(0); hvm_cpu_down(); acpi_sleep_prepare(state); console_start_sync(); printk("Entering ACPI S%d state.\n", state); local_irq_save(flags); spin_debug_disable(); if ( (error = device_power_down()) ) { printk(XENLOG_ERR "Some devices failed to power down."); goto done; } ACPI_FLUSH_CPU_CACHE(); switch ( state ) { case ACPI_STATE_S3: do_suspend_lowlevel(); system_reset_counter++; error = tboot_s3_resume(); break; case ACPI_STATE_S5: acpi_enter_sleep_state(ACPI_STATE_S5); break; default: error = -EINVAL; break; } /* Restore CR4 and EFER from cached values. */ write_cr4(read_cr4()); if ( cpu_has_efer ) write_efer(read_efer()); device_power_up(); printk(XENLOG_INFO "Finishing wakeup from ACPI S%d state.\n", state); if ( (state == ACPI_STATE_S3) && error ) panic("Memory integrity was lost on resume (%d)\n", error); done: spin_debug_enable(); local_irq_restore(flags); console_end_sync(); acpi_sleep_post(state); if ( !hvm_cpu_up() ) BUG(); enable_cpu: cpufreq_add_cpu(0); microcode_resume_cpu(0); enable_nonboot_cpus(); thaw_domains(); spin_unlock(&pm_lock); return error; }