예제 #1
0
static int exynos_enter_coupled_lowpower(struct cpuidle_device *dev,
					 struct cpuidle_driver *drv,
					 int index)
{
	int ret;

	exynos_cpuidle_pdata->pre_enter_aftr();

	/*
	 * Waiting all cpus to reach this point at the same moment
	 */
	cpuidle_coupled_parallel_barrier(dev, &exynos_idle_barrier);

	/*
	 * Both cpus will reach this point at the same time
	 */
	ret = dev->cpu ? exynos_cpuidle_pdata->cpu1_powerdown()
		       : exynos_cpuidle_pdata->cpu0_enter_aftr();
	if (ret)
		index = ret;

	/*
	 * Waiting all cpus to finish the power sequence before going further
	 */
	cpuidle_coupled_parallel_barrier(dev, &exynos_idle_barrier);

	exynos_cpuidle_pdata->post_enter_aftr();

	return index;
}
예제 #2
0
static int tegra20_idle_lp2_coupled(struct cpuidle_device *dev,
				    struct cpuidle_driver *drv,
				    int index)
{
	u32 cpu = is_smp() ? cpu_logical_map(dev->cpu) : dev->cpu;
	bool entered_lp2 = false;

	if (tegra_pending_sgi())
		ACCESS_ONCE_RW(abort_flag) = true;

	cpuidle_coupled_parallel_barrier(dev, &abort_barrier);

	if (abort_flag) {
		cpuidle_coupled_parallel_barrier(dev, &abort_barrier);
		abort_flag = false;	/* clean flag for next coming */
		return -EINTR;
	}

	local_fiq_disable();

	tegra_set_cpu_in_lp2(cpu);
	cpu_pm_enter();

	if (cpu == 0)
		entered_lp2 = tegra20_cpu_cluster_power_down(dev, drv, index);
	else
		entered_lp2 = tegra20_idle_enter_lp2_cpu_1(dev, drv, index);

	cpu_pm_exit();
	tegra_clear_cpu_in_lp2(cpu);

	local_fiq_enable();

	smp_rmb();

	return entered_lp2 ? index : 0;
}