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

Commit 652ed95d authored by Viresh Kumar's avatar Viresh Kumar Committed by Rafael J. Wysocki
Browse files

cpufreq: introduce cpufreq_generic_get() routine



CPUFreq drivers that use clock frameworks interface,i.e. clk_get_rate(),
to get CPUs clk rate, have similar sort of code used in most of them.

This patch adds a generic ->get() which will do the same thing for them.
All those drivers are required to now is to set .get to cpufreq_generic_get()
and set their clk pointer in policy->clk during ->init().

Acked-by: default avatarHans-Christian Egtvedt <egtvedt@samfundet.no>
Acked-by: default avatarShawn Guo <shawn.guo@linaro.org>
Acked-by: default avatarLinus Walleij <linus.walleij@linaro.org>
Acked-by: default avatarShawn Guo <shawn.guo@linaro.org>
Acked-by: default avatarStephen Warren <swarren@nvidia.com>
Signed-off-by: default avatarViresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent 0ad04fb3
Loading
Loading
Loading
Loading
+5 −12
Original line number Diff line number Diff line
@@ -21,17 +21,8 @@
#include <linux/export.h>
#include <linux/slab.h>

static struct clk *cpuclk;
static struct cpufreq_frequency_table *freq_table;

static unsigned int at32_get_speed(unsigned int cpu)
{
	/* No SMP support */
	if (cpu)
		return 0;
	return (unsigned int)((clk_get_rate(cpuclk) + 500) / 1000);
}

static unsigned int	ref_freq;
static unsigned long	loops_per_jiffy_ref;

