/*
 * 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;
}
Пример #2
0
/*
 * 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
}
Пример #3
0
/*
 * 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;
}
Пример #6
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;
}
Пример #7
0
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;
}
Пример #8
0
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;
}
Пример #9
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;
}
Пример #10
0
static int tango_pm_enter(suspend_state_t state)
{
	if (state == PM_SUSPEND_MEM)
		return cpu_suspend(0, tango_pm_powerdown);

	return -EINVAL;
}
Пример #11
0
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;
}
Пример #12
0
/*
 * 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;
}
Пример #13
0
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;
	}
}
Пример #14
0
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;
}
Пример #16
0
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();
}
Пример #17
0
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;
}
Пример #18
0
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;
}
Пример #19
0
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;
}
Пример #20
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;
}
Пример #21
0
/**
 * 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;
}
Пример #22
0
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;
}
Пример #23
0
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;
}
Пример #24
0
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;
}
Пример #25
0
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;
}
Пример #26
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;
}
Пример #27
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;
}
Пример #28
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;
}
Пример #29
0
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;
}
Пример #30
0
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;
}