static int prepare_processes(void) { int error; pm_prepare_console(); sys_sync(); disable_nonboot_cpus(); if (freeze_processes()) { error = -EBUSY; goto thaw; } if (pm_disk_mode == PM_DISK_PLATFORM) { if (pm_ops && pm_ops->prepare) { if ((error = pm_ops->prepare(PM_SUSPEND_DISK))) goto thaw; } } /* Free memory before shutting down devices. */ free_some_memory(); return 0; thaw: thaw_processes(); enable_nonboot_cpus(); pm_restore_console(); return error; }
/** * suspend_enter - enter the desired system sleep state. * @state: state to enter * * This function should be called after devices have been suspended. */ static int suspend_enter(suspend_state_t state) { int error; if (suspend_ops->prepare) { error = suspend_ops->prepare(); if (error) return error; } error = dpm_suspend_noirq(PMSG_SUSPEND); if (error) { printk(KERN_ERR "PM: Some devices failed to power down\n"); goto Platfrom_finish; } if (suspend_ops->prepare_late) { error = suspend_ops->prepare_late(); if (error) goto Power_up_devices; } if (suspend_test(TEST_PLATFORM)) goto Platform_wake; error = disable_nonboot_cpus(); if (error || suspend_test(TEST_CPUS)) goto Enable_cpus; arch_suspend_disable_irqs(); BUG_ON(!irqs_disabled()); error = sysdev_suspend(PMSG_SUSPEND); if (!error) { if (!suspend_test(TEST_CORE) && pm_check_wakeup_events()) { error = suspend_ops->enter(state); events_check_enabled = false; } sysdev_resume(); } arch_suspend_enable_irqs(); BUG_ON(irqs_disabled()); Enable_cpus: enable_nonboot_cpus(); Platform_wake: if (suspend_ops->wake) suspend_ops->wake(); Power_up_devices: dpm_resume_noirq(PMSG_RESUME); Platfrom_finish: if (suspend_ops->finish) suspend_ops->finish(); return error; }
static inline int snapshot_restore(int platform_suspend) { int error; mutex_lock(&pm_mutex); pm_prepare_console(); if (platform_suspend) { error = platform_prepare(); if (error) goto Finish; } suspend_console(); error = device_suspend(PMSG_PRETHAW); if (error) goto Resume_devices; error = disable_nonboot_cpus(); if (!error) error = swsusp_resume(); enable_nonboot_cpus(); Resume_devices: if (platform_suspend) platform_finish(); device_resume(); resume_console(); Finish: pm_restore_console(); mutex_unlock(&pm_mutex); return error; }
static int prepare_processes(void) { int error = 0; pm_prepare_console(); error = disable_nonboot_cpus(); if (error) goto enable_cpus; if (freeze_processes()) { error = -EBUSY; goto thaw; } if (pm_disk_mode == PM_DISK_TESTPROC) { printk("swsusp debug: Waiting for 5 seconds.\n"); mdelay(5000); goto thaw; } /* Free memory before shutting down devices. */ if (!(error = swsusp_shrink_memory())) return 0; thaw: thaw_processes(); enable_cpus: enable_nonboot_cpus(); pm_restore_console(); return error; }
/** * suspend_devices_and_enter - suspend devices and enter the desired system sleep * state. * @state: state to enter */ int suspend_devices_and_enter(suspend_state_t state) { int error; if (!pm_ops) return -ENOSYS; if (pm_ops->set_target) { error = pm_ops->set_target(state); if (error) return error; } suspend_console(); error = device_suspend(PMSG_SUSPEND); if (error) { printk(KERN_ERR "Some devices failed to suspend\n"); goto Resume_console; } if (pm_ops->prepare) { error = pm_ops->prepare(state); if (error) goto Resume_devices; } error = disable_nonboot_cpus(); if (!error) suspend_enter(state); enable_nonboot_cpus(); pm_finish(state); Resume_devices: device_resume(); Resume_console: resume_console(); return error; }
static int suspend_enter(suspend_state_t state, bool *wakeup) { int error; if (suspend_ops->prepare) { error = suspend_ops->prepare(); if (error) goto Platform_finish; } error = dpm_suspend_end(PMSG_SUSPEND); if (error) { pr_debug(KERN_ERR "PM: Some devices failed to power down\n"); goto Platform_finish; } if (suspend_ops->prepare_late) { error = suspend_ops->prepare_late(); if (error) goto Platform_wake; } if (suspend_test(TEST_PLATFORM)) goto Platform_wake; error = disable_nonboot_cpus(); if (error || suspend_test(TEST_CPUS)) goto Enable_cpus; arch_suspend_disable_irqs(); BUG_ON(!irqs_disabled()); error = syscore_suspend(); if (!error) { *wakeup = pm_wakeup_pending(); if (!(suspend_test(TEST_CORE) || *wakeup)) { error = suspend_ops->enter(state); events_check_enabled = false; } syscore_resume(); } arch_suspend_enable_irqs(); BUG_ON(irqs_disabled()); Enable_cpus: enable_nonboot_cpus(); Platform_wake: if (suspend_ops->wake) suspend_ops->wake(); dpm_resume_start(PMSG_RESUME); Platform_finish: if (suspend_ops->finish) suspend_ops->finish(); return error; }
/** * suspend_enter - enter the desired system sleep state. * @state: state to enter * * This function should be called after devices have been suspended. */ static int suspend_enter(suspend_state_t state) { int error; if (suspend_ops->prepare) { error = suspend_ops->prepare(); if (error) return error; } error = dpm_suspend_noirq(PMSG_SUSPEND); if (error) { printk(KERN_ERR "PM: Some devices failed to power down\n"); goto Platfrom_finish; } if (suspend_ops->prepare_late) { error = suspend_ops->prepare_late(); if (error) goto Power_up_devices; } if (suspend_test(TEST_PLATFORM)) goto Platform_wake; error = disable_nonboot_cpus(); if (error || suspend_test(TEST_CPUS)) goto Enable_cpus; arch_suspend_disable_irqs(); BUG_ON(!irqs_disabled()); error = sysdev_suspend(PMSG_SUSPEND); if (!error) { //Check there is no NIRQ1 wakeup event before going in suspend if (!suspend_test(TEST_CORE) && !(omap_readl(0x4A10019C)&0x80000000) ) error = suspend_ops->enter(state); sysdev_resume(); } arch_suspend_enable_irqs(); BUG_ON(irqs_disabled()); Enable_cpus: enable_nonboot_cpus(); Platform_wake: if (suspend_ops->wake) suspend_ops->wake(); Power_up_devices: dpm_resume_noirq(PMSG_RESUME); Platfrom_finish: if (suspend_ops->finish) suspend_ops->finish(); return error; }
/** * suspend_devices_and_enter - suspend devices and enter the desired system * sleep state. * @state: state to enter */ int suspend_devices_and_enter(suspend_state_t state) { int error, ftrace_save; if (!suspend_ops) return -ENOSYS; if (suspend_ops->begin) { error = suspend_ops->begin(state); if (error) goto Close; } suspend_console(); ftrace_save = __ftrace_enabled_save(); suspend_test_start(); error = device_suspend(PMSG_SUSPEND); if (error) { printk(KERN_ERR "PM: Some devices failed to suspend\n"); goto Recover_platform; } suspend_test_finish("suspend devices"); if (suspend_test(TEST_DEVICES)) goto Recover_platform; if (suspend_ops->prepare) { error = suspend_ops->prepare(); if (error) goto Resume_devices; } if (suspend_test(TEST_PLATFORM)) goto Finish; error = disable_nonboot_cpus(); if (!error && !suspend_test(TEST_CPUS)) suspend_enter(state); enable_nonboot_cpus(); Finish: if (suspend_ops->finish) suspend_ops->finish(); Resume_devices: suspend_test_start(); device_resume(PMSG_RESUME); suspend_test_finish("resume devices"); __ftrace_enabled_restore(ftrace_save); resume_console(); Close: if (suspend_ops->end) suspend_ops->end(); return error; Recover_platform: if (suspend_ops->recover) suspend_ops->recover(); goto Resume_devices; }
/** * suspend_enter - enter the desired system sleep state. * @state: state to enter * * This function should be called after devices have been suspended. */ static int suspend_enter(suspend_state_t state) { int error; if (suspend_ops->prepare) { error = suspend_ops->prepare(); if (error) goto Platform_finish; } error = dpm_suspend_noirq(PMSG_SUSPEND); if (error) { ; goto Platform_finish; } if (suspend_ops->prepare_late) { error = suspend_ops->prepare_late(); if (error) goto Platform_wake; } if (suspend_test(TEST_PLATFORM)) goto Platform_wake; error = disable_nonboot_cpus(); if (error || suspend_test(TEST_CPUS)) goto Platform_wake; arch_suspend_disable_irqs(); BUG_ON(!irqs_disabled()); error = syscore_suspend(); if (!error) { if (!(suspend_test(TEST_CORE) || pm_wakeup_pending())) { error = suspend_ops->enter(state); events_check_enabled = false; } syscore_resume(); } arch_suspend_enable_irqs(); BUG_ON(irqs_disabled()); Platform_wake: if (suspend_ops->wake) suspend_ops->wake(); dpm_resume_noirq(PMSG_RESUME); Platform_finish: if (suspend_ops->finish) suspend_ops->finish(); return error; }
int hibernation_platform_enter(void) { int error; if (!hibernation_ops) return -ENOSYS; /* * We have cancelled the power transition by running * hibernation_ops->finish() before saving the image, so we should let * the firmware know that we're going to enter the sleep state after all */ error = hibernation_ops->begin(); if (error) goto Close; suspend_console(); error = device_suspend(PMSG_HIBERNATE); if (error) { if (hibernation_ops->recover) hibernation_ops->recover(); goto Resume_devices; } error = hibernation_ops->prepare(); if (error) goto Resume_devices; error = disable_nonboot_cpus(); if (error) goto Finish; device_pm_lock(); local_irq_disable(); error = device_power_down(PMSG_HIBERNATE); if (!error) { hibernation_ops->enter(); /* We should never get here */ while (1); } local_irq_enable(); device_pm_unlock(); /* * We don't need to reenable the nonboot CPUs or resume consoles, since * the system is going to be halted anyway. */ Finish: hibernation_ops->finish(); Resume_devices: device_resume(PMSG_RESTORE); resume_console(); Close: hibernation_ops->end(); return error; }
static void ambench_apbread(void) { u64 raw_counter = 0; u64 amba_counter = 0; unsigned long flags; disable_nonboot_cpus(); local_irq_save(flags); amba_clrbitsl(TIMER_CTR_REG, TIMER_CTR_EN1); amba_writel(TIMER1_STATUS_REG, APBREAD_RELOAD_NUM); amba_writel(TIMER1_RELOAD_REG, 0x0); amba_writel(TIMER1_MATCH1_REG, 0x0); amba_writel(TIMER1_MATCH2_REG, 0x0); amba_clrbitsl(TIMER_CTR_REG, TIMER_CTR_OF1); amba_clrbitsl(TIMER_CTR_REG, TIMER_CTR_CSL1); amba_setbitsl(TIMER_CTR_REG, TIMER_CTR_EN1); do { raw_counter++; } while(__raw_readl((const volatile void *)TIMER1_STATUS_REG)); amba_clrbitsl(TIMER_CTR_REG, TIMER_CTR_EN1); amba_writel(TIMER1_STATUS_REG, APBREAD_RELOAD_NUM); amba_writel(TIMER1_RELOAD_REG, 0x0); amba_writel(TIMER1_MATCH1_REG, 0x0); amba_writel(TIMER1_MATCH2_REG, 0x0); amba_clrbitsl(TIMER_CTR_REG, TIMER_CTR_OF1); amba_clrbitsl(TIMER_CTR_REG, TIMER_CTR_CSL1); amba_setbitsl(TIMER_CTR_REG, TIMER_CTR_EN1); do { amba_counter++; } while(amba_readl(TIMER1_STATUS_REG)); amba_clrbitsl(TIMER_CTR_REG, TIMER_CTR_EN1); local_irq_restore(flags); enable_nonboot_cpus(); #if defined(CONFIG_PLAT_AMBARELLA_SUPPORT_HAL) raw_counter *= get_apb_bus_freq_hz(); #else raw_counter *= clk_get_rate(clk_get(NULL, "gclk_apb")); #endif do_div(raw_counter, APBREAD_RELOAD_NUM); #if defined(CONFIG_PLAT_AMBARELLA_SUPPORT_HAL) amba_counter *= get_apb_bus_freq_hz(); #else amba_counter *= clk_get_rate(clk_get(NULL, "gclk_apb")); #endif do_div(amba_counter, APBREAD_RELOAD_NUM); pr_info("CPU[0x%x] APBRead: raw speed %llu/s!\n", cpu_architecture(), raw_counter); pr_info("CPU[0x%x] APBRead: amba speed %llu/s!\n", cpu_architecture(), amba_counter); }
/** * kernel_power_off - power_off the system * * Shutdown everything and perform a clean system power_off. */ void kernel_power_off(void) { kernel_shutdown_prepare(SYSTEM_POWER_OFF); if (pm_power_off_prepare) pm_power_off_prepare(); disable_nonboot_cpus(); sysdev_shutdown(); printk(KERN_EMERG "Power down.\n"); machine_power_off(); }
/** * suspend_enter - enter the desired system sleep state. * @state: state to enter * * This function should be called after devices have been suspended. */ static int suspend_enter(suspend_state_t state) { int error; if (suspend_ops->prepare) { error = suspend_ops->prepare(); if (error) return error; } error = dpm_suspend_noirq(PMSG_SUSPEND); if (error) { printk(KERN_ERR "PM: Some devices failed to power down\n"); goto Platfrom_finish; } if (suspend_ops->prepare_late) { error = suspend_ops->prepare_late(); if (error) goto Power_up_devices; } if (suspend_test(TEST_PLATFORM)) goto Platform_wake; error = disable_nonboot_cpus(); if (error || suspend_test(TEST_CPUS)) goto Enable_cpus; error = _suspend_enter(state); #ifdef CONFIG_QUICK_WAKEUP while (!error && !quickwakeup_execute()) { if (has_wake_lock(WAKE_LOCK_SUSPEND)) break; error = _suspend_enter(state); } #endif Enable_cpus: enable_nonboot_cpus(); Platform_wake: if (suspend_ops->wake) suspend_ops->wake(); Power_up_devices: dpm_resume_noirq(PMSG_RESUME); Platfrom_finish: if (suspend_ops->finish) suspend_ops->finish(); return error; }
int hibernation_snapshot(int platform_mode) { int error; /* Free memory before shutting down devices. */ error = swsusp_shrink_memory(); if (error) return error; error = platform_begin(platform_mode); if (error) goto Close; suspend_console(); error = device_suspend(PMSG_FREEZE); if (error) goto Recover_platform; if (hibernation_test(TEST_DEVICES)) goto Recover_platform; error = platform_pre_snapshot(platform_mode); if (error || hibernation_test(TEST_PLATFORM)) goto Finish; error = disable_nonboot_cpus(); if (!error) { if (hibernation_test(TEST_CPUS)) goto Enable_cpus; if (hibernation_testmode(HIBERNATION_TEST)) goto Enable_cpus; error = create_image(platform_mode); /* Control returns here after successful restore */ } Enable_cpus: enable_nonboot_cpus(); Finish: platform_finish(platform_mode); Resume_devices: device_resume(in_suspend ? (error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE); resume_console(); Close: platform_end(platform_mode); return error; Recover_platform: platform_recover(platform_mode); goto Resume_devices; }
static int suspend_prepare(suspend_state_t state) { int error = 0; unsigned int free_pages; if (!pm_ops || !pm_ops->enter) return -EPERM; pm_prepare_console(); disable_nonboot_cpus(); if (num_online_cpus() != 1) { error = -EPERM; goto Enable_cpu; } if (freeze_processes()) { error = -EAGAIN; goto Thaw; } if ((free_pages = nr_free_pages()) < FREE_PAGE_NUMBER) { pr_debug("PM: free some memory\n"); shrink_all_memory(FREE_PAGE_NUMBER - free_pages); if (nr_free_pages() < FREE_PAGE_NUMBER) { error = -ENOMEM; printk(KERN_ERR "PM: No enough memory\n"); goto Thaw; } } if (pm_ops->prepare) { if ((error = pm_ops->prepare(state))) goto Thaw; } if ((error = device_suspend(PMSG_SUSPEND))) { printk(KERN_ERR "Some devices failed to suspend\n"); goto Finish; } return 0; Finish: if (pm_ops->finish) pm_ops->finish(state); Thaw: thaw_processes(); Enable_cpu: enable_nonboot_cpus(); pm_restore_console(); return error; }
static int suspend_prepare(suspend_state_t state) { int error; unsigned int free_pages; if (!pm_ops || !pm_ops->enter) return -EPERM; pm_prepare_console(); if (freeze_processes()) { error = -EAGAIN; goto Thaw; } if ((free_pages = global_page_state(NR_FREE_PAGES)) < FREE_PAGE_NUMBER) { pr_debug("PM: free some memory\n"); shrink_all_memory(FREE_PAGE_NUMBER - free_pages); if (nr_free_pages() < FREE_PAGE_NUMBER) { error = -ENOMEM; printk(KERN_ERR "PM: No enough memory\n"); goto Thaw; } } if (pm_ops->prepare) { if ((error = pm_ops->prepare(state))) goto Thaw; } suspend_console(); error = device_suspend(PMSG_SUSPEND); if (error) { printk(KERN_ERR "Some devices failed to suspend\n"); goto Resume_devices; } error = disable_nonboot_cpus(); if (!error) return 0; enable_nonboot_cpus(); Resume_devices: pm_finish(state); device_resume(); resume_console(); Thaw: thaw_processes(); pm_restore_console(); return error; }
static void ambench_apbread(void) { u64 raw_counter = 0; u64 amba_counter = 0; unsigned long flags; disable_nonboot_cpus(); local_irq_save(flags); amba_clrbitsl(TIMER_CTR_REG, TIMER_CTR_EN1); amba_writel(TIMER1_STATUS_REG, APBREAD_RELOAD_NUM); amba_writel(TIMER1_RELOAD_REG, 0x0); amba_writel(TIMER1_MATCH1_REG, 0x0); amba_writel(TIMER1_MATCH2_REG, 0x0); amba_clrbitsl(TIMER_CTR_REG, TIMER_CTR_OF1); amba_clrbitsl(TIMER_CTR_REG, TIMER_CTR_CSL1); amba_setbitsl(TIMER_CTR_REG, TIMER_CTR_EN1); do { raw_counter++; } while(__raw_readl(TIMER1_STATUS_REG)); amba_clrbitsl(TIMER_CTR_REG, TIMER_CTR_EN1); amba_writel(TIMER1_STATUS_REG, APBREAD_RELOAD_NUM); amba_writel(TIMER1_RELOAD_REG, 0x0); amba_writel(TIMER1_MATCH1_REG, 0x0); amba_writel(TIMER1_MATCH2_REG, 0x0); amba_clrbitsl(TIMER_CTR_REG, TIMER_CTR_OF1); amba_clrbitsl(TIMER_CTR_REG, TIMER_CTR_CSL1); amba_setbitsl(TIMER_CTR_REG, TIMER_CTR_EN1); do { amba_counter++; } while(amba_readl(TIMER1_STATUS_REG)); amba_clrbitsl(TIMER_CTR_REG, TIMER_CTR_EN1); local_irq_restore(flags); enable_nonboot_cpus(); raw_counter *= get_apb_bus_freq_hz(); do_div(raw_counter, APBREAD_RELOAD_NUM); amba_counter *= get_apb_bus_freq_hz(); do_div(amba_counter, APBREAD_RELOAD_NUM); pr_info("CPU[0x%x] APBRead: raw speed %llu/s!\n", cpu_architecture(), raw_counter); pr_info("CPU[0x%x] APBRead: amba speed %llu/s!\n", cpu_architecture(), amba_counter); }
int hibernation_snapshot(int platform_mode) { int error; /* Free memory before shutting down devices. */ error = swsusp_shrink_memory(); if (error) return error; error = platform_start(platform_mode); if (error) return error; suspend_console(); error = device_suspend(PMSG_FREEZE); if (error) goto Resume_console; error = platform_pre_snapshot(platform_mode); if (error) goto Resume_devices; error = disable_nonboot_cpus(); if (!error) { if (hibernation_mode != HIBERNATION_TEST) { in_suspend = 1; error = create_image(platform_mode); /* Control returns here after successful restore */ } else { printk("swsusp debug: Waiting for 5 seconds.\n"); mdelay(5000); } } enable_nonboot_cpus(); Resume_devices: platform_finish(platform_mode); device_resume(); Resume_console: resume_console(); return error; }
void machine_crash_shutdown(struct pt_regs *regs) { unsigned long msecs; local_irq_disable(); disable_nonboot_cpus(); atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1); smp_call_function(machine_crash_nonpanic_core, NULL, false); msecs = 1000; /* Wait at most a second for the other cpus to stop */ while ((atomic_read(&waiting_for_crash_ipi) > 0) && msecs) { mdelay(1); msecs--; } if (atomic_read(&waiting_for_crash_ipi) > 0) pr_warn("Non-crashing CPUs did not react to IPI\n"); crash_save_cpu(regs, smp_processor_id()); machine_kexec_mask_interrupts(); pr_info("Loading crashdump kernel...\n"); }
int hibernation_restore(int platform_mode) { int error; pm_prepare_console(); suspend_console(); error = device_suspend(PMSG_PRETHAW); if (error) goto Finish; error = platform_pre_restore(platform_mode); if (!error) { error = disable_nonboot_cpus(); if (!error) error = swsusp_resume(); enable_nonboot_cpus(); } platform_restore_cleanup(platform_mode); device_resume(); Finish: resume_console(); pm_restore_console(); return error; }
static inline int snapshot_suspend(int platform_suspend) { int error; mutex_lock(&pm_mutex); /* Free memory before shutting down devices. */ error = swsusp_shrink_memory(); if (error) goto Finish; if (platform_suspend) { error = platform_prepare(); if (error) goto Finish; } suspend_console(); error = device_suspend(PMSG_FREEZE); if (error) goto Resume_devices; error = disable_nonboot_cpus(); if (!error) { in_suspend = 1; error = swsusp_suspend(); } enable_nonboot_cpus(); Resume_devices: if (platform_suspend) platform_finish(); device_resume(); resume_console(); Finish: mutex_unlock(&pm_mutex); return error; }
int hibernation_restore(int platform_mode) { int error; pm_prepare_console(); suspend_console(); error = device_suspend(PMSG_QUIESCE); if (error) goto Finish; error = platform_pre_restore(platform_mode); if (!error) { error = disable_nonboot_cpus(); if (!error) error = resume_target_kernel(); enable_nonboot_cpus(); } platform_restore_cleanup(platform_mode); device_resume(PMSG_RECOVER); Finish: resume_console(); pm_restore_console(); return error; }
/** * hibernation_platform_enter - Power off the system using the platform driver. */ int hibernation_platform_enter(void) { int error; if (!hibernation_ops) return -ENOSYS; /* * We have cancelled the power transition by running * hibernation_ops->finish() before saving the image, so we should let * the firmware know that we're going to enter the sleep state after all */ error = hibernation_ops->begin(); if (error) goto Close; entering_platform_hibernation = true; suspend_console(); error = dpm_suspend_start(PMSG_HIBERNATE); if (error) { if (hibernation_ops->recover) hibernation_ops->recover(); goto Resume_devices; } error = dpm_suspend_end(PMSG_HIBERNATE); if (error) goto Resume_devices; error = hibernation_ops->prepare(); if (error) goto Platform_finish; error = disable_nonboot_cpus(); if (error) goto Enable_cpus; local_irq_disable(); syscore_suspend(); if (pm_wakeup_pending()) { error = -EAGAIN; goto Power_up; } hibernation_ops->enter(); /* We should never get here */ while (1); Power_up: syscore_resume(); local_irq_enable(); Enable_cpus: enable_nonboot_cpus(); Platform_finish: hibernation_ops->finish(); dpm_resume_start(PMSG_RESTORE); Resume_devices: entering_platform_hibernation = false; dpm_resume_end(PMSG_RESTORE); resume_console(); Close: hibernation_ops->end(); return error; }
int __weak hibernate_resume_nonboot_cpu_disable(void) { return disable_nonboot_cpus(); }
/** * create_image - Create a hibernation image. * @platform_mode: Whether or not to use the platform driver. * * Execute device drivers' "late" and "noirq" freeze callbacks, create a * hibernation image and run the drivers' "noirq" and "early" thaw callbacks. * * Control reappears in this routine after the subsequent restore. */ static int create_image(int platform_mode) { int error; error = dpm_suspend_end(PMSG_FREEZE); if (error) { pr_err("Some devices failed to power down, aborting hibernation\n"); return error; } error = platform_pre_snapshot(platform_mode); if (error || hibernation_test(TEST_PLATFORM)) goto Platform_finish; error = disable_nonboot_cpus(); if (error || hibernation_test(TEST_CPUS)) goto Enable_cpus; local_irq_disable(); error = syscore_suspend(); if (error) { pr_err("Some system devices failed to power down, aborting hibernation\n"); goto Enable_irqs; } if (hibernation_test(TEST_CORE) || pm_wakeup_pending()) goto Power_up; in_suspend = 1; save_processor_state(); trace_suspend_resume(TPS("machine_suspend"), PM_EVENT_HIBERNATE, true); error = swsusp_arch_suspend(); /* Restore control flow magically appears here */ restore_processor_state(); trace_suspend_resume(TPS("machine_suspend"), PM_EVENT_HIBERNATE, false); if (error) pr_err("Error %d creating hibernation image\n", error); if (!in_suspend) { events_check_enabled = false; clear_free_pages(); } platform_leave(platform_mode); Power_up: syscore_resume(); Enable_irqs: local_irq_enable(); Enable_cpus: enable_nonboot_cpus(); Platform_finish: platform_finish(platform_mode); dpm_resume_start(in_suspend ? (error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE); return error; }
/** * suspend_enter - Make the system enter the given sleep state. * @state: System sleep state to enter. * @wakeup: Returns information that the sleep state should not be re-entered. * * This function should be called after devices have been suspended. */ static int suspend_enter(suspend_state_t state, bool *wakeup) { int error; if (need_suspend_ops(state) && suspend_ops->prepare) { error = suspend_ops->prepare(); if (error) goto Platform_finish; } error = dpm_suspend_end(PMSG_SUSPEND); if (error) { printk(KERN_ERR "PM: Some devices failed to power down\n"); goto Platform_finish; } if (need_suspend_ops(state) && suspend_ops->prepare_late) { error = suspend_ops->prepare_late(); if (error) goto Platform_wake; } /* * PM_SUSPEND_FREEZE equals * frozen processes + suspended devices + idle processors. * Thus we should invoke freeze_enter() soon after * all the devices are suspended. */ if (state == PM_SUSPEND_FREEZE) { freeze_enter(); goto Platform_wake; } if (suspend_test(TEST_PLATFORM)) goto Platform_wake; error = disable_nonboot_cpus(); if (error || suspend_test(TEST_CPUS)) goto Enable_cpus; arch_suspend_disable_irqs(); BUG_ON(!irqs_disabled()); error = syscore_suspend(); if (!error) { *wakeup = pm_wakeup_pending(); if (!(suspend_test(TEST_CORE) || *wakeup)) { error = suspend_ops->enter(state); events_check_enabled = false; } syscore_resume(); } arch_suspend_enable_irqs(); BUG_ON(irqs_disabled()); Enable_cpus: enable_nonboot_cpus(); Platform_wake: if (need_suspend_ops(state) && suspend_ops->wake) suspend_ops->wake(); dpm_resume_start(PMSG_RESUME); Platform_finish: if (need_suspend_ops(state) && suspend_ops->finish) suspend_ops->finish(); return error; }
/** * suspend_enter - Make the system enter the given sleep state. * @state: System sleep state to enter. * @wakeup: Returns information that the sleep state should not be re-entered. * * This function should be called after devices have been suspended. */ static int suspend_enter(suspend_state_t state, bool *wakeup) { int error; #ifdef CONFIG_SEC_GPIO_DVS /************************ Caution !!! ****************************/ /* This function must be located in appropriate SLEEP position * in accordance with the specification of each BB vendor. */ /************************ Caution !!! ****************************/ gpio_dvs_check_sleepgpio(); #ifdef SECGPIO_SLEEP_DEBUGGING /************************ Caution !!! ****************************/ /* This func. must be located in an appropriate position for GPIO SLEEP debugging * in accordance with the specification of each BB vendor, and * the func. must be called after calling the function "gpio_dvs_check_sleepgpio" */ /************************ Caution !!! ****************************/ gpio_dvs_set_sleepgpio(); #endif #endif if (suspend_ops->prepare) { error = suspend_ops->prepare(); if (error) goto Platform_finish; } error = dpm_suspend_end(PMSG_SUSPEND); if (error) { printk(KERN_ERR "PM: Some devices failed to power down\n"); goto Platform_finish; } if (suspend_ops->prepare_late) { error = suspend_ops->prepare_late(); if (error) goto Platform_wake; } if (suspend_test(TEST_PLATFORM)) goto Platform_wake; error = disable_nonboot_cpus(); if (error || suspend_test(TEST_CPUS)) goto Enable_cpus; arch_suspend_disable_irqs(); BUG_ON(!irqs_disabled()); error = syscore_suspend(); if (!error) { *wakeup = pm_wakeup_pending(); if (!(suspend_test(TEST_CORE) || *wakeup)) { error = suspend_ops->enter(state); events_check_enabled = false; } syscore_resume(); } arch_suspend_enable_irqs(); BUG_ON(irqs_disabled()); Enable_cpus: enable_nonboot_cpus(); Platform_wake: if (suspend_ops->wake) suspend_ops->wake(); dpm_resume_start(PMSG_RESUME); Platform_finish: if (suspend_ops->finish) suspend_ops->finish(); return error; }
/* 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; }
static int snapshot_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { int error = 0; struct snapshot_data *data; loff_t avail; sector_t offset; if (_IOC_TYPE(cmd) != SNAPSHOT_IOC_MAGIC) return -ENOTTY; if (_IOC_NR(cmd) > SNAPSHOT_IOC_MAXNR) return -ENOTTY; if (!capable(CAP_SYS_ADMIN)) return -EPERM; data = filp->private_data; switch (cmd) { case SNAPSHOT_FREEZE: if (data->frozen) break; mutex_lock(&pm_mutex); if (freeze_processes()) { thaw_processes(); error = -EBUSY; } mutex_unlock(&pm_mutex); if (!error) data->frozen = 1; break; case SNAPSHOT_UNFREEZE: if (!data->frozen || data->ready) break; mutex_lock(&pm_mutex); thaw_processes(); mutex_unlock(&pm_mutex); data->frozen = 0; break; case SNAPSHOT_ATOMIC_SNAPSHOT: if (data->mode != O_RDONLY || !data->frozen || data->ready) { error = -EPERM; break; } error = snapshot_suspend(data->platform_suspend); if (!error) error = put_user(in_suspend, (unsigned int __user *)arg); if (!error) data->ready = 1; break; case SNAPSHOT_ATOMIC_RESTORE: snapshot_write_finalize(&data->handle); if (data->mode != O_WRONLY || !data->frozen || !snapshot_image_loaded(&data->handle)) { error = -EPERM; break; } error = snapshot_restore(data->platform_suspend); break; case SNAPSHOT_FREE: swsusp_free(); memset(&data->handle, 0, sizeof(struct snapshot_handle)); data->ready = 0; break; case SNAPSHOT_SET_IMAGE_SIZE: image_size = arg; break; case SNAPSHOT_AVAIL_SWAP: avail = count_swap_pages(data->swap, 1); avail <<= PAGE_SHIFT; error = put_user(avail, (loff_t __user *)arg); break; case SNAPSHOT_GET_SWAP_PAGE: if (data->swap < 0 || data->swap >= MAX_SWAPFILES) { error = -ENODEV; break; } offset = alloc_swapdev_block(data->swap); if (offset) { offset <<= PAGE_SHIFT; error = put_user(offset, (sector_t __user *)arg); } else { error = -ENOSPC; } break; case SNAPSHOT_FREE_SWAP_PAGES: if (data->swap < 0 || data->swap >= MAX_SWAPFILES) { error = -ENODEV; break; } free_all_swap_pages(data->swap); break; case SNAPSHOT_SET_SWAP_FILE: if (!swsusp_swap_in_use()) { /* * User space encodes device types as two-byte values, * so we need to recode them */ if (old_decode_dev(arg)) { data->swap = swap_type_of(old_decode_dev(arg), 0, NULL); if (data->swap < 0) error = -ENODEV; } else { data->swap = -1; error = -EINVAL; } } else { error = -EPERM; } break; case SNAPSHOT_S2RAM: if (!pm_ops) { error = -ENOSYS; break; } if (!data->frozen) { error = -EPERM; break; } if (!mutex_trylock(&pm_mutex)) { error = -EBUSY; break; } if (pm_ops->prepare) { error = pm_ops->prepare(PM_SUSPEND_MEM); if (error) goto OutS3; } /* Put devices to sleep */ suspend_console(); error = device_suspend(PMSG_SUSPEND); if (error) { printk(KERN_ERR "Failed to suspend some devices.\n"); } else { error = disable_nonboot_cpus(); if (!error) { /* Enter S3, system is already frozen */ suspend_enter(PM_SUSPEND_MEM); enable_nonboot_cpus(); } /* Wake up devices */ device_resume(); } resume_console(); if (pm_ops->finish) pm_ops->finish(PM_SUSPEND_MEM); OutS3: mutex_unlock(&pm_mutex); break; case SNAPSHOT_PMOPS: error = -EINVAL; switch (arg) { case PMOPS_PREPARE: if (hibernation_ops) { data->platform_suspend = 1; error = 0; } else { error = -ENOSYS; } break; case PMOPS_ENTER: if (data->platform_suspend) { kernel_shutdown_prepare(SYSTEM_SUSPEND_DISK); error = hibernation_ops->enter(); } break; case PMOPS_FINISH: if (data->platform_suspend) error = 0; break; default: printk(KERN_ERR "SNAPSHOT_PMOPS: invalid argument %ld\n", arg); } break; case SNAPSHOT_SET_SWAP_AREA: if (swsusp_swap_in_use()) { error = -EPERM; } else { struct resume_swap_area swap_area; dev_t swdev; error = copy_from_user(&swap_area, (void __user *)arg, sizeof(struct resume_swap_area)); if (error) { error = -EFAULT; break; } /* * User space encodes device types as two-byte values, * so we need to recode them */ swdev = old_decode_dev(swap_area.dev); if (swdev) { offset = swap_area.offset; data->swap = swap_type_of(swdev, offset, NULL); if (data->swap < 0) error = -ENODEV; } else { data->swap = -1; error = -EINVAL; } } break; default: error = -ENOTTY; } return error; }
/* * Called by kexec, immediately prior to machine_kexec(). * * This must completely disable all secondary CPUs; simply causing those CPUs * to execute e.g. a RAM-based pin loop is not sufficient. This allows the * kexec'd kernel to use any and all RAM as it sees fit, without having to * avoid any code or data used by any SW CPU pin loop. The CPU hotplug * functionality embodied in disable_nonboot_cpus() to achieve this. */ void machine_shutdown(void) { disable_nonboot_cpus(); }