@@ -39,7 +30,7 @@ static int at32_set_target(struct cpufreq_policy *policy, unsigned int index)
{
	unsigned int old_freq, new_freq;

	old_freq = at32_get_speed(0);
	old_freq = policy->cur;
	new_freq = freq_table[index].frequency;

	if (!ref_freq) {
@@ -50,7 +41,7 @@ static int at32_set_target(struct cpufreq_policy *policy, unsigned int index)
	if (old_freq < new_freq)
		boot_cpu_data.loops_per_jiffy = cpufreq_scale(
				loops_per_jiffy_ref, ref_freq, new_freq);
	clk_set_rate(cpuclk, new_freq * 1000);
	clk_set_rate(policy->clk, new_freq * 1000);
	if (new_freq < old_freq)
		boot_cpu_data.loops_per_jiffy = cpufreq_scale(
				loops_per_jiffy_ref, ref_freq, new_freq);
@@ -61,6 +52,7 @@ static int at32_set_target(struct cpufreq_policy *policy, unsigned int index)
static int at32_cpufreq_driver_init(struct cpufreq_policy *policy)
{
	unsigned int frequency, rate, min_freq;
	static struct clk *cpuclk;
	int retval, steps, i;

	if (policy->cpu != 0)
@@ -103,6 +95,7 @@ static int at32_cpufreq_driver_init(struct cpufreq_policy *policy)
		frequency /= 2;
	}

	policy->clk = cpuclk;
	freq_table[steps - 1].frequency = CPUFREQ_TABLE_END;

	retval = cpufreq_table_validate_and_show(policy, freq_table);
@@ -123,7 +116,7 @@ static struct cpufreq_driver at32_driver = {
	.init		= at32_cpufreq_driver_init,
	.verify		= cpufreq_generic_frequency_table_verify,
	.target_index	= at32_set_target,
	.get		= at32_get_speed,
	.get		= cpufreq_generic_get,
	.flags		= CPUFREQ_STICKY,
};

+2 −6
Original line number Diff line number Diff line
@@ -30,11 +30,6 @@ static struct clk *cpu_clk;
static struct regulator *cpu_reg;
static struct cpufreq_frequency_table *freq_table;

static unsigned int cpu0_get_speed(unsigned int cpu)
{
	return clk_get_rate(cpu_clk) / 1000;
}

static int cpu0_set_target(struct cpufreq_policy *policy, unsigned int index)
{
	struct dev_pm_opp *opp;
@@ -100,6 +95,7 @@ static int cpu0_set_target(struct cpufreq_policy *policy, unsigned int index)

static int cpu0_cpufreq_init(struct cpufreq_policy *policy)
{
	policy->clk = cpu_clk;
	return cpufreq_generic_init(policy, freq_table, transition_latency);
}

@@ -107,7 +103,7 @@ static struct cpufreq_driver cpu0_cpufreq_driver = {
	.flags = CPUFREQ_STICKY,
	.verify = cpufreq_generic_frequency_table_verify,
	.target_index = cpu0_set_target,
	.get = cpu0_get_speed,
	.get = cpufreq_generic_get,
	.init = cpu0_cpufreq_init,
	.exit = cpufreq_generic_exit,
	.name = "generic_cpu0",
+20 −6
Original line number Diff line number Diff line
@@ -176,6 +176,20 @@ int cpufreq_generic_init(struct cpufreq_policy *policy,
}
EXPORT_SYMBOL_GPL(cpufreq_generic_init);

unsigned int cpufreq_generic_get(unsigned int cpu)
{
	struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu);

	if (!policy || IS_ERR(policy->clk)) {
		pr_err("%s: No %s associated to cpu: %d\n", __func__,
				policy ? "clk" : "policy", cpu);
		return 0;
	}

	return clk_get_rate(policy->clk) / 1000;
}
EXPORT_SYMBOL_GPL(cpufreq_generic_get);

struct cpufreq_policy *cpufreq_cpu_get(unsigned int cpu)
{
	struct cpufreq_policy *policy = NULL;
@@ -1068,6 +1082,11 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif,
		goto err_set_policy_cpu;
	}

	write_lock_irqsave(&cpufreq_driver_lock, flags);
	for_each_cpu(j, policy->cpus)
		per_cpu(cpufreq_cpu_data, j) = policy;
	write_unlock_irqrestore(&cpufreq_driver_lock, flags);

	if (cpufreq_driver->get) {
		policy->cur = cpufreq_driver->get(policy->cpu);
		if (!policy->cur) {
@@ -1142,11 +1161,6 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif,
	}
#endif

	write_lock_irqsave(&cpufreq_driver_lock, flags);
	for_each_cpu(j, policy->cpus)
		per_cpu(cpufreq_cpu_data, j) = policy;
	write_unlock_irqrestore(&cpufreq_driver_lock, flags);

	if (!frozen) {
		ret = cpufreq_add_dev_interface(policy, dev);
		if (ret)
@@ -1174,12 +1188,12 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif,
	return 0;

err_out_unregister:
err_get_freq:
	write_lock_irqsave(&cpufreq_driver_lock, flags);
	for_each_cpu(j, policy->cpus)
		per_cpu(cpufreq_cpu_data, j) = NULL;
	write_unlock_irqrestore(&cpufreq_driver_lock, flags);

err_get_freq:
	if (cpufreq_driver->exit)
		cpufreq_driver->exit(policy);
err_set_policy_cpu:
+4 −10
Original line number Diff line number Diff line
@@ -58,14 +58,6 @@ static int davinci_verify_speed(struct cpufreq_policy *policy)
	return 0;
}

static unsigned int davinci_getspeed(unsigned int cpu)
{
	if (cpu)
		return 0;

	return clk_get_rate(cpufreq.armclk) / 1000;
}

static int davinci_target(struct cpufreq_policy *policy, unsigned int idx)
{
	struct davinci_cpufreq_config *pdata = cpufreq.dev->platform_data;
@@ -73,7 +65,7 @@ static int davinci_target(struct cpufreq_policy *policy, unsigned int idx)
	unsigned int old_freq, new_freq;
	int ret = 0;

	old_freq = davinci_getspeed(0);
	old_freq = policy->cur;
	new_freq = pdata->freq_table[idx].frequency;

	/* if moving to higher frequency, up the voltage beforehand */
@@ -116,6 +108,8 @@ static int davinci_cpu_init(struct cpufreq_policy *policy)
			return result;
	}

	policy->clk = cpufreq.armclk;

	/*
	 * Time measurement across the target() function yields ~1500-1800us
	 * time taken with no drivers on notification list.
@@ -129,7 +123,7 @@ static struct cpufreq_driver davinci_driver = {
	.flags		= CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK,
	.verify		= davinci_verify_speed,
	.target_index	= davinci_target,
	.get		= davinci_getspeed,
	.get		= cpufreq_generic_get,
	.init		= davinci_cpu_init,
	.exit		= cpufreq_generic_exit,
	.name		= "davinci",
+2 −17
Original line number Diff line number Diff line
@@ -26,24 +26,9 @@ static int dbx500_cpufreq_target(struct cpufreq_policy *policy,
	return clk_set_rate(armss_clk, freq_table[index].frequency * 1000);
}

static unsigned int dbx500_cpufreq_getspeed(unsigned int cpu)
{
	int i = 0;
	unsigned long freq = clk_get_rate(armss_clk) / 1000;

	/* The value is rounded to closest frequency in the defined table. */
	while (freq_table[i + 1].frequency != CPUFREQ_TABLE_END) {
		if (freq < freq_table[i].frequency +
		   (freq_table[i + 1].frequency - freq_table[i].frequency) / 2)
			return freq_table[i].frequency;
		i++;
	}

	return freq_table[i].frequency;
}

static int dbx500_cpufreq_init(struct cpufreq_policy *policy)
{
	policy->clk = armss_clk;
	return cpufreq_generic_init(policy, freq_table, 20 * 1000);
}

@@ -52,7 +37,7 @@ static struct cpufreq_driver dbx500_cpufreq_driver = {
			CPUFREQ_NEED_INITIAL_FREQ_CHECK,
	.verify = cpufreq_generic_frequency_table_verify,
	.target_index = dbx500_cpufreq_target,
	.get    = dbx500_cpufreq_getspeed,
	.get    = cpufreq_generic_get,
	.init   = dbx500_cpufreq_init,
	.name   = "DBX500",
	.attr   = cpufreq_generic_attr,
Loading