/* * arm_enter_idle_state - Programs CPU to enter the specified state * * @dev: cpuidle device * @drv: cpuidle driver * @idx: state index * * Called from the CPUidle framework to program the device to the * specified target state selected by the governor. */ static int arm_enter_idle_state(struct cpuidle_device *dev, struct cpuidle_driver *drv, int idx) { int ret = 0; struct timeval start_time, end_time; long usec_elapsed; if (cpuidle_debug) { do_gettimeofday(&start_time); } switch (idx) { case STANDBY: cpu_do_idle(); break; case L_SLEEP: light_sleep_en(); cpu_do_idle(); light_sleep_dis(); break; case CORE_PD: light_sleep_en(); cpu_pm_enter(); ret = cpu_suspend(idx); cpu_pm_exit(); light_sleep_dis(); break; case CLUSTER_PD: light_sleep_en(); cpu_pm_enter(); cpu_cluster_pm_enter(); ret = cpu_suspend(idx); cpu_cluster_pm_exit(); cpu_pm_exit(); light_sleep_dis(); break; #ifdef CONFIG_ARCH_SCX35LT8 case TOP_PD: light_sleep_en(); cpu_pm_enter(); cpu_cluster_pm_enter(); ret = cpu_suspend(idx); cpu_cluster_pm_exit(); cpu_pm_exit(); light_sleep_dis(); break; #endif default: cpu_do_idle(); WARN(1, "[CPUIDLE]: NO THIS IDLE LEVEL!!!"); } if (cpuidle_debug) { do_gettimeofday(&end_time); usec_elapsed = (end_time.tv_sec - start_time.tv_sec) * 1000000 + (end_time.tv_usec - start_time.tv_usec); pr_info("[CPUIDLE] Enter idle state: %d ,usec_elapsed = %ld \n", idx, usec_elapsed); } return ret ? -1 : idx; }
/* * Save the current CPU state before suspend / poweroff. */ int notrace swsusp_arch_suspend(void) { #ifdef CONFIG_MTK_HIBERNATION int retval = 0; retval = cpu_suspend(0, arch_save_image); if (swsusp_saved) retval = 0; return retval; #else return cpu_suspend(0, arch_save_image); #endif }
/* * bl_enter_powerdown - Programs CPU to enter the specified state * @dev: cpuidle device * @drv: The target state to be programmed * @idx: state index * * Called from the CPUidle framework to program the device to the * specified target state selected by the governor. */ static int bl_enter_powerdown(struct cpuidle_device *dev, struct cpuidle_driver *drv, int idx) { struct timespec ts_preidle, ts_postidle, ts_idle; int ret; /* Used to keep track of the total time in idle */ getnstimeofday(&ts_preidle); BUG_ON(!irqs_disabled()); cpu_pm_enter(); clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &dev->cpu); ret = cpu_suspend((unsigned long) dev, bl_powerdown_finisher); if (ret) BUG(); mcpm_cpu_powered_up(); clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu); cpu_pm_exit(); getnstimeofday(&ts_postidle); local_irq_enable(); ts_idle = timespec_sub(ts_postidle, ts_preidle); dev->last_residency = ts_idle.tv_nsec / NSEC_PER_USEC + ts_idle.tv_sec * USEC_PER_SEC; return idx; }
/* static int notrace mcpm_powerdown_finisher(unsigned long arg) { u32 mpidr = read_cpuid_mpidr(); u32 cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0); u32 this_cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1); mcpm_set_entry_vector(cpu, this_cluster, cpu_resume); mcpm_cpu_suspend(arg); return 1; } */ static int mmp_pm_enter(suspend_state_t state) { unsigned int real_idx = mmp_suspend->suspend_state; #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(); #endif if (mmp_suspend->ops->pre_suspend_check) { if (mmp_suspend->ops->pre_suspend_check()) return -EAGAIN; } cpu_suspend((unsigned long)&real_idx); if (mmp_suspend->ops->post_chk_wakeup) detect_wakeup_status = mmp_suspend->ops->post_chk_wakeup(); if (mmp_suspend->ops->post_clr_wakeup) mmp_suspend->ops->post_clr_wakeup(detect_wakeup_status); if (real_idx != mmp_suspend->suspend_state) pr_info("WARNING!!! Suspend Didn't enter the Expected Low power mode\n"); mcpm_cpu_powered_up(); return 0; }
static int hi6xxx_pm_enter(suspend_state_t state) { //volatile int wait_loop = 600000; pr_info("%s ++\n", __func__); //while(wait_loop >= 0) // wait_loop--; cpu_pm_enter(); /* setup_mm_for_reboot(); gic_cpu_if_down(); hisi_cluster_exit_coherence(0); */ hisi_set_acpu_subsys_powerdown_flag(); cpu_suspend(3); hisi_clear_acpu_subsys_powerdown_flag(); //coherent_init(); //coherent_slave_port_config(); cpu_pm_exit(); g_pwcAcpuWakeFlagIcc = 1; g_pwcAcpuWakeFlagRfile = 1; pr_info("%s --\n", __func__); pwrctrl_mcu_debug_info_show(); pwrctrl_ccpu_debug_info_show(); return 0; }
static int imx6sx_enter_wait(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index) { imx6q_set_lpm(WAIT_UNCLOCKED); switch (index) { case 1: cpu_do_idle(); break; case 2: imx6_enable_rbc(true); imx_gpc_set_arm_power_in_lpm(true); imx_set_cpu_jump(0, v7_cpu_resume); /* Need to notify there is a cpu pm operation. */ cpu_pm_enter(); cpu_cluster_pm_enter(); cpu_suspend(0, imx6sx_idle_finish); cpu_cluster_pm_exit(); cpu_pm_exit(); imx_gpc_set_arm_power_in_lpm(false); imx6_enable_rbc(false); break; default: break; } imx6q_set_lpm(WAIT_CLOCKED); return index; }
static int sunxi_cpu_power_down_c2state(struct cpuidle_device *dev, \ struct cpuidle_driver *drv, \ int index) { unsigned int mpidr = read_cpuid_mpidr(); unsigned int cluster = MPIDR_AFFINITY_LEVEL(mpidr, 1); unsigned int cpu = MPIDR_AFFINITY_LEVEL(mpidr, 0); cpu_pm_enter(); //cpu_cluster_pm_enter(); clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &dev->cpu); smp_wmb(); cpu_suspend(CPUIDLE_FLAG_C2_STATE, sunxi_powerdown_c2_finisher); /* * Since this is called with IRQs enabled, and no arch_spin_lock_irq * variant exists, we need to disable IRQs manually here. */ local_irq_disable(); arch_spin_lock(&sun8i_mcpm_lock); sun8i_cpu_use_count[cluster][cpu]++; sun8i_cluster_use_count[cluster]++; arch_spin_unlock(&sun8i_mcpm_lock); local_irq_enable(); clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu); //cpu_cluster_pm_exit(); cpu_pm_exit(); return index; }
static int sa11x0_pm_enter(suspend_state_t state) { unsigned long gpio, sleep_save[SLEEP_SAVE_COUNT]; gpio = GPLR; /* save vital registers */ SAVE(GPDR); SAVE(GAFR); SAVE(PPDR); SAVE(PPSR); SAVE(PPAR); SAVE(PSDR); SAVE(Ser1SDCR0); /* Clear previous reset status */ RCSR = RCSR_HWR | RCSR_SWR | RCSR_WDR | RCSR_SMR; /* set resume return address */ PSPR = virt_to_phys(cpu_resume); /* go zzz */ cpu_suspend(0, sa1100_finish_suspend); /* * Ensure not to come back here if it wasn't intended */ PSPR = 0; /* * Ensure interrupt sources are disabled; we will re-init * the interrupt subsystem via the device manager. */ ICLR = 0; ICCR = 1; ICMR = 0; /* restore registers */ RESTORE(GPDR); RESTORE(GAFR); RESTORE(PPDR); RESTORE(PPSR); RESTORE(PPAR); RESTORE(PSDR); RESTORE(Ser1SDCR0); GPSR = gpio; GPCR = ~gpio; /* * Clear the peripheral sleep-hold bit. */ PSSR = PSSR_PH; return 0; }
static int tegra114_idle_power_down(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index) { local_fiq_disable(); tegra_set_cpu_in_lp2(); cpu_pm_enter(); clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &dev->cpu); call_firmware_op(prepare_idle); /* Do suspend by ourselves if the firmware does not implement it */ if (call_firmware_op(do_idle) == -ENOSYS) cpu_suspend(0, tegra30_sleep_cpu_secondary_finish); clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu); cpu_pm_exit(); tegra_clear_cpu_in_lp2(); local_fiq_enable(); return index; }
static int tango_pm_enter(suspend_state_t state) { if (state == PM_SUSPEND_MEM) return cpu_suspend(0, tango_pm_powerdown); return -EINVAL; }
static int calxeda_pwrdown_idle(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index) { cpu_pm_enter(); cpu_suspend(0, calxeda_idle_finish); cpu_pm_exit(); return index; }
/* * Save the current CPU state before suspend / poweroff. */ int notrace swsusp_arch_suspend(void) { int retval = 0; retval = cpu_suspend(0, __swsusp_arch_save_image); if (swsusp_saved) retval = 0; return retval; }
static void pxa25x_cpu_pm_enter(suspend_state_t state) { /* Clear reset status */ RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR; switch (state) { case PM_SUSPEND_MEM: cpu_suspend(PWRMODE_SLEEP, pxa25x_finish_suspend); break; } }
static int exynos_suspend(void) { if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9) exynos_save_cp15(); writel(EXYNOS_SLEEP_MAGIC, sysram_ns_base_addr + EXYNOS_BOOT_FLAG); writel(virt_to_phys(exynos_cpu_resume_ns), sysram_ns_base_addr + EXYNOS_BOOT_ADDR); return cpu_suspend(0, exynos_cpu_suspend); }
static int __maybe_unused cpu_psci_cpu_suspend(unsigned long index) { int ret; u32 *state = __this_cpu_read(psci_power_state); /* * idle state index 0 corresponds to wfi, should never be called * from the cpu_suspend operations */ if (WARN_ON_ONCE(!index)) return -EINVAL; if (unlikely(index >= PSCI_UNUSED_INDEX)) return cpu_suspend(index, psci_suspend_customized_finisher); if (!psci_power_state_loses_context(state[index - 1])) ret = psci_ops.cpu_suspend(state[index - 1], 0); else ret = cpu_suspend(index, psci_suspend_finisher); return ret; }
void tegra_idle_lp2_last(void) { tegra_pmc_pm_set(TEGRA_SUSPEND_LP2); cpu_cluster_pm_enter(); suspend_cpu_complex(); cpu_suspend(PHYS_OFFSET - PAGE_OFFSET, &tegra_sleep_cpu); restore_cpu_complex(); cpu_cluster_pm_exit(); }
static int am33xx_pm_suspend(void) { int state, ret = 0; struct omap_hwmod *cpgmac_oh, *gpmc_oh, *usb_oh; cpgmac_oh = omap_hwmod_lookup("cpgmac0"); usb_oh = omap_hwmod_lookup("usb_otg_hs"); gpmc_oh = omap_hwmod_lookup("gpmc"); omap_hwmod_enable(cpgmac_oh); omap_hwmod_enable(usb_oh); omap_hwmod_enable(gpmc_oh); omap_hwmod_idle(cpgmac_oh); omap_hwmod_idle(usb_oh); omap_hwmod_idle(gpmc_oh); if (gfx_l3_clkdm && gfx_l4ls_clkdm) { clkdm_sleep(gfx_l3_clkdm); clkdm_sleep(gfx_l4ls_clkdm); } /* Try to put GFX to sleep */ if (gfx_pwrdm) pwrdm_set_next_pwrst(gfx_pwrdm, PWRDM_POWER_OFF); else pr_err("Could not program GFX to low power state\n"); writel(0x0, AM33XX_CM_MPU_MPU_CLKCTRL); ret = cpu_suspend(0, am33xx_do_sram_idle); writel(0x2, AM33XX_CM_MPU_MPU_CLKCTRL); if (gfx_pwrdm) { state = pwrdm_read_pwrst(gfx_pwrdm); if (state != PWRDM_POWER_OFF) pr_err("GFX domain did not transition to low power state\n"); else pr_info("GFX domain entered low power state\n"); } /* XXX: Why do we need to wakeup the clockdomains? */ if(gfx_l3_clkdm && gfx_l4ls_clkdm) { clkdm_wakeup(gfx_l3_clkdm); clkdm_wakeup(gfx_l4ls_clkdm); } core_suspend_stat = ret; return ret; }
bool emu_suspend(const char *file) { gui_busy_raii gui_busy; FILE *fp = fopen_utf8(file, "wb"); if(!fp) return false; int dupfd = dup(fileno(fp)); fclose(fp); fp = nullptr; // gzdopen takes ownership of the fd gzFile gzf = gzdopen(dupfd, "wb"); if(!gzf) { close(dupfd); return false; } size_t size = sizeof(emu_snapshot) + flash_suspend_flexsize(); auto snapshot = (struct emu_snapshot *) malloc(size); if(!snapshot) { gzclose(gzf); return false; } snapshot->product = product; snapshot->asic_user_flags = asic_user_flags; // TODO: Max length strncpy(snapshot->path_boot1, path_boot1.c_str(), sizeof(snapshot->path_boot1) - 1); strncpy(snapshot->path_flash, path_flash.c_str(), sizeof(snapshot->path_flash) - 1); if(!flash_suspend(snapshot) || !cpu_suspend(snapshot) || !sched_suspend(snapshot) || !memory_suspend(snapshot)) { free(snapshot); gzclose(gzf); return false; } snapshot->sig = SNAPSHOT_SIG; snapshot->version = SNAPSHOT_VER; bool success = (size_t) gzwrite(gzf, snapshot, size) == size; free(snapshot); gzclose(gzf); return success; }
static int zynqmp_pm_enter(suspend_state_t suspend_state) { switch (suspend_state) { case PM_SUSPEND_STANDBY: case PM_SUSPEND_MEM: cpu_suspend(0); break; default: return -EINVAL; } return 0; }
static bool tegra30_cpu_core_power_down(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index) { tick_broadcast_enter(); smp_wmb(); cpu_suspend(0, tegra30_sleep_cpu_secondary_finish); tick_broadcast_exit(); return true; }
/** * bl_enter_powerdown - Programs CPU to enter the specified state * @dev: cpuidle device * @drv: The target state to be programmed * @idx: state index * * Called from the CPUidle framework to program the device to the * specified target state selected by the governor. */ static int bl_enter_powerdown(struct cpuidle_device *dev, struct cpuidle_driver *drv, int idx) { cpu_pm_enter(); cpu_suspend(0, bl_powerdown_finisher); /* signals the MCPM core that CPU is out of low power state */ mcpm_cpu_powered_up(); cpu_pm_exit(); return idx; }
static int sunxi_cpu_core_power_down(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index) { cpu_pm_enter(); clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &dev->cpu); smp_wmb(); cpu_suspend(0, sunxi_powerdown_finisher); clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu); cpu_pm_exit(); return index; }
static bool tegra30_cpu_core_power_down(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index) { clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &dev->cpu); smp_wmb(); cpu_suspend(0, tegra30_sleep_cpu_secondary_finish); clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu); return true; }
static bool tegra20_idle_enter_lp2_cpu_1(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index) { clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &dev->cpu); cpu_suspend(0, tegra20_sleep_cpu_secondary_finish); tegra20_cpu_clear_resettable(); clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu); return true; }
static int sa11x0_pm_enter(suspend_state_t state) { unsigned long gpio, sleep_save[SLEEP_SAVE_COUNT]; gpio = GPLR; SAVE(GPDR); SAVE(GAFR); SAVE(PPDR); SAVE(PPSR); SAVE(PPAR); SAVE(PSDR); SAVE(Ser1SDCR0); RCSR = RCSR_HWR | RCSR_SWR | RCSR_WDR | RCSR_SMR; PSPR = virt_to_phys(cpu_resume); cpu_suspend(0, sa1100_finish_suspend); PSPR = 0; ICLR = 0; ICCR = 1; ICMR = 0; RESTORE(GPDR); RESTORE(GAFR); RESTORE(PPDR); RESTORE(PPSR); RESTORE(PPAR); RESTORE(PSDR); RESTORE(Ser1SDCR0); GPSR = gpio; GPCR = ~gpio; PSSR = PSSR_PH; return 0; }
static int sirfsoc_pm_enter(suspend_state_t state) { switch (state) { case PM_SUSPEND_MEM: sirfsoc_pre_suspend_power_off(); outer_disable(); /* go zzz */ cpu_suspend(0, sirfsoc_finish_suspend); outer_resume(); break; default: return -EINVAL; } return 0; }
static int highbank_pm_enter(suspend_state_t state) { cpu_pm_enter(); cpu_cluster_pm_enter(0); highbank_set_cpu_jump(0, cpu_resume); cpu_suspend(0, highbank_suspend_finish); cpu_cluster_pm_exit(0); cpu_pm_exit(); highbank_smc1(0x102, 0x1); if (scu_base_addr) scu_enable(scu_base_addr); return 0; }
static int am33xx_pm_suspend(unsigned int state) { int i, ret = 0; struct wkup_m3_wakeup_src wakeup_src; omap_set_pwrdm_state(gfx_pwrdm, PWRDM_POWER_OFF); am33xx_pm->ops->pre_suspend(state); ret = cpu_suspend((long unsigned int) &susp_params, am33xx_do_sram_idle); am33xx_pm->ops->post_suspend(state); if (ret) { pr_err("PM: Kernel suspend failure\n"); } else { i = wkup_m3_pm_status(); switch (i) { case 0: pr_info("PM: Successfully put all powerdomains to target state\n"); /* * The PRCM registers on AM335x do not contain * previous state information like those present on * OMAP4 so we must manually indicate transition so * state counters are properly incremented */ pwrdm_post_transition(mpu_pwrdm); pwrdm_post_transition(per_pwrdm); break; case 1: pr_err("PM: Could not transition all powerdomains to target state\n"); ret = -1; break; default: pr_err("PM: CM3 returned unknown result = %d\n", i); ret = -1; } /* print the wakeup reason */ wakeup_src = wkup_m3_wake_src(); pr_info("PM: Wakeup source %s\n", wakeup_src.src); } return ret; }
int psci_cpu_suspend_enter(unsigned long index) { int ret; u32 *state = __this_cpu_read(psci_power_state); /* * idle state index 0 corresponds to wfi, should never be called * from the cpu_suspend operations */ if (WARN_ON_ONCE(!index)) return -EINVAL; if (!psci_power_state_loses_context(state[index - 1])) ret = psci_ops.cpu_suspend(state[index - 1], 0); else ret = cpu_suspend(index, psci_suspend_finisher); return ret; }
static int imx6q_pm_enter(suspend_state_t state) { switch (state) { case PM_SUSPEND_MEM: imx6q_set_lpm(STOP_POWER_OFF); imx_gpc_pre_suspend(); imx_set_cpu_jump(0, v7_cpu_resume); /* Zzz ... */ cpu_suspend(0, imx6q_suspend_finish); imx_smp_prepare(); imx_gpc_post_resume(); break; default: return -EINVAL; } return 0; }