Commit 9c0ebcf7 authored by Viresh Kumar's avatar Viresh Kumar Committed by Rafael J. Wysocki

cpufreq: Implement light weight ->target_index() routine

Currently, the prototype of cpufreq_drivers target routines is:

int target(struct cpufreq_policy *policy, unsigned int target_freq,
		unsigned int relation);

And most of the drivers call cpufreq_frequency_table_target() to get a valid
index of their frequency table which is closest to the target_freq. And they
don't use target_freq and relation after that.

So, it makes sense to just do this work in cpufreq core before calling
cpufreq_frequency_table_target() and simply pass index instead. But this can be
done only with drivers which expose their frequency table with cpufreq core. For
others we need to stick with the old prototype of target() until those drivers
are converted to expose frequency tables.

This patch implements the new light weight prototype for target_index() routine.
It looks like this:

int target_index(struct cpufreq_policy *policy, unsigned int index);

CPUFreq core will call cpufreq_frequency_table_target() before calling this
routine and pass index to it. Because CPUFreq core now requires to call routines
present in freq_table.c CONFIG_CPU_FREQ_TABLE must be enabled all the time.

This also marks target() interface as deprecated. So, that new drivers avoid
using it. And Documentation is updated accordingly.

It also converts existing .target() to newly defined light weight
.target_index() routine for many driver.
Acked-by: default avatarHans-Christian Egtvedt <egtvedt@samfundet.no>
Acked-by: default avatarJesper Nilsson <jesper.nilsson@axis.com>
Acked-by: Linus Walleij's avatarLinus Walleij <linus.walleij@linaro.org>
Acked-by: default avatarRussell King <linux@arm.linux.org.uk>
Acked-by: default avatarDavid S. Miller <davem@davemloft.net>
Tested-by: default avatarAndrew Lunn <andrew@lunn.ch>
Signed-off-by: default avatarViresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: default avatarRafael J. Wysocki <rjw@rjwysocki.net>
parent 6ddee424
......@@ -23,8 +23,8 @@ Contents:
1.1 Initialization
1.2 Per-CPU Initialization
1.3 verify
1.4 target or setpolicy?
1.5 target
1.4 target/target_index or setpolicy?
1.5 target/target_index
1.6 setpolicy
2. Frequency Table Helpers
......@@ -56,7 +56,8 @@ cpufreq_driver.init - A pointer to the per-CPU initialization
cpufreq_driver.verify - A pointer to a "verification" function.
cpufreq_driver.setpolicy _or_
cpufreq_driver.target - See below on the differences.
cpufreq_driver.target/
target_index - See below on the differences.
And optionally
......@@ -66,7 +67,7 @@ cpufreq_driver.resume - A pointer to a per-CPU resume function
which is called with interrupts disabled
and _before_ the pre-suspend frequency
and/or policy is restored by a call to
->target or ->setpolicy.
->target/target_index or ->setpolicy.
cpufreq_driver.attr - A pointer to a NULL-terminated list of
"struct freq_attr" which allow to
......@@ -103,8 +104,8 @@ policy->governor must contain the "default policy" for
this CPU. A few moments later,
cpufreq_driver.verify and either
cpufreq_driver.setpolicy or
cpufreq_driver.target is called with
these values.
cpufreq_driver.target/target_index is called
with these values.
For setting some of these values (cpuinfo.min[max]_freq, policy->min[max]), the
frequency table helpers might be helpful. See the section 2 for more information
......@@ -133,20 +134,28 @@ range) is within policy->min and policy->max. If necessary, increase
policy->max first, and only if this is no solution, decrease policy->min.
1.4 target or setpolicy?
1.4 target/target_index or setpolicy?
----------------------------
Most cpufreq drivers or even most cpu frequency scaling algorithms
only allow the CPU to be set to one frequency. For these, you use the
->target call.
->target/target_index call.
Some cpufreq-capable processors switch the frequency between certain
limits on their own. These shall use the ->setpolicy call
1.4. target
1.4. target/target_index
-------------
The target_index call has two arguments: struct cpufreq_policy *policy,
and unsigned int index (into the exposed frequency table).
The CPUfreq driver must set the new frequency when called here. The
actual frequency must be determined by freq_table[index].frequency.
Deprecated:
----------
The target call has three arguments: struct cpufreq_policy *policy,
unsigned int target_frequency, unsigned int relation.
......
......@@ -40,7 +40,7 @@ Most cpufreq drivers (in fact, all except one, longrun) or even most
cpu frequency scaling algorithms only offer the CPU to be set to one
frequency. In order to offer dynamic frequency scaling, the cpufreq
core must be able to tell these drivers of a "target frequency". So
these specific drivers will be transformed to offer a "->target"
these specific drivers will be transformed to offer a "->target/target_index"
call instead of the existing "->setpolicy" call. For "longrun", all
stays the same, though.
......@@ -71,7 +71,7 @@ CPU can be set to switch independently | CPU can only be set
/ the limits of policy->{min,max}
/ \
/ \
Using the ->setpolicy call, Using the ->target call,
Using the ->setpolicy call, Using the ->target/target_index call,
the limits and the the frequency closest
"policy" is set. to target_freq is set.
It is assured that it
......
......@@ -62,26 +62,6 @@ struct cpufreq_frequency_table sa11x0_freq_table[NR_FREQS+1] = {
{ .frequency = CPUFREQ_TABLE_END, },
};
/* rounds up(!) */
unsigned int sa11x0_freq_to_ppcr(unsigned int khz)
{
int i;
for (i = 0; i < NR_FREQS; i++)
if (sa11x0_freq_table[i].frequency >= khz)
break;
return i;
}
unsigned int sa11x0_ppcr_to_freq(unsigned int idx)
{
unsigned int freq = 0;
if (idx < NR_FREQS)
freq = sa11x0_freq_table[idx].frequency;
return freq;
}
unsigned int sa11x0_getspeed(unsigned int cpu)
{
if (cpu)
......
......@@ -21,9 +21,7 @@ extern void sa1110_mb_enable(void);
extern void sa1110_mb_disable(void);
extern struct cpufreq_frequency_table sa11x0_freq_table[];
extern unsigned int sa11x0_freq_to_ppcr(unsigned int khz);
extern unsigned int sa11x0_getspeed(unsigned int cpu);
extern unsigned int sa11x0_ppcr_to_freq(unsigned int idx);
struct flash_platform_data;
struct resource;
......
......@@ -424,17 +424,17 @@ static unsigned int check_freqs(const struct cpumask *mask, unsigned int freq,
}
static int acpi_cpufreq_target(struct cpufreq_policy *policy,
unsigned int target_freq, unsigned int relation)
unsigned int index)
{
struct acpi_cpufreq_data *data = per_cpu(acfreq_data, policy->cpu);
struct acpi_processor_performance *perf;
struct cpufreq_freqs freqs;
struct drv_cmd cmd;
unsigned int next_state = 0; /* Index into freq_table */
unsigned int next_perf_state = 0; /* Index into perf table */
int result = 0;
pr_debug("acpi_cpufreq_target %d (%d)\n", target_freq, policy->cpu);
pr_debug("acpi_cpufreq_target %d (%d)\n",
data->freq_table[index].frequency, policy->cpu);
if (unlikely(data == NULL ||
data->acpi_data == NULL || data->freq_table == NULL)) {
......@@ -442,16 +442,7 @@ static int acpi_cpufreq_target(struct cpufreq_policy *policy,
}
perf = data->acpi_data;
result = cpufreq_frequency_table_target(policy,
data->freq_table,
target_freq,
relation, &next_state);
if (unlikely(result)) {
result = -ENODEV;
goto out;
}
next_perf_state = data->freq_table[next_state].driver_data;
next_perf_state = data->freq_table[index].driver_data;
if (perf->state == next_perf_state) {
if (unlikely(data->resume)) {
pr_debug("Called after resume, resetting to P%d\n",
......@@ -493,7 +484,7 @@ static int acpi_cpufreq_target(struct cpufreq_policy *policy,
cmd.mask = cpumask_of(policy->cpu);
freqs.old = perf->states[perf->state].core_frequency * 1000;
freqs.new = data->freq_table[next_state].frequency;
freqs.new = data->freq_table[index].frequency;
cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
drv_write(&cmd);
......@@ -923,7 +914,7 @@ static struct freq_attr *acpi_cpufreq_attr[] = {
static struct cpufreq_driver acpi_cpufreq_driver = {
.verify = cpufreq_generic_frequency_table_verify,
.target = acpi_cpufreq_target,
.target_index = acpi_cpufreq_target,
.bios_limit = acpi_processor_get_bios_limit,
.init = acpi_cpufreq_cpu_init,
.exit = acpi_cpufreq_cpu_exit,
......
......@@ -49,28 +49,21 @@ static unsigned int bL_cpufreq_get(unsigned int cpu)
/* Set clock frequency */
static int bL_cpufreq_set_target(struct cpufreq_policy *policy,
unsigned int target_freq, unsigned int relation)
unsigned int index)
{
struct cpufreq_freqs freqs;
u32 cpu = policy->cpu, freq_tab_idx, cur_cluster;
u32 cpu = policy->cpu, cur_cluster;
int ret = 0;
cur_cluster = cpu_to_cluster(policy->cpu);
freqs.old = bL_cpufreq_get(policy->cpu);
/* Determine valid target frequency using freq_table */
cpufreq_frequency_table_target(policy, freq_table[cur_cluster],
target_freq, relation, &freq_tab_idx);
freqs.new = freq_table[cur_cluster][freq_tab_idx].frequency;
freqs.new = freq_table[cur_cluster][index].frequency;
pr_debug("%s: cpu: %d, cluster: %d, oldfreq: %d, target freq: %d, new freq: %d\n",
__func__, cpu, cur_cluster, freqs.old, target_freq,
__func__, cpu, cur_cluster, freqs.old, freqs.new,
freqs.new);
if (freqs.old == freqs.new)
return 0;
cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
ret = clk_set_rate(clk[cur_cluster], freqs.new * 1000);
......@@ -200,7 +193,7 @@ static struct cpufreq_driver bL_cpufreq_driver = {
.flags = CPUFREQ_STICKY |
CPUFREQ_HAVE_GOVERNOR_PER_POLICY,
.verify = cpufreq_generic_frequency_table_verify,
.target = bL_cpufreq_set_target,
.target_index = bL_cpufreq_set_target,
.get = bL_cpufreq_get,
.init = bL_cpufreq_init,
.exit = bL_cpufreq_exit,
......
......@@ -35,25 +35,12 @@ static unsigned int at32_get_speed(unsigned int cpu)
static unsigned int ref_freq;
static unsigned long loops_per_jiffy_ref;
static int at32_set_target(struct cpufreq_policy *policy,
unsigned int target_freq,
unsigned int relation)
static int at32_set_target(struct cpufreq_policy *policy, unsigned int index)
{
struct cpufreq_freqs freqs;
long freq;
/* Convert target_freq from kHz to Hz */
freq = clk_round_rate(cpuclk, target_freq * 1000);
/* Check if policy->min <= new_freq <= policy->max */
if(freq < (policy->min * 1000) || freq > (policy->max * 1000))
return -EINVAL;
pr_debug("cpufreq: requested frequency %u Hz\n", target_freq * 1000);
freqs.old = at32_get_speed(0);
freqs.new = (freq + 500) / 1000;
freqs.flags = 0;
freqs.new = freq_table[index].frequency;
if (!ref_freq) {
ref_freq = freqs.old;
......@@ -64,13 +51,13 @@ static int at32_set_target(struct cpufreq_policy *policy,
if (freqs.old < freqs.new)
boot_cpu_data.loops_per_jiffy = cpufreq_scale(
loops_per_jiffy_ref, ref_freq, freqs.new);
clk_set_rate(cpuclk, freq);
clk_set_rate(cpuclk, freqs.new * 1000);
if (freqs.new < freqs.old)
boot_cpu_data.loops_per_jiffy = cpufreq_scale(
loops_per_jiffy_ref, ref_freq, freqs.new);
cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
pr_debug("cpufreq: set frequency %lu Hz\n", freq);
pr_debug("cpufreq: set frequency %u Hz\n", freqs.new * 1000);
return 0;
}
......@@ -139,7 +126,7 @@ static struct cpufreq_driver at32_driver = {
.name = "at32ap",
.init = at32_cpufreq_driver_init,
.verify = cpufreq_generic_frequency_table_verify,
.target = at32_set_target,
.target_index = at32_set_target,
.get = at32_get_speed,
.flags = CPUFREQ_STICKY,
};
......
......@@ -127,14 +127,11 @@ unsigned long cpu_set_cclk(int cpu, unsigned long new)
}
#endif
static int bfin_target(struct cpufreq_policy *policy,
unsigned int target_freq, unsigned int relation)
static int bfin_target(struct cpufreq_policy *policy, unsigned int index)
{
#ifndef CONFIG_BF60x
unsigned int plldiv;
#endif
unsigned int index;
unsigned long cclk_hz;
struct cpufreq_freqs freqs;
static unsigned long lpj_ref;
static unsigned int lpj_ref_freq;
......@@ -144,17 +141,11 @@ static int bfin_target(struct cpufreq_policy *policy,
cycles_t cycles;
#endif
if (cpufreq_frequency_table_target(policy, bfin_freq_table, target_freq,
relation, &index))
return -EINVAL;
cclk_hz = bfin_freq_table[index].frequency;
freqs.old = bfin_getfreq_khz(0);
freqs.new = cclk_hz;
freqs.new = bfin_freq_table[index].frequency;
pr_debug("cpufreq: changing cclk to %lu; target = %u, oldfreq = %u\n",
cclk_hz, target_freq, freqs.old);
freqs.new, freqs.new, freqs.old);
cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
#ifndef CONFIG_BF60x
......@@ -209,7 +200,7 @@ static int __bfin_cpu_init(struct cpufreq_policy *policy)
static struct cpufreq_driver bfin_driver = {
.verify = cpufreq_generic_frequency_table_verify,
.target = bfin_target,
.target_index = bfin_target,
.get = bfin_getfreq_khz,
.init = __bfin_cpu_init,
.exit = cpufreq_generic_exit,
......
......@@ -35,24 +35,14 @@ 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 target_freq, unsigned int relation)
static int cpu0_set_target(struct cpufreq_policy *policy, unsigned int index)
{
struct cpufreq_freqs freqs;
struct dev_pm_opp *opp;
unsigned long volt = 0, volt_old = 0, tol = 0;
long freq_Hz, freq_exact;
unsigned int index;
int ret;
ret = cpufreq_frequency_table_target(policy, freq_table, target_freq,
relation, &index);
if (ret) {
pr_err("failed to match target freqency %d: %d\n",
target_freq, ret);
return ret;
}
freq_Hz = clk_round_rate(cpu_clk, freq_table[index].frequency * 1000);
if (freq_Hz < 0)
freq_Hz = freq_table[index].frequency * 1000;
......@@ -60,9 +50,6 @@ static int cpu0_set_target(struct cpufreq_policy *policy,
freqs.new = freq_Hz / 1000;
freqs.old = clk_get_rate(cpu_clk) / 1000;
if (freqs.old == freqs.new)
return 0;
cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
if (!IS_ERR(cpu_reg)) {
......@@ -128,7 +115,7 @@ static int cpu0_cpufreq_init(struct cpufreq_policy *policy)
static struct cpufreq_driver cpu0_cpufreq_driver = {
.flags = CPUFREQ_STICKY,
.verify = cpufreq_generic_frequency_table_verify,
.target = cpu0_set_target,
.target_index = cpu0_set_target,
.get = cpu0_get_speed,
.init = cpu0_cpufreq_init,
.exit = cpufreq_generic_exit,
......
......@@ -47,6 +47,11 @@ static LIST_HEAD(cpufreq_policy_list);
static DEFINE_PER_CPU(char[CPUFREQ_NAME_LEN], cpufreq_cpu_governor);
#endif
static inline bool has_target(void)
{
return cpufreq_driver->target_index || cpufreq_driver->target;
}
/*
* cpu_policy_rwsem is a per CPU reader-writer semaphore designed to cure
* all cpufreq/hotplug/workqueue/etc related lock issues.
......@@ -392,7 +397,7 @@ static int cpufreq_parse_governor(char *str_governor, unsigned int *policy,
*policy = CPUFREQ_POLICY_POWERSAVE;
err = 0;
}
} else if (cpufreq_driver->target) {
} else if (has_target()) {
struct cpufreq_governor *t;
mutex_lock(&cpufreq_governor_mutex);
......@@ -550,7 +555,7 @@ static ssize_t show_scaling_available_governors(struct cpufreq_policy *policy,
ssize_t i = 0;
struct cpufreq_governor *t;
if (!cpufreq_driver->target) {
if (!has_target()) {
i += sprintf(buf, "performance powersave");
goto out;
}
......@@ -835,7 +840,7 @@ static int cpufreq_add_dev_interface(struct cpufreq_policy *policy,
if (ret)
goto err_out_kobj_put;
}
if (cpufreq_driver->target) {
if (has_target()) {
ret = sysfs_create_file(&policy->kobj, &scaling_cur_freq.attr);
if (ret)
goto err_out_kobj_put;
......@@ -884,10 +889,10 @@ static int cpufreq_add_policy_cpu(struct cpufreq_policy *policy,
unsigned int cpu, struct device *dev,
bool frozen)
{
int ret = 0, has_target = !!cpufreq_driver->target;
int ret = 0;
unsigned long flags;
if (has_target) {
if (has_target()) {
ret = __cpufreq_governor(policy, CPUFREQ_GOV_STOP);
if (ret) {
pr_err("%s: Failed to stop governor\n", __func__);
......@@ -905,7 +910,7 @@ static int cpufreq_add_policy_cpu(struct cpufreq_policy *policy,
unlock_policy_rwsem_write(policy->cpu);
if (has_target) {
if (has_target()) {
if ((ret = __cpufreq_governor(policy, CPUFREQ_GOV_START)) ||
(ret = __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS))) {
pr_err("%s: Failed to start governor\n", __func__);
......@@ -1215,7 +1220,7 @@ static int __cpufreq_remove_dev_prepare(struct device *dev,
return -EINVAL;
}
if (cpufreq_driver->target) {
if (has_target()) {
ret = __cpufreq_governor(policy, CPUFREQ_GOV_STOP);
if (ret) {
pr_err("%s: Failed to stop governor\n", __func__);
......@@ -1280,7 +1285,7 @@ static int __cpufreq_remove_dev_finish(struct device *dev,
/* If cpu is last user of policy, free policy */
if (cpus == 1) {
if (cpufreq_driver->target) {
if (has_target()) {
ret = __cpufreq_governor(policy,
CPUFREQ_GOV_POLICY_EXIT);
if (ret) {
......@@ -1323,7 +1328,7 @@ static int __cpufreq_remove_dev_finish(struct device *dev,
if (!frozen)
cpufreq_policy_free(policy);
} else {
if (cpufreq_driver->target) {
if (has_target()) {
if ((ret = __cpufreq_governor(policy, CPUFREQ_GOV_START)) ||
(ret = __cpufreq_governor(policy, CPUFREQ_GOV_LIMITS))) {
pr_err("%s: Failed to start governor\n",
......@@ -1694,12 +1699,41 @@ int __cpufreq_driver_target(struct cpufreq_policy *policy,
pr_debug("target for CPU %u: %u kHz, relation %u, requested %u kHz\n",
policy->cpu, target_freq, relation, old_target_freq);
/*
* This might look like a redundant call as we are checking it again
* after finding index. But it is left intentionally for cases where
* exactly same freq is called again and so we can save on few function
* calls.
*/
if (target_freq == policy->cur)
return 0;
if (cpufreq_driver->target)
retval = cpufreq_driver->target(policy, target_freq, relation);
else if (cpufreq_driver->target_index) {
struct cpufreq_frequency_table *freq_table;
int index;
freq_table = cpufreq_frequency_get_table(policy->cpu);
if (unlikely(!freq_table)) {
pr_err("%s: Unable to find freq_table\n", __func__);
goto out;
}
retval = cpufreq_frequency_table_target(policy, freq_table,
target_freq, relation, &index);
if (unlikely(retval)) {
pr_err("%s: Unable to find matching freq\n", __func__);
goto out;
}
if (freq_table[index].frequency == policy->cur)
retval = 0;
else
retval = cpufreq_driver->target_index(policy, index);
}
out:
return retval;
}
EXPORT_SYMBOL_GPL(__cpufreq_driver_target);
......@@ -2025,7 +2059,7 @@ int cpufreq_update_policy(unsigned int cpu)
pr_debug("Driver did not initialize current freq");
policy->cur = new_policy.cur;
} else {
if (policy->cur != new_policy.cur && cpufreq_driver->target)
if (policy->cur != new_policy.cur && has_target())
cpufreq_out_of_sync(cpu, policy->cur,
new_policy.cur);
}
......@@ -2103,7 +2137,8 @@ int cpufreq_register_driver(struct cpufreq_driver *driver_data)
return -ENODEV;
if (!driver_data || !driver_data->verify || !driver_data->init ||
((!driver_data->setpolicy) && (!driver_data->target)))
!(driver_data->setpolicy || driver_data->target_index ||
driver_data->target))
return -EINVAL;
pr_debug("trying to register driver %s\n", driver_data->name);
......
......@@ -27,8 +27,7 @@ static unsigned int cris_freq_get_cpu_frequency(unsigned int cpu)
return clk_ctrl.pll ? 200000 : 6000;
}
static void cris_freq_set_cpu_state(struct cpufreq_policy *policy,
unsigned int state)
static int cris_freq_target(struct cpufreq_policy *policy, unsigned int state)
{
struct cpufreq_freqs freqs;
reg_clkgen_rw_clk_ctrl clk_ctrl;
......@@ -52,19 +51,6 @@ static void cris_freq_set_cpu_state(struct cpufreq_policy *policy,
local_irq_enable();
cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
};
static int cris_freq_target(struct cpufreq_policy *policy,
unsigned int target_freq,
unsigned int relation)
{
unsigned int newstate = 0;
if (cpufreq_frequency_table_target(policy, cris_freq_table,
target_freq, relation, &newstate))
return -EINVAL;
cris_freq_set_cpu_state(policy, newstate);
return 0;
}
......@@ -77,7 +63,7 @@ static int cris_freq_cpu_init(struct cpufreq_policy *policy)
static struct cpufreq_driver cris_freq_driver = {
.get = cris_freq_get_cpu_frequency,
.verify = cpufreq_generic_frequency_table_verify,
.target = cris_freq_target,
.target_index = cris_freq_target,
.init = cris_freq_cpu_init,
.exit = cpufreq_generic_exit,
.name = "cris_freq",
......
......@@ -27,8 +27,7 @@ static unsigned int cris_freq_get_cpu_frequency(unsigned int cpu)
return clk_ctrl.pll ? 200000 : 6000;
}
static void cris_freq_set_cpu_state(struct cpufreq_policy *policy,
unsigned int state)
static int cris_freq_target(struct cpufreq_policy *policy, unsigned int state)
{
struct cpufreq_freqs freqs;
reg_config_rw_clk_ctrl clk_ctrl;
......@@ -52,18 +51,6 @@ static void cris_freq_set_cpu_state(struct cpufreq_policy *policy,
local_irq_enable();
cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
};
static int cris_freq_target(struct cpufreq_policy *policy,
unsigned int target_freq, unsigned int relation)
{
unsigned int newstate = 0;
if (cpufreq_frequency_table_target
(policy, cris_freq_table, target_freq, relation, &newstate))
return -EINVAL;
cris_freq_set_cpu_state(policy, newstate);
return 0;
}
......@@ -76,7 +63,7 @@ static int cris_freq_cpu_init(struct cpufreq_policy *policy)
static struct cpufreq_driver cris_freq_driver = {
.get = cris_freq_get_cpu_frequency,
.verify = cpufreq_generic_frequency_table_verify,
.target = cris_freq_target,
.target_index = cris_freq_target,
.init = cris_freq_cpu_init,
.exit = cpufreq_generic_exit,
.name = "cris_freq",
......
......@@ -66,28 +66,18 @@ static unsigned int davinci_getspeed(unsigned int cpu)
return clk_get_rate(cpufreq.armclk) / 1000;
}
static int davinci_target(struct cpufreq_policy *policy,
unsigned int target_freq, unsigned int relation)
static int davinci_target(struct cpufreq_policy *policy, unsigned int idx)
{
int ret = 0;
unsigned int idx;
struct cpufreq_freqs freqs;
struct davinci_cpufreq_config *pdata = cpufreq.dev->platform_data;
struct clk *armclk = cpufreq.armclk;
freqs.old = davinci_getspeed(0);
freqs.new = clk_round_rate(armclk, target_freq * 1000) / 1000;
if (freqs.old == freqs.new)
return ret;
freqs.new = pdata->freq_table[idx].frequency;
dev_dbg(cpufreq.dev, "transition: %u --> %u\n", freqs.old, freqs.new);
ret = cpufreq_frequency_table_target(policy, pdata->freq_table,
freqs.new, relation, &idx);
if (ret)
return -EINVAL;
cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
/* if moving to higher frequency, up the voltage beforehand */
......@@ -148,7 +138,7 @@ static int davinci_cpu_init(struct cpufreq_policy *policy)
static struct cpufreq_driver davinci_driver = {
.flags = CPUFREQ_STICKY,
.verify = davinci_verify_speed,
.target = davinci_target,
.target_index = davinci_target,
.get = davinci_getspeed,
.init = davinci_cpu_init,
.exit = cpufreq_generic_exit,
......
......@@ -20,23 +20,13 @@ static struct cpufreq_frequency_table *freq_table;
static struct clk *armss_clk;
static int dbx500_cpufreq_target(struct cpufreq_policy *policy,
unsigned int target_freq,
unsigned int relation)
unsigned int index)
{
struct cpufreq_freqs freqs;
unsigned int idx;
int ret;
/* Lookup the next frequency */
if (cpufreq_frequency_table_target(policy, freq_table, target_freq,
relation, &idx))
return -EINVAL;
freqs.old = policy->cur;
freqs.new = freq_table[idx].frequency;
if (freqs.old == freqs.new)
return 0;
freqs.new = freq_table[index].frequency;
/* pre-change notification */
cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
......@@ -80,7 +70,7 @@ static int dbx500_cpufreq_init(struct cpufreq_policy *policy)
static struct cpufreq_driver dbx500_cpufreq_driver = {
.flags = CPUFREQ_STICKY | CPUFREQ_CONST_LOOPS,
.verify = cpufreq_generic_frequency_table_verify,
.target = dbx500_cpufreq_target,
.target_index = dbx500_cpufreq_target,
.get = dbx500_cpufreq_getspeed,
.init = dbx500_cpufreq_init,
.name = "DBX500",
......
......@@ -168,12 +168,9 @@ static int eps_set_state(struct eps_cpu_data *centaur,
return err;
}
static int eps_target(struct cpufreq_policy *policy,
unsigned int target_freq,
unsigned int relation)
static int eps_target(struct cpufreq_policy *policy, unsigned int index)
{
struct eps_cpu_data *centaur;
unsigned int newstate = 0;
unsigned int cpu = policy->cpu;
unsigned int dest_state;
int ret;
......@@ -182,16 +179,8 @@ static int eps_target(struct cpufreq_policy *policy,
return -ENODEV;
centaur = eps_cpu[cpu];
if (unlikely(cpufreq_frequency_table_target(policy,
&eps_cpu[cpu]->freq_table[0],
target_freq,
relation,
&newstate))) {
return -EINVAL;
}
/* Make frequency transition */
dest_state = centaur->freq_table[newstate].driver_data & 0xffff;
dest_state = centaur->freq_table[index].driver_data & 0xffff;
ret = eps_set_state(centaur, policy, dest_state);
if (ret)
printk(KERN_ERR "eps: Timeout!\n");
......@@ -418,7 +407,7 @@ static int eps_cpu_exit(struct cpufreq_policy *policy)
static struct cpufreq_driver eps_driver = {
.verify = cpufreq_generic_frequency_table_verify,
.target = eps_target,
.target_index = eps_target,
.init = eps_cpu_init,
.exit = eps_cpu_exit,
.get = eps_get,
......
......@@ -105,20 +105,8 @@ static unsigned int elanfreq_get_cpu_frequency(unsigned int cpu)
}
/**
* elanfreq_set_cpu_frequency: Change the CPU core frequency
* @cpu: cpu number
* @freq: frequency in kHz