Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2e710321 authored by qctecmdr Service's avatar qctecmdr Service Committed by Gerrit - the friendly Code Review server
Browse files

Merge "smp: Do not wake up all idle CPUs"

parents cb7a471b 3d1defdd
Loading
Loading
Loading
Loading
+32 −11
Original line number Diff line number Diff line
@@ -950,17 +950,6 @@ static int cluster_select(struct lpm_cluster *cluster, bool from_idle,
		latency_us = pm_qos_request_for_cpumask(PM_QOS_CPU_DMA_LATENCY,
							&mask);

	/*
	 * If atleast one of the core in the cluster is online, the cluster
	 * low power modes should be determined by the idle characteristics
	 * even if the last core enters the low power mode as a part of
	 * hotplug.
	 */

	if (!from_idle && num_online_cpus() > 1 &&
		cpumask_intersects(&cluster->child_cpus, cpu_online_mask))
		from_idle = true;

	for (i = 0; i < cluster->nlevels; i++) {
		struct lpm_cluster_level *level = &cluster->levels[i];
		struct power_params *pwr_params = &level->pwr;
@@ -1408,6 +1397,30 @@ static int lpm_cpuidle_enter(struct cpuidle_device *dev,
	return idx;
}

static void lpm_cpuidle_s2idle(struct cpuidle_device *dev,
		struct cpuidle_driver *drv, int idx)
{
	struct lpm_cpu *cpu = per_cpu(cpu_lpm, dev->cpu);
	const struct cpumask *cpumask = get_cpu_mask(dev->cpu);

	for (; idx >= 0; idx--) {
		if (lpm_cpu_mode_allow(dev->cpu, idx, false))
			break;
	}
	if (idx < 0) {
		pr_err("Failed suspend\n");
		return;
	}

	cpu_prepare(cpu, idx, true);
	cluster_prepare(cpu->parent, cpumask, idx, false, 0);

	psci_enter_sleep(cpu, idx, false);

	cluster_unprepare(cpu->parent, cpumask, idx, false, 0);
	cpu_unprepare(cpu, idx, true);
}

#ifdef CONFIG_CPU_IDLE_MULTIPLE_DRIVERS
static int cpuidle_register_cpu(struct cpuidle_driver *drv,
		struct cpumask *mask)
@@ -1494,6 +1507,8 @@ static int cluster_cpuidle_register(struct lpm_cluster *cl)
			st->power_usage = cpu_level->pwr.ss_power;
			st->target_residency = 0;
			st->enter = lpm_cpuidle_enter;
			if (i == lpm_cpu->nlevels - 1)
				st->enter_s2idle = lpm_cpuidle_s2idle;
		}

		lpm_cpu->drv->state_count = lpm_cpu->nlevels;
@@ -1642,6 +1657,11 @@ static const struct platform_suspend_ops lpm_suspend_ops = {
	.wake = lpm_suspend_wake,
};

static const struct platform_s2idle_ops lpm_s2idle_ops = {
	.prepare = lpm_suspend_prepare,
	.restore = lpm_suspend_wake,
};

static int lpm_probe(struct platform_device *pdev)
{
	int ret;
@@ -1670,6 +1690,7 @@ static int lpm_probe(struct platform_device *pdev)
	 * how late lpm_levels gets initialized.
	 */
	suspend_set_ops(&lpm_suspend_ops);
	s2idle_set_ops(&lpm_s2idle_ops);
	hrtimer_init(&lpm_hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	for_each_possible_cpu(cpu) {
		cpu_histtimer = &per_cpu(histtimer, cpu);
+2 −1
Original line number Diff line number Diff line
@@ -770,6 +770,7 @@ void wake_up_all_idle_cpus(void)
		if (cpu == smp_processor_id())
			continue;

		if (!cpu_isolated(cpu))
			wake_up_if_idle(cpu);
	}
	preempt_enable();