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

Commit dca690e7 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "lpm-levels: Add QCOM cpuidle governor"

parents f5c14a0f a5887ccd
Loading
Loading
Loading
Loading
+45 −18
Original line number Diff line number Diff line
@@ -294,7 +294,7 @@ static int set_device_mode(struct lpm_cluster *cluster, int ndevice,
}

static int cpu_power_select(struct cpuidle_device *dev,
		struct lpm_cpu *cpu, int *index)
		struct lpm_cpu *cpu)
{
	int best_level = -1;
	uint32_t latency_us = pm_qos_request_for_cpu(PM_QOS_CPU_DMA_LATENCY,
@@ -806,15 +806,16 @@ bool psci_enter_sleep(struct lpm_cluster *cluster, int idx, bool from_idle)
}
#endif

static int lpm_cpuidle_enter(struct cpuidle_device *dev,
		struct cpuidle_driver *drv, int index)
static int lpm_cpuidle_select(struct cpuidle_driver *drv,
		struct cpuidle_device *dev)
{
	struct lpm_cluster *cluster = per_cpu(cpu_cluster, dev->cpu);
	int64_t time = ktime_to_ns(ktime_get());
	bool success = true;
	int idx = cpu_power_select(dev, cluster->cpu, &index);
	const struct cpumask *cpumask = get_cpu_mask(dev->cpu);
	struct power_params *pwr_params;
	int idx;

	if (!cluster)
		return 0;

	idx = cpu_power_select(dev, cluster->cpu);

	if (idx < 0) {
		local_irq_enable();
@@ -822,25 +823,35 @@ static int lpm_cpuidle_enter(struct cpuidle_device *dev,
	}

	trace_cpu_idle_rcuidle(idx, dev->cpu);
	return idx;
}

static int lpm_cpuidle_enter(struct cpuidle_device *dev,
		struct cpuidle_driver *drv, int idx)
{
	struct lpm_cluster *cluster = per_cpu(cpu_cluster, dev->cpu);
	bool success = true;
	const struct cpumask *cpumask = get_cpu_mask(dev->cpu);
	int64_t start_time = ktime_to_ns(ktime_get()), end_time;
	struct power_params *pwr_params;

	pwr_params = &cluster->cpu->levels[idx].pwr;
	sched_set_cpu_cstate(smp_processor_id(), idx + 1,
		pwr_params->energy_overhead, pwr_params->latency_us);

	trace_cpu_idle_enter(idx);

	cpu_prepare(cluster, idx, true);
	cluster_prepare(cluster, cpumask, idx, true);
	lpm_stats_cpu_enter(idx);

	if (need_resched() || (idx < 0))
		goto exit;

	trace_cpu_idle_enter(idx);
	lpm_stats_cpu_enter(idx);

	if (!use_psci) {
		if (idx > 0)
			update_debug_pc_event(CPU_ENTER, idx, 0xdeaffeed,
					0xdeaffeed, true);

		success = msm_cpu_pm_enter_sleep(cluster->cpu->levels[idx].mode,
				true);

@@ -857,13 +868,12 @@ exit:
	cpu_unprepare(cluster, idx, true);

	sched_set_cpu_cstate(smp_processor_id(), 0, 0, 0);

	time = ktime_to_ns(ktime_get()) - time;
	do_div(time, 1000);
	dev->last_residency = (int)time;
	trace_cpu_idle_exit(idx, success);
	trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, dev->cpu);
	end_time = ktime_to_ns(ktime_get()) - start_time;
	dev->last_residency = do_div(end_time, 1000);
	local_irq_enable();

	return idx;
}

@@ -910,6 +920,13 @@ static int cpuidle_register_cpu(struct cpuidle_driver *drv,
}
#endif

static struct cpuidle_governor lpm_governor = {
	.name =		"qcom",
	.rating =	30,
	.select =	lpm_cpuidle_select,
	.owner =	THIS_MODULE,
};

static int cluster_cpuidle_register(struct lpm_cluster *cl)
{
	int i = 0, ret = 0;
@@ -971,10 +988,19 @@ static int cluster_cpuidle_register(struct lpm_cluster *cl)
		kfree(cl->drv);
		return -ENOMEM;
	}

	return 0;
}

/**
 * init_lpm - initializes the governor
 */
static int __init init_lpm(void)
{
	return cpuidle_register_governor(&lpm_governor);
}

postcore_initcall(init_lpm);

static void register_cpu_lpm_stats(struct lpm_cpu *cpu,
		struct lpm_cluster *parent)
{
@@ -1299,3 +1325,4 @@ void lpm_cpu_hotplug_enter(unsigned int cpu)
	msm_cpu_pm_enter_sleep(mode, false);
}