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

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
...@@ -21,17 +21,8 @@ ...@@ -21,17 +21,8 @@
#include <linux/export.h> #include <linux/export.h>
#include <linux/slab.h> #include <linux/slab.h>
static struct clk *cpuclk;
static struct cpufreq_frequency_table *freq_table; 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 int ref_freq;
static unsigned long loops_per_jiffy_ref; static unsigned long loops_per_jiffy_ref;
...@@ -39,7 +30,7 @@ static int at32_set_target(struct cpufreq_policy *policy, unsigned int index) ...@@ -39,7 +30,7 @@ static int at32_set_target(struct cpufreq_policy *policy, unsigned int index)
{ {
unsigned int old_freq, new_freq; unsigned int old_freq, new_freq;
old_freq = at32_get_speed(0); old_freq = policy->cur;
new_freq = freq_table[index].frequency; new_freq = freq_table[index].frequency;
if (!ref_freq) { if (!ref_freq) {
...@@ -50,7 +41,7 @@ static int at32_set_target(struct cpufreq_policy *policy, unsigned int index) ...@@ -50,7 +41,7 @@ static int at32_set_target(struct cpufreq_policy *policy, unsigned int index)
if (old_freq < new_freq) if (old_freq < new_freq)
boot_cpu_data.loops_per_jiffy = cpufreq_scale( boot_cpu_data.loops_per_jiffy = cpufreq_scale(
loops_per_jiffy_ref, ref_freq, new_freq); 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) if (new_freq < old_freq)
boot_cpu_data.loops_per_jiffy = cpufreq_scale( boot_cpu_data.loops_per_jiffy = cpufreq_scale(
loops_per_jiffy_ref, ref_freq, new_freq); loops_per_jiffy_ref, ref_freq, new_freq);
...@@ -61,6 +52,7 @@ static int at32_set_target(struct cpufreq_policy *policy, unsigned int index) ...@@ -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) static int at32_cpufreq_driver_init(struct cpufreq_policy *policy)
{ {
unsigned int frequency, rate, min_freq; unsigned int frequency, rate, min_freq;
static struct clk *cpuclk;
int retval, steps, i; int retval, steps, i;
if (policy->cpu != 0) if (policy->cpu != 0)
...@@ -103,6 +95,7 @@ static int at32_cpufreq_driver_init(struct cpufreq_policy *policy) ...@@ -103,6 +95,7 @@ static int at32_cpufreq_driver_init(struct cpufreq_policy *policy)
frequency /= 2; frequency /= 2;
} }
policy->clk = cpuclk;
freq_table[steps - 1].frequency = CPUFREQ_TABLE_END; freq_table[steps - 1].frequency = CPUFREQ_TABLE_END;
retval = cpufreq_table_validate_and_show(policy, freq_table); retval = cpufreq_table_validate_and_show(policy, freq_table);
...@@ -123,7 +116,7 @@ static struct cpufreq_driver at32_driver = { ...@@ -123,7 +116,7 @@ static struct cpufreq_driver at32_driver = {
.init = at32_cpufreq_driver_init, .init = at32_cpufreq_driver_init,
.verify = cpufreq_generic_frequency_table_verify, .verify = cpufreq_generic_frequency_table_verify,
.target_index = at32_set_target, .target_index = at32_set_target,
.get = at32_get_speed, .get = cpufreq_generic_get,
.flags = CPUFREQ_STICKY, .flags = CPUFREQ_STICKY,
}; };
......
...@@ -30,11 +30,6 @@ static struct clk *cpu_clk; ...@@ -30,11 +30,6 @@ static struct clk *cpu_clk;
static struct regulator *cpu_reg; static struct regulator *cpu_reg;
static struct cpufreq_frequency_table *freq_table; 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) static int cpu0_set_target(struct cpufreq_policy *policy, unsigned int index)
{ {
struct dev_pm_opp *opp; struct dev_pm_opp *opp;
...@@ -100,6 +95,7 @@ static int cpu0_set_target(struct cpufreq_policy *policy, unsigned int index) ...@@ -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) static int cpu0_cpufreq_init(struct cpufreq_policy *policy)
{ {
policy->clk = cpu_clk;
return cpufreq_generic_init(policy, freq_table, transition_latency); return cpufreq_generic_init(policy, freq_table, transition_latency);
} }
...@@ -107,7 +103,7 @@ static struct cpufreq_driver cpu0_cpufreq_driver = { ...@@ -107,7 +103,7 @@ static struct cpufreq_driver cpu0_cpufreq_driver = {
.flags = CPUFREQ_STICKY, .flags = CPUFREQ_STICKY,
.verify = cpufreq_generic_frequency_table_verify, .verify = cpufreq_generic_frequency_table_verify,
.target_index = cpu0_set_target, .target_index = cpu0_set_target,
.get = cpu0_get_speed, .get = cpufreq_generic_get,
.init = cpu0_cpufreq_init, .init = cpu0_cpufreq_init,
.exit = cpufreq_generic_exit, .exit = cpufreq_generic_exit,
.name = "generic_cpu0", .name = "generic_cpu0",
......
...@@ -176,6 +176,20 @@ int cpufreq_generic_init(struct cpufreq_policy *policy, ...@@ -176,6 +176,20 @@ int cpufreq_generic_init(struct cpufreq_policy *policy,
} }
EXPORT_SYMBOL_GPL(cpufreq_generic_init); 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 *cpufreq_cpu_get(unsigned int cpu)
{ {
struct cpufreq_policy *policy = NULL; struct cpufreq_policy *policy = NULL;
...@@ -1068,6 +1082,11 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif, ...@@ -1068,6 +1082,11 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif,
goto err_set_policy_cpu; 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) { if (cpufreq_driver->get) {
policy->cur = cpufreq_driver->get(policy->cpu); policy->cur = cpufreq_driver->get(policy->cpu);
if (!policy->cur) { if (!policy->cur) {
...@@ -1142,11 +1161,6 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif, ...@@ -1142,11 +1161,6 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif,
} }
#endif #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) { if (!frozen) {
ret = cpufreq_add_dev_interface(policy, dev); ret = cpufreq_add_dev_interface(policy, dev);
if (ret) if (ret)
...@@ -1174,12 +1188,12 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif, ...@@ -1174,12 +1188,12 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif,
return 0; return 0;
err_out_unregister: err_out_unregister:
err_get_freq:
write_lock_irqsave(&cpufreq_driver_lock, flags); write_lock_irqsave(&cpufreq_driver_lock, flags);
for_each_cpu(j, policy->cpus) for_each_cpu(j, policy->cpus)
per_cpu(cpufreq_cpu_data, j) = NULL; per_cpu(cpufreq_cpu_data, j) = NULL;
write_unlock_irqrestore(&cpufreq_driver_lock, flags); write_unlock_irqrestore(&cpufreq_driver_lock, flags);
err_get_freq:
if (cpufreq_driver->exit) if (cpufreq_driver->exit)
cpufreq_driver->exit(policy); cpufreq_driver->exit(policy);
err_set_policy_cpu: err_set_policy_cpu:
......
...@@ -58,14 +58,6 @@ static int davinci_verify_speed(struct cpufreq_policy *policy) ...@@ -58,14 +58,6 @@ static int davinci_verify_speed(struct cpufreq_policy *policy)
return 0; 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) static int davinci_target(struct cpufreq_policy *policy, unsigned int idx)
{ {
struct davinci_cpufreq_config *pdata = cpufreq.dev->platform_data; struct davinci_cpufreq_config *pdata = cpufreq.dev->platform_data;
...@@ -73,7 +65,7 @@ static int davinci_target(struct cpufreq_policy *policy, unsigned int idx) ...@@ -73,7 +65,7 @@ static int davinci_target(struct cpufreq_policy *policy, unsigned int idx)
unsigned int old_freq, new_freq; unsigned int old_freq, new_freq;
int ret = 0; int ret = 0;
old_freq = davinci_getspeed(0); old_freq = policy->cur;
new_freq = pdata->freq_table[idx].frequency; new_freq = pdata->freq_table[idx].frequency;
/* if moving to higher frequency, up the voltage beforehand */ /* if moving to higher frequency, up the voltage beforehand */
...@@ -116,6 +108,8 @@ static int davinci_cpu_init(struct cpufreq_policy *policy) ...@@ -116,6 +108,8 @@ static int davinci_cpu_init(struct cpufreq_policy *policy)
return result; return result;
} }
policy->clk = cpufreq.armclk;
/* /*
* Time measurement across the target() function yields ~1500-1800us * Time measurement across the target() function yields ~1500-1800us
* time taken with no drivers on notification list. * time taken with no drivers on notification list.
...@@ -129,7 +123,7 @@ static struct cpufreq_driver davinci_driver = { ...@@ -129,7 +123,7 @@ static struct cpufreq_driver davinci_driver = {
.flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK, .flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK,
.verify = davinci_verify_speed, .verify = davinci_verify_speed,
.target_index = davinci_target, .target_index = davinci_target,
.get = davinci_getspeed, .get = cpufreq_generic_get,
.init = davinci_cpu_init, .init = davinci_cpu_init,
.exit = cpufreq_generic_exit, .exit = cpufreq_generic_exit,
.name = "davinci", .name = "davinci",
......
...@@ -26,24 +26,9 @@ static int dbx500_cpufreq_target(struct cpufreq_policy *policy, ...@@ -26,24 +26,9 @@ static int dbx500_cpufreq_target(struct cpufreq_policy *policy,
return clk_set_rate(armss_clk, freq_table[index].frequency * 1000); 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) static int dbx500_cpufreq_init(struct cpufreq_policy *policy)
{ {
policy->clk = armss_clk;
return cpufreq_generic_init(policy, freq_table, 20 * 1000); return cpufreq_generic_init(policy, freq_table, 20 * 1000);
} }
...@@ -52,7 +37,7 @@ static struct cpufreq_driver dbx500_cpufreq_driver = { ...@@ -52,7 +37,7 @@ static struct cpufreq_driver dbx500_cpufreq_driver = {
CPUFREQ_NEED_INITIAL_FREQ_CHECK, CPUFREQ_NEED_INITIAL_FREQ_CHECK,
.verify = cpufreq_generic_frequency_table_verify, .verify = cpufreq_generic_frequency_table_verify,
.target_index = dbx500_cpufreq_target, .target_index = dbx500_cpufreq_target,
.get = dbx500_cpufreq_getspeed, .get = cpufreq_generic_get,
.init = dbx500_cpufreq_init, .init = dbx500_cpufreq_init,
.name = "DBX500", .name = "DBX500",
.attr = cpufreq_generic_attr, .attr = cpufreq_generic_attr,
......
...@@ -31,11 +31,6 @@ static unsigned int locking_frequency; ...@@ -31,11 +31,6 @@ static unsigned int locking_frequency;
static bool frequency_locked; static bool frequency_locked;
static DEFINE_MUTEX(cpufreq_lock); static DEFINE_MUTEX(cpufreq_lock);
static unsigned int exynos_getspeed(unsigned int cpu)
{
return clk_get_rate(exynos_info->cpu_clk) / 1000;
}
static int exynos_cpufreq_get_index(unsigned int freq) static int exynos_cpufreq_get_index(unsigned int freq)
{ {
struct cpufreq_frequency_table *freq_table = exynos_info->freq_table; struct cpufreq_frequency_table *freq_table = exynos_info->freq_table;
...@@ -215,6 +210,7 @@ static struct notifier_block exynos_cpufreq_nb = { ...@@ -215,6 +210,7 @@ static struct notifier_block exynos_cpufreq_nb = {
static int exynos_cpufreq_cpu_init(struct cpufreq_policy *policy) static int exynos_cpufreq_cpu_init(struct cpufreq_policy *policy)
{ {
policy->clk = exynos_info->cpu_clk;
return cpufreq_generic_init(policy, exynos_info->freq_table, 100000); return cpufreq_generic_init(policy, exynos_info->freq_table, 100000);
} }
...@@ -222,7 +218,7 @@ static struct cpufreq_driver exynos_driver = { ...@@ -222,7 +218,7 @@ static struct cpufreq_driver exynos_driver = {
.flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK, .flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK,
.verify = cpufreq_generic_frequency_table_verify, .verify = cpufreq_generic_frequency_table_verify,
.target_index = exynos_target, .target_index = exynos_target,
.get = exynos_getspeed, .get = cpufreq_generic_get,
.init = exynos_cpufreq_cpu_init, .init = exynos_cpufreq_cpu_init,
.exit = cpufreq_generic_exit, .exit = cpufreq_generic_exit,
.name = "exynos_cpufreq", .name = "exynos_cpufreq",
...@@ -264,7 +260,7 @@ static int exynos_cpufreq_probe(struct platform_device *pdev) ...@@ -264,7 +260,7 @@ static int exynos_cpufreq_probe(struct platform_device *pdev)
goto err_vdd_arm; goto err_vdd_arm;
} }
locking_frequency = exynos_getspeed(0); locking_frequency = clk_get_rate(exynos_info->cpu_clk) / 1000;
register_pm_notifier(&exynos_cpufreq_nb); register_pm_notifier(&exynos_cpufreq_nb);
......
...@@ -100,7 +100,6 @@ struct exynos_dvfs_data { ...@@ -100,7 +100,6 @@ struct exynos_dvfs_data {
struct resource *mem; struct resource *mem;
int irq; int irq;
struct clk *cpu_clk; struct clk *cpu_clk;
unsigned int cur_frequency;
unsigned int latency; unsigned int latency;
struct cpufreq_frequency_table *freq_table; struct cpufreq_frequency_table *freq_table;
unsigned int freq_count; unsigned int freq_count;
...@@ -165,7 +164,7 @@ static int init_div_table(void) ...@@ -165,7 +164,7 @@ static int init_div_table(void)
return 0; return 0;
} }
static void exynos_enable_dvfs(void) static void exynos_enable_dvfs(unsigned int cur_frequency)
{ {
unsigned int tmp, i, cpu; unsigned int tmp, i, cpu;
struct cpufreq_frequency_table *freq_table = dvfs_info->freq_table; struct cpufreq_frequency_table *freq_table = dvfs_info->freq_table;
...@@ -184,18 +183,18 @@ static void exynos_enable_dvfs(void) ...@@ -184,18 +183,18 @@ static void exynos_enable_dvfs(void)
/* Set initial performance index */ /* Set initial performance index */
for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++) for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++)
if (freq_table[i].frequency == dvfs_info->cur_frequency) if (freq_table[i].frequency == cur_frequency)
break; break;
if (freq_table[i].frequency == CPUFREQ_TABLE_END) { if (freq_table[i].frequency == CPUFREQ_TABLE_END) {
dev_crit(dvfs_info->dev, "Boot up frequency not supported\n"); dev_crit(dvfs_info->dev, "Boot up frequency not supported\n");
/* Assign the highest frequency */ /* Assign the highest frequency */
i = 0; i = 0;
dvfs_info->cur_frequency = freq_table[i].frequency; cur_frequency = freq_table[i].frequency;
} }
dev_info(dvfs_info->dev, "Setting dvfs initial frequency = %uKHZ", dev_info(dvfs_info->dev, "Setting dvfs initial frequency = %uKHZ",
dvfs_info->cur_frequency); cur_frequency);
for (cpu = 0; cpu < CONFIG_NR_CPUS; cpu++) { for (cpu = 0; cpu < CONFIG_NR_CPUS; cpu++) {
tmp = __raw_readl(dvfs_info->base + XMU_C0_3_PSTATE + cpu * 4); tmp = __raw_readl(dvfs_info->base + XMU_C0_3_PSTATE + cpu * 4);
...@@ -209,11 +208,6 @@ static void exynos_enable_dvfs(void) ...@@ -209,11 +208,6 @@ static void exynos_enable_dvfs(void)
dvfs_info->base + XMU_DVFS_CTRL); dvfs_info->base + XMU_DVFS_CTRL);
} }
static unsigned int exynos_getspeed(unsigned int cpu)
{
return dvfs_info->cur_frequency;
}
static int exynos_target(struct cpufreq_policy *policy, unsigned int index) static int exynos_target(struct cpufreq_policy *policy, unsigned int index)
{ {
unsigned int tmp; unsigned int tmp;
...@@ -222,7 +216,7 @@ static int exynos_target(struct cpufreq_policy *policy, unsigned int index) ...@@ -222,7 +216,7 @@ static int exynos_target(struct cpufreq_policy *policy, unsigned int index)
mutex_lock(&cpufreq_lock); mutex_lock(&cpufreq_lock);
freqs.old = dvfs_info->cur_frequency; freqs.old = policy->cur;
freqs.new = freq_table[index].frequency; freqs.new = freq_table[index].frequency;
cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
...@@ -250,7 +244,7 @@ static void exynos_cpufreq_work(struct work_struct *work) ...@@ -250,7 +244,7 @@ static void exynos_cpufreq_work(struct work_struct *work)
goto skip_work; goto skip_work;
mutex_lock(&cpufreq_lock); mutex_lock(&cpufreq_lock);
freqs.old = dvfs_info->cur_frequency; freqs.old = policy->cur;
cur_pstate = __raw_readl(dvfs_info->base + XMU_P_STATUS); cur_pstate = __raw_readl(dvfs_info->base + XMU_P_STATUS);
if (cur_pstate >> C0_3_PSTATE_VALID_SHIFT & 0x1) if (cur_pstate >> C0_3_PSTATE_VALID_SHIFT & 0x1)
...@@ -260,10 +254,9 @@ static void exynos_cpufreq_work(struct work_struct *work) ...@@ -260,10 +254,9 @@ static void exynos_cpufreq_work(struct work_struct *work)
if (likely(index < dvfs_info->freq_count)) { if (likely(index < dvfs_info->freq_count)) {
freqs.new = freq_table[index].frequency; freqs.new = freq_table[index].frequency;
dvfs_info->cur_frequency = freqs.new;
} else { } else {
dev_crit(dvfs_info->dev, "New frequency out of range\n"); dev_crit(dvfs_info->dev, "New frequency out of range\n");
freqs.new = dvfs_info->cur_frequency; freqs.new = freqs.old;
} }
cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
...@@ -307,6 +300,7 @@ static void exynos_sort_descend_freq_table(void) ...@@ -307,6 +300,7 @@ static void exynos_sort_descend_freq_table(void)
static int exynos_cpufreq_cpu_init(struct cpufreq_policy *policy) static int exynos_cpufreq_cpu_init(struct cpufreq_policy *policy)
{ {
policy->clk = dvfs_info->cpu_clk;
return cpufreq_generic_init(policy, dvfs_info->freq_table, return cpufreq_generic_init(policy, dvfs_info->freq_table,
dvfs_info->latency); dvfs_info->latency);
} }
...@@ -316,7 +310,7 @@ static struct cpufreq_driver exynos_driver = { ...@@ -316,7 +310,7 @@ static struct cpufreq_driver exynos_driver = {
CPUFREQ_NEED_INITIAL_FREQ_CHECK, CPUFREQ_NEED_INITIAL_FREQ_CHECK,
.verify = cpufreq_generic_frequency_table_verify, .verify = cpufreq_generic_frequency_table_verify,
.target_index = exynos_target, .target_index = exynos_target,
.get = exynos_getspeed, .get = cpufreq_generic_get,
.init = exynos_cpufreq_cpu_init, .init = exynos_cpufreq_cpu_init,
.exit = cpufreq_generic_exit, .exit = cpufreq_generic_exit,
.name = CPUFREQ_NAME, .name = CPUFREQ_NAME,
...@@ -336,6 +330,7 @@ static int exynos_cpufreq_probe(struct platform_device *pdev) ...@@ -336,6 +330,7 @@ static int exynos_cpufreq_probe(struct platform_device *pdev)
int ret = -EINVAL; int ret = -EINVAL;
struct device_node *np; struct device_node *np;
struct resource res; struct resource res;
unsigned int cur_frequency;
np = pdev->dev.of_node; np = pdev->dev.of_node;
if (!np) if (!np)
...@@ -392,13 +387,13 @@ static int exynos_cpufreq_probe(struct platform_device *pdev) ...@@ -392,13 +387,13 @@ static int exynos_cpufreq_probe(struct platform_device *pdev)
goto err_free_table; goto err_free_table;
} }
dvfs_info->cur_frequency = clk_get_rate(dvfs_info->cpu_clk); cur_frequency = clk_get_rate(dvfs_info->cpu_clk);
if (!dvfs_info->cur_frequency) { if (!cur_frequency) {
dev_err(dvfs_info->dev, "Failed to get clock rate\n"); dev_err(dvfs_info->dev, "Failed to get clock rate\n");
ret = -EINVAL; ret = -EINVAL;
goto err_free_table; goto err_free_table;
} }
dvfs_info->cur_frequency /= 1000; cur_frequency /= 1000;
INIT_WORK(&dvfs_info->irq_work, exynos_cpufreq_work); INIT_WORK(&dvfs_info->irq_work, exynos_cpufreq_work);
ret = devm_request_irq(dvfs_info->dev, dvfs_info->irq, ret = devm_request_irq(dvfs_info->dev, dvfs_info->irq,
...@@ -415,7 +410,7 @@ static int exynos_cpufreq_probe(struct platform_device *pdev) ...@@ -415,7 +410,7 @@ static int exynos_cpufreq_probe(struct platform_device *pdev)
goto err_free_table; goto err_free_table;
} }
exynos_enable_dvfs(); exynos_enable_dvfs(cur_frequency);
ret = cpufreq_register_driver(&exynos_driver); ret = cpufreq_register_driver(&exynos_driver);
if (ret) { if (ret) {
dev_err(dvfs_info->dev, dev_err(dvfs_info->dev,
......
...@@ -38,11 +38,6 @@ static unsigned int transition_latency; ...@@ -38,11 +38,6 @@ static unsigned int transition_latency;
static u32 *imx6_soc_volt; static u32 *imx6_soc_volt;
static u32 soc_opp_count; static u32 soc_opp_count;
static unsigned int imx6q_get_speed(unsigned int cpu)
{
return clk_get_rate(arm_clk) / 1000;
}
static int imx6q_set_target(struct cpufreq_policy *policy, unsigned int index) static int imx6q_set_target(struct cpufreq_policy *policy, unsigned int index)
{ {
struct dev_pm_opp *opp; struct dev_pm_opp *opp;
...@@ -139,6 +134,7 @@ static int imx6q_set_target(struct cpufreq_policy *policy, unsigned int index) ...@@ -139,6 +134,7 @@ static int imx6q_set_target(struct cpufreq_policy *policy, unsigned int index)
static int imx6q_cpufreq_init(struct cpufreq_policy *policy) static int imx6q_cpufreq_init(struct cpufreq_policy *policy)
{ {
policy->clk = arm_clk;
return cpufreq_generic_init(policy, freq_table, transition_latency); return cpufreq_generic_init(policy, freq_table, transition_latency);
} }
...@@ -146,7 +142,7 @@ static struct cpufreq_driver imx6q_cpufreq_driver = { ...@@ -146,7 +142,7 @@ static struct cpufreq_driver imx6q_cpufreq_driver = {
.flags = CPUFREQ_NEED_INITIAL_FREQ_CHECK, .flags = CPUFREQ_NEED_INITIAL_FREQ_CHECK,
.verify = cpufreq_generic_frequency_table_verify, .verify = cpufreq_generic_frequency_table_verify,
.target_index = imx6q_set_target, .target_index = imx6q_set_target,
.get = imx6q_get_speed, .get = cpufreq_generic_get,
.init = imx6q_cpufreq_init, .init = imx6q_cpufreq_init,
.exit = cpufreq_generic_exit, .exit = cpufreq_generic_exit,
.name = "imx6q-cpufreq", .name = "imx6q-cpufreq",
......
...@@ -24,8 +24,6 @@ ...@@ -24,8 +24,6 @@
static uint nowait; static uint nowait;
static struct clk *cpuclk;
static void (*saved_cpu_wait) (void); static void (*saved_cpu_wait) (void);
static int loongson2_cpu_freq_notifier(struct notifier_block *nb, static int loongson2_cpu_freq_notifier(struct notifier_block *nb,
...@@ -44,11 +42,6 @@ static int loongson2_cpu_freq_notifier(struct notifier_block *nb, ...@@ -44,11 +42,6 @@ static int loongson2_cpu_freq_notifier(struct notifier_block *nb,
return 0; return 0;
} }
static unsigned int loongson2_cpufreq_get(unsigned int cpu)
{
return clk_get_rate(cpuclk);
}
/* /*
* Here we notify other drivers of the proposed change and the final change. * Here we notify other drivers of the proposed change and the final change.
*/ */
...@@ -69,13 +62,14 @@ static int loongson2_cpufreq_target(struct cpufreq_policy *policy, ...@@ -69,13 +62,14 @@ static int loongson2_cpufreq_target(struct cpufreq_policy *policy,
set_cpus_allowed_ptr(current, &cpus_allowed); set_cpus_allowed_ptr(current, &cpus_allowed);
/* setting the cpu frequency */ /* setting the cpu frequency */
clk_set_rate(cpuclk, freq); clk_set_rate(policy->clk, freq);
return 0; return 0;
} }
static int loongson2_cpufreq_cpu_init(struct cpufreq_policy *policy) static int loongson2_cpufreq_cpu_init(struct cpufreq_policy *policy)
{ {
static struct clk *cpuclk;
int i; int i;
unsigned long rate; unsigned long rate;
int ret; int ret;
...@@ -104,13 +98,14 @@ static int loongson2_cpufreq_cpu_init(struct cpufreq_policy *policy) ...@@ -104,13 +98,14 @@ static int loongson2_cpufreq_cpu_init(struct cpufreq_policy *policy)
return ret; return ret;
} }
policy->clk = cpuclk;
return cpufreq_generic_init(policy, &loongson2_clockmod_table[0], 0); return cpufreq_generic_init(policy, &loongson2_clockmod_table[0], 0);
} }
static int loongson2_cpufreq_exit(struct cpufreq_policy *policy) static int loongson2_cpufreq_exit(struct cpufreq_policy *policy)
{ {
cpufreq_frequency_table_put_attr(policy->cpu); cpufreq_frequency_table_put_attr(policy->cpu);
clk_put(cpuclk); clk_put(policy->clk);
return 0; return 0;
} }
...@@ -119,7 +114,7 @@ static struct cpufreq_driver loongson2_cpufreq_driver = { ...@@ -119,7 +114,7 @@ static struct cpufreq_driver loongson2_cpufreq_driver = {
.init = loongson2_cpufreq_cpu_init, .init = loongson2_cpufreq_cpu_init,
.verify = cpufreq_generic_frequency_table_verify, .verify = cpufreq_generic_frequency_table_verify,
.target_index = loongson2_cpufreq_target, .target_index = loongson2_cpufreq_target,
.get = loongson2_cpufreq_get, .get = cpufreq_generic_get,
.exit = loongson2_cpufreq_exit, .exit = loongson2_cpufreq_exit,
.attr = cpufreq_generic_attr, .attr = cpufreq_generic_attr,
}; };
......
...@@ -36,21 +36,9 @@ ...@@ -36,21 +36,9 @@
static struct cpufreq_frequency_table *freq_table; static struct cpufreq_frequency_table *freq_table;
static atomic_t freq_table_users = ATOMIC_INIT(0); static atomic_t freq_table_users = ATOMIC_INIT(0);
static struct clk *mpu_clk;
static struct device *mpu_dev; static struct device *mpu_dev;
static struct regulator *mpu_reg; static struct regulator *mpu_reg;
static unsigned int omap_getspeed(unsigned int cpu)
{
unsigned long rate;
if (cpu >= NR_CPUS)
return 0;
rate = clk_get_rate(mpu_clk) / 1000;
return rate;
}
static int omap_target(struct cpufreq_policy *policy, unsigned int index) static int omap_target(struct cpufreq_policy *policy, unsigned int index)
{ {
int r, ret; int r, ret;
...@@ -58,11 +46,11 @@ static int omap_target(struct cpufreq_policy *policy, unsigned int index) ...@@ -58,11 +46,11 @@ static int omap_target(struct cpufreq_policy *policy, unsigned int index)
unsigned long freq, volt = 0, volt_old = 0, tol = 0; unsigned long freq, volt = 0, volt_old = 0, tol = 0;
unsigned int old_freq, new_freq; unsigned int old_freq, new_freq;
old_freq = omap_getspeed(policy->cpu); old_freq = policy->cur;
new_freq = freq_table[index].frequency; new_freq = freq_table[index].frequency;
freq = new_freq * 1000; freq = new_freq * 1000;
ret = clk_round_rate(mpu_clk, freq); ret = clk_round_rate(policy->clk, freq);
if (IS_ERR_VALUE(ret)) { if (IS_ERR_VALUE(ret)) {
dev_warn(mpu_dev, dev_warn(mpu_dev,
"CPUfreq: Cannot find matching frequency for %lu\n", "CPUfreq: Cannot find matching frequency for %lu\n",
...@@ -100,7 +88,7 @@ static int omap_target(struct cpufreq_policy *policy, unsigned int index) ...@@ -100,7 +88,7 @@ static int omap_target(struct cpufreq_policy *policy, unsigned int index)
} }
} }
ret = clk_set_rate(mpu_clk, new_freq * 1000); ret = clk_set_rate(policy->clk, new_freq * 1000);
/* scaling down? scale voltage after frequency */ /* scaling down? scale voltage after frequency */
if (mpu_reg && (new_freq < old_freq)) { if (mpu_reg && (new_freq < old_freq)) {
...@@ -108,7 +96,7 @@ static int omap_target(struct cpufreq_policy *policy, unsigned int index) ...@@ -108,7 +96,7 @@ static int omap_target(struct cpufreq_policy *policy, unsigned int index)
if (r < 0) { if (r < 0) {
dev_warn(mpu_dev, "%s: unable to scale voltage down.\n", dev_warn(mpu_dev, "%s: unable to scale voltage down.\n",
__func__); __func__);
clk_set_rate(mpu_clk, old_freq * 1000); clk_set_rate(policy->clk, old_freq * 1000);
return r; return r;
} }
} }
...@@ -126,9 +114,9 @@ static int omap_cpu_init(struct cpufreq_policy *policy) ...@@ -126,9 +114,9 @@ static int omap_cpu_init(struct cpufreq_policy *policy)
{ {
int result; int result;
mpu_clk = clk_get(NULL, "cpufreq_ck"); policy->clk = clk_get(NULL, "cpufreq_ck");
if (IS_ERR(mpu_clk)) if (IS_ERR(policy->clk))
return PTR_ERR(mpu_clk); return PTR_ERR(policy->clk);
if (!freq_table) { if (!freq_table) {
result = dev_pm_opp_init_cpufreq_table(mpu_dev, &freq_table); result = dev_pm_opp_init_cpufreq_table(mpu_dev, &freq_table);
...@@ -149,7 +137,7 @@ static int omap_cpu_init(struct cpufreq_policy *policy) ...@@ -149,7 +137,7 @@ static int omap_cpu_init(struct cpufreq_policy *policy)
freq_table_free(); freq_table_free();
fail: fail:
clk_put(mpu_clk); clk_put(policy->clk);
return result; return result;
} }
...@@ -157,7 +145,7 @@ static int omap_cpu_exit(struct cpufreq_policy *policy) ...@@ -157,7 +145,7 @@ static int omap_cpu_exit(struct cpufreq_policy *policy)
{ {
cpufreq_frequency_table_put_attr(policy->cpu); cpufreq_frequency_table_put_attr(policy->cpu);
freq_table_free(); freq_table_free();
clk_put(mpu_clk); clk_put(policy->clk);
return 0; return 0;
} }
...@@ -165,7 +153,7 @@ static struct cpufreq_driver omap_driver = { ...@@ -165,7 +153,7 @@ static struct cpufreq_driver omap_driver = {
.flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK, .flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK,
.verify = cpufreq_generic_frequency_table_verify, .verify = cpufreq_generic_frequency_table_verify,
.target_index = omap_target, .target_index = omap_target,
.get = omap_getspeed, .get = cpufreq_generic_get,
.init = omap_cpu_init, .init = omap_cpu_init,
.exit = omap_cpu_exit, .exit = omap_cpu_exit,
.name = "omap", .name = "omap",
......
...@@ -24,12 +24,10 @@ ...@@ -24,12 +24,10 @@
/** /**
* struct cpu_data - per CPU data struct * struct cpu_data - per CPU data struct
* @clk: the clk of CPU
* @parent: the parent node of cpu clock * @parent: the parent node of cpu clock
* @table: frequency table * @table: frequency table
*/ */
struct cpu_data { struct cpu_data {
struct clk *clk;
struct device_node *parent; struct device_node *parent;
struct cpufreq_frequency_table *table; struct cpufreq_frequency_table *table;
}; };
...@@ -81,13 +79,6 @@ static inline const struct cpumask *cpu_core_mask(int cpu) ...@@ -81,13 +79,6 @@ static inline const struct cpumask *cpu_core_mask(int cpu)
} }
#endif #endif
static unsigned int corenet_cpufreq_get_speed(unsigned int cpu)
{
struct cpu_data *data = per_cpu(cpu_data, cpu);
return clk_get_rate(data->clk) / 1000;
}
/* reduce the duplicated frequencies in frequency table */ /* reduce the duplicated frequencies in frequency table */
static void freq_table_redup(struct cpufreq_frequency_table *freq_table, static void freq_table_redup(struct cpufreq_frequency_table *freq_table,
int count) int count)
...@@ -158,8 +149,8 @@ static int corenet_cpufreq_cpu_init(struct cpufreq_policy *policy) ...@@ -158,8 +149,8 @@ static int corenet_cpufreq_cpu_init(struct cpufreq_policy *policy)
goto err_np; goto err_np;
} }
data->clk = of_clk_get(np, 0); policy->clk = of_clk_get(np, 0);
if (IS_ERR(data->clk)) { if (IS_ERR(policy->clk)) {
pr_err("%s: no clock information\n", __func__); pr_err("%s: no clock information\n", __func__);
goto err_nomem2; goto err_nomem2;
} }
...@@ -255,7 +246,7 @@ static int corenet_cpufreq_target(struct cpufreq_policy *policy, ...@@ -255,7 +246,7 @@ static int corenet_cpufreq_target(struct cpufreq_policy *policy,
struct cpu_data *data = per_cpu(cpu_data, policy->cpu); struct cpu_data *data = per_cpu(cpu_data, policy->cpu);
parent = of_clk_get(data->parent, data->table[index].driver_data); parent = of_clk_get(data->parent, data->table[index].driver_data);
return clk_set_parent(data->clk, parent); return clk_set_parent(policy->clk, parent);
} }
static struct cpufreq_driver ppc_corenet_cpufreq_driver = { static struct cpufreq_driver ppc_corenet_cpufreq_driver = {
...@@ -265,7 +256,7 @@ static struct cpufreq_driver ppc_corenet_cpufreq_driver = { ...@@ -265,7 +256,7 @@ static struct cpufreq_driver ppc_corenet_cpufreq_driver = {
.exit = __exit_p(corenet_cpufreq_cpu_exit), .exit = __exit_p(corenet_cpufreq_cpu_exit),
.verify = cpufreq_generic_frequency_table_verify, .verify = cpufreq_generic_frequency_table_verify,
.target_index = corenet_cpufreq_target, .target_index = corenet_cpufreq_target,
.get = corenet_cpufreq_get_speed, .get = cpufreq_generic_get,
.attr = cpufreq_generic_attr, .attr = cpufreq_generic_attr,
}; };
......
...@@ -355,11 +355,6 @@ static int s3c_cpufreq_target(struct cpufreq_policy *policy, ...@@ -355,11 +355,6 @@ static int s3c_cpufreq_target(struct cpufreq_policy *policy,
return -EINVAL; return -EINVAL;
} }
static unsigned int s3c_cpufreq_get(unsigned int cpu)
{
return clk_get_rate(clk_arm) / 1000;
}
struct clk *s3c_cpufreq_clk_get(struct device *dev, const char *name) struct clk *s3c_cpufreq_clk_get(struct device *dev, const char *name)
{ {
struct clk *clk; struct clk *clk;
...@@ -373,6 +368,7 @@ struct clk *s3c_cpufreq_clk_get(struct device *dev, const char *name) ...@@ -373,6 +368,7 @@ struct clk *s3c_cpufreq_clk_get(struct device *dev, const char *name)
static int s3c_cpufreq_init(struct cpufreq_policy *policy) static int s3c_cpufreq_init(struct cpufreq_policy *policy)
{ {
policy->clk = clk_arm;
return cpufreq_generic_init(policy, ftab, cpu_cur.info->latency); return cpufreq_generic_init(policy, ftab, cpu_cur.info->latency);
} }
...@@ -408,7 +404,7 @@ static int s3c_cpufreq_suspend(struct cpufreq_policy *policy) ...@@ -408,7 +404,7 @@ static int s3c_cpufreq_suspend(struct cpufreq_policy *policy)
{ {
suspend_pll.frequency = clk_get_rate(_clk_mpll); suspend_pll.frequency = clk_get_rate(_clk_mpll);
suspend_pll.driver_data = __raw_readl(S3C2410_MPLLCON); suspend_pll.driver_data = __raw_readl(S3C2410_MPLLCON);
suspend_freq = s3c_cpufreq_get(0) * 1000; suspend_freq = clk_get_rate(clk_arm);
return 0; return 0;
} }
...@@ -450,7 +446,7 @@ static int s3c_cpufreq_resume(struct cpufreq_policy *policy) ...@@ -450,7 +446,7 @@ static int s3c_cpufreq_resume(struct cpufreq_policy *policy)
static struct cpufreq_driver s3c24xx_driver = { static struct cpufreq_driver s3c24xx_driver = {
.flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK, .flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK,
.target = s3c_cpufreq_target, .target = s3c_cpufreq_target,
.get = s3c_cpufreq_get, .get = cpufreq_generic_get,
.init = s3c_cpufreq_init, .init = s3c_cpufreq_init,
.suspend = s3c_cpufreq_suspend, .suspend = s3c_cpufreq_suspend,
.resume = s3c_cpufreq_resume, .resume = s3c_cpufreq_resume,
......
...@@ -19,7 +19,6 @@ ...@@ -19,7 +19,6 @@
#include <linux/regulator/consumer.h> #include <linux/regulator/consumer.h>
#include <linux/module.h> #include <linux/module.h>
static struct clk *armclk;
static struct regulator *vddarm; static struct regulator *vddarm;
static unsigned long regulator_latency; static unsigned long regulator_latency;
...@@ -54,14 +53,6 @@ static struct cpufreq_frequency_table s3c64xx_freq_table[] = { ...@@ -54,14 +53,6 @@ static struct cpufreq_frequency_table s3c64xx_freq_table[] = {
}; };
#endif #endif
static unsigned int s3c64xx_cpufreq_get_speed(unsigned int cpu)
{
if (cpu != 0)
return 0;
return clk_get_rate(armclk) / 1000;
}
static int s3c64xx_cpufreq_set_target(struct cpufreq_policy *policy, static int s3c64xx_cpufreq_set_target(struct cpufreq_policy *policy,
unsigned int index) unsigned int index)
{ {
...@@ -69,7 +60,7 @@ static int s3c64xx_cpufreq_set_target(struct cpufreq_policy *policy, ...@@ -69,7 +60,7 @@ static int s3c64xx_cpufreq_set_target(struct cpufreq_policy *policy,
unsigned int old_freq, new_freq; unsigned int old_freq, new_freq;
int ret; int ret;
old_freq = clk_get_rate(armclk) / 1000; old_freq = clk_get_rate(policy->clk) / 1000;
new_freq = s3c64xx_freq_table[index].frequency; new_freq = s3c64xx_freq_table[index].frequency;
dvfs = &s3c64xx_dvfs_table[s3c64xx_freq_table[index].driver_data]; dvfs = &s3c64xx_dvfs_table[s3c64xx_freq_table[index].driver_data];
...@@ -86,7 +77,7 @@ static int s3c64xx_cpufreq_set_target(struct cpufreq_policy *policy, ...@@ -86,7 +77,7 @@ static int s3c64xx_cpufreq_set_target(struct cpufreq_policy *policy,
} }
#endif #endif
ret = clk_set_rate(armclk, new_freq * 1000); ret = clk_set_rate(policy->clk, new_freq * 1000);
if (ret < 0) { if (ret < 0) {
pr_err("Failed to set rate %dkHz: %d\n", pr_err("Failed to set rate %dkHz: %d\n",
new_freq, ret); new_freq, ret);
...@@ -101,7 +92,7 @@ static int s3c64xx_cpufreq_set_target(struct cpufreq_policy *policy, ...@@ -101,7 +92,7 @@ static int s3c64xx_cpufreq_set_target(struct cpufreq_policy *policy,
if (ret != 0) { if (ret != 0) {
pr_err("Failed to set VDDARM for %dkHz: %d\n", pr_err("Failed to set VDDARM for %dkHz: %d\n",
new_freq, ret); new_freq, ret);
if (clk_set_rate(armclk, old_freq * 1000) < 0) if (clk_set_rate(policy->clk, old_freq * 1000) < 0)
pr_err("Failed to restore original clock rate\n"); pr_err("Failed to restore original clock rate\n");
return ret; return ret;
...@@ -110,7 +101,7 @@ static int s3c64xx_cpufreq_set_target(struct cpufreq_policy *policy, ...@@ -110,7 +101,7 @@ static int s3c64xx_cpufreq_set_target(struct cpufreq_policy *policy,
#endif #endif
pr_debug("Set actual frequency %lukHz\n", pr_debug("Set actual frequency %lukHz\n",
clk_get_rate(armclk) / 1000); clk_get_rate(policy->clk) / 1000);
return 0; return 0;
} }
...@@ -169,11 +160,11 @@ static int s3c64xx_cpufreq_driver_init(struct cpufreq_policy *policy) ...@@ -169,11 +160,11 @@ static int s3c64xx_cpufreq_driver_init(struct cpufreq_policy *policy)
return -ENODEV; return -ENODEV;
} }
armclk = clk_get(NULL, "armclk"); policy->clk = clk_get(NULL, "armclk");
if (IS_ERR(armclk)) { if (IS_ERR(policy->clk)) {
pr_err("Unable to obtain ARMCLK: %ld\n", pr_err("Unable to obtain ARMCLK: %ld\n",
PTR_ERR(armclk)); PTR_ERR(policy->clk));
return PTR_ERR(armclk); return PTR_ERR(policy->clk);
} }
#ifdef CONFIG_REGULATOR #ifdef CONFIG_REGULATOR
...@@ -193,7 +184,7 @@ static int s3c64xx_cpufreq_driver_init(struct cpufreq_policy *policy) ...@@ -193,7 +184,7 @@ static int s3c64xx_cpufreq_driver_init(struct cpufreq_policy *policy)
unsigned long r; unsigned long r;
/* Check for frequencies we can generate */ /* Check for frequencies we can generate */
r = clk_round_rate(armclk, freq->frequency * 1000); r = clk_round_rate(policy->clk, freq->frequency * 1000);
r /= 1000; r /= 1000;
if (r != freq->frequency) { if (r != freq->frequency) {
pr_debug("%dkHz unsupported by clock\n", pr_debug("%dkHz unsupported by clock\n",
...@@ -203,7 +194,7 @@ static int s3c64xx_cpufreq_driver_init(struct cpufreq_policy *policy) ...@@ -203,7 +194,7 @@ static int s3c64xx_cpufreq_driver_init(struct cpufreq_policy *policy)
/* If we have no regulator then assume startup /* If we have no regulator then assume startup
* frequency is the maximum we can support. */ * frequency is the maximum we can support. */
if (!vddarm && freq->frequency > s3c64xx_cpufreq_get_speed(0)) if (!vddarm && freq->frequency > clk_get_rate(policy->clk) / 1000)
freq->frequency = CPUFREQ_ENTRY_INVALID; freq->frequency = CPUFREQ_ENTRY_INVALID;
freq++; freq++;
...@@ -219,7 +210,7 @@ static int s3c64xx_cpufreq_driver_init(struct cpufreq_policy *policy) ...@@ -219,7 +210,7 @@ static int s3c64xx_cpufreq_driver_init(struct cpufreq_policy *policy)
pr_err("Failed to configure frequency table: %d\n", pr_err("Failed to configure frequency table: %d\n",
ret); ret);
regulator_put(vddarm); regulator_put(vddarm);
clk_put(armclk); clk_put(policy->clk);
} }
return ret; return ret;
...@@ -229,7 +220,7 @@ static struct cpufreq_driver s3c64xx_cpufreq_driver = { ...@@ -229,7 +220,7 @@ static struct cpufreq_driver s3c64xx_cpufreq_driver = {
.flags = CPUFREQ_NEED_INITIAL_FREQ_CHECK, .flags = CPUFREQ_NEED_INITIAL_FREQ_CHECK,
.verify = cpufreq_generic_frequency_table_verify, .verify = cpufreq_generic_frequency_table_verify,
.target_index = s3c64xx_cpufreq_set_target, .target_index = s3c64xx_cpufreq_set_target,
.get = s3c64xx_cpufreq_get_speed, .get = cpufreq_generic_get,
.init = s3c64xx_cpufreq_driver_init, .init = s3c64xx_cpufreq_driver_init,
.name = "s3c", .name = "s3c",
}; };
......
...@@ -23,7 +23,6 @@ ...@@ -23,7 +23,6 @@
#include <mach/map.h> #include <mach/map.h>
#include <mach/regs-clock.h> #include <mach/regs-clock.h>
static struct clk *cpu_clk;
static struct clk *dmc0_clk; static struct clk *dmc0_clk;
static struct clk *dmc1_clk; static struct clk *dmc1_clk;
static DEFINE_MUTEX(set_freq_lock); static DEFINE_MUTEX(set_freq_lock);
...@@ -164,14 +163,6 @@ static void s5pv210_set_refresh(enum s5pv210_dmc_port ch, unsigned long freq) ...@@ -164,14 +163,6 @@ static void s5pv210_set_refresh(enum s5pv210_dmc_port ch, unsigned long freq)
__raw_writel(tmp1, reg); __raw_writel(tmp1, reg);
} }
static unsigned int s5pv210_getspeed(unsigned int cpu)
{
if (cpu)
return 0;
return clk_get_rate(cpu_clk) / 1000;
}
static int s5pv210_target(struct cpufreq_policy *policy, unsigned int index) static int s5pv210_target(struct cpufreq_policy *policy, unsigned int index)
{ {
unsigned long reg; unsigned long reg;
...@@ -193,7 +184,7 @@ static int s5pv210_target(struct cpufreq_policy *policy, unsigned int index) ...@@ -193,7 +184,7 @@ static int s5pv210_target(struct cpufreq_policy *policy, unsigned int index)
goto exit; goto exit;
} }
old_freq = s5pv210_getspeed(0); old_freq = policy->cur;
new_freq = s5pv210_freq_table[index].frequency; new_freq = s5pv210_freq_table[index].frequency;
/* Finding current running level index */ /* Finding current running level index */
...@@ -471,9 +462,9 @@ static int __init s5pv210_cpu_init(struct cpufreq_policy *policy) ...@@ -471,9 +462,9 @@ static int __init s5pv210_cpu_init(struct cpufreq_policy *policy)
unsigned long mem_type; unsigned long mem_type;
int ret; int ret;
cpu_clk = clk_get(NULL, "armclk"); policy->clk = clk_get(NULL, "armclk");
if (IS_ERR(cpu_clk)) if (IS_ERR(policy->clk))
return PTR_ERR(cpu_clk); return PTR_ERR(policy->clk);
dmc0_clk = clk_get(NULL, "sclk_dmc0"); dmc0_clk = clk_get(NULL, "sclk_dmc0");
if (IS_ERR(dmc0_clk)) { if (IS_ERR(dmc0_clk)) {
...@@ -516,7 +507,7 @@ static int __init s5pv210_cpu_init(struct cpufreq_policy *policy) ...@@ -516,7 +507,7 @@ static int __init s5pv210_cpu_init(struct cpufreq_policy *policy)
out_dmc1: out_dmc1:
clk_put(dmc0_clk); clk_put(dmc0_clk);
out_dmc0: out_dmc0:
clk_put(cpu_clk); clk_put(policy->clk);
return ret; return ret;
} }
...@@ -563,7 +554,7 @@ static struct cpufreq_driver s5pv210_driver = { ...@@ -563,7 +554,7 @@ static struct cpufreq_driver s5pv210_driver = {
.flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK, .flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK,
.verify = cpufreq_generic_frequency_table_verify, .verify = cpufreq_generic_frequency_table_verify,
.target_index = s5pv210_target, .target_index = s5pv210_target,
.get = s5pv210_getspeed, .get = cpufreq_generic_get,
.init = s5pv210_cpu_init, .init = s5pv210_cpu_init,
.name = "s5pv210", .name = "s5pv210",
#ifdef CONFIG_PM #ifdef CONFIG_PM
......
...@@ -30,11 +30,6 @@ static struct { ...@@ -30,11 +30,6 @@ static struct {
u32 cnt; u32 cnt;
} spear_cpufreq; } spear_cpufreq;
static unsigned int spear_cpufreq_get(unsigned int cpu)
{
return clk_get_rate(spear_cpufreq.clk) / 1000;
}
static struct clk *spear1340_cpu_get_possible_parent(unsigned long newfreq) static struct clk *spear1340_cpu_get_possible_parent(unsigned long newfreq)
{ {
struct clk *sys_pclk; struct clk *sys_pclk;
...@@ -156,6 +151,7 @@ static int spear_cpufreq_target(struct cpufreq_policy *policy, ...@@ -156,6 +151,7 @@ static int spear_cpufreq_target(struct cpufreq_policy *policy,
static int spear_cpufreq_init(struct cpufreq_policy *policy) static int spear_cpufreq_init(struct cpufreq_policy *policy)
{ {
policy->clk = spear_cpufreq.clk;
return cpufreq_generic_init(policy, spear_cpufreq.freq_tbl, return cpufreq_generic_init(policy, spear_cpufreq.freq_tbl,
spear_cpufreq.transition_latency); spear_cpufreq.transition_latency);
} }
...@@ -165,7 +161,7 @@ static struct cpufreq_driver spear_cpufreq_driver = { ...@@ -165,7 +161,7 @@ static struct cpufreq_driver spear_cpufreq_driver = {
.flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK, .flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK,
.verify = cpufreq_generic_frequency_table_verify, .verify = cpufreq_generic_frequency_table_verify,
.target_index = spear_cpufreq_target, .target_index = spear_cpufreq_target,
.get = spear_cpufreq_get, .get = cpufreq_generic_get,
.init = spear_cpufreq_init, .init = spear_cpufreq_init,
.exit = cpufreq_generic_exit, .exit = cpufreq_generic_exit,
.attr = cpufreq_generic_attr, .attr = cpufreq_generic_attr,
......
...@@ -47,21 +47,9 @@ static struct clk *pll_x_clk; ...@@ -47,21 +47,9 @@ static struct clk *pll_x_clk;
static struct clk *pll_p_clk; static struct clk *pll_p_clk;
static struct clk *emc_clk; static struct clk *emc_clk;
static unsigned long target_cpu_speed[NUM_CPUS];
static DEFINE_MUTEX(tegra_cpu_lock); static DEFINE_MUTEX(tegra_cpu_lock);
static bool is_suspended; static bool is_suspended;
static unsigned int tegra_getspeed(unsigned int cpu)
{
unsigned long rate;
if (cpu >= NUM_CPUS)
return 0;
rate = clk_get_rate(cpu_clk) / 1000;
return rate;
}
static int tegra_cpu_clk_set_rate(unsigned long rate) static int tegra_cpu_clk_set_rate(unsigned long rate)
{ {
int ret; int ret;
...@@ -103,9 +91,6 @@ static int tegra_update_cpu_speed(struct cpufreq_policy *policy, ...@@ -103,9 +91,6 @@ static int tegra_update_cpu_speed(struct cpufreq_policy *policy,
{ {
int ret = 0; int ret = 0;
if (tegra_getspeed(0) == rate)
return ret;
/* /*
* Vote on memory bus frequency based on cpu frequency * Vote on memory bus frequency based on cpu frequency
* This sets the minimum frequency, display or avp may request higher * This sets the minimum frequency, display or avp may request higher
...@@ -125,33 +110,16 @@ static int tegra_update_cpu_speed(struct cpufreq_policy *policy, ...@@ -125,33 +110,16 @@ static int tegra_update_cpu_speed(struct cpufreq_policy *policy,
return ret; return ret;
} }
static unsigned long tegra_cpu_highest_speed(void)
{
unsigned long rate = 0;
int i;
for_each_online_cpu(i)
rate = max(rate, target_cpu_speed[i]);
return rate;
}
static int tegra_target(struct cpufreq_policy *policy, unsigned int index) static int tegra_target(struct cpufreq_policy *policy, unsigned int index)
{ {
unsigned int freq; int ret = -EBUSY;
int ret = 0;
mutex_lock(&tegra_cpu_lock); mutex_lock(&tegra_cpu_lock);
if (is_suspended) if (!is_suspended)
goto out; ret = tegra_update_cpu_speed(policy,
freq_table[index].frequency);
freq = freq_table[index].frequency;
target_cpu_speed[policy->cpu] = freq;
ret = tegra_update_cpu_speed(policy, tegra_cpu_highest_speed());
out:
mutex_unlock(&tegra_cpu_lock); mutex_unlock(&tegra_cpu_lock);
return ret; return ret;
} }
...@@ -165,6 +133,7 @@ static int tegra_pm_notify(struct notifier_block *nb, unsigned long event, ...@@ -165,6 +133,7 @@ static int tegra_pm_notify(struct notifier_block *nb, unsigned long event,
is_suspended = true; is_suspended = true;
pr_info("Tegra cpufreq suspend: setting frequency to %d kHz\n", pr_info("Tegra cpufreq suspend: setting frequency to %d kHz\n",
freq_table[0].frequency); freq_table[0].frequency);
if (clk_get_rate(cpu_clk) / 1000 != freq_table[0].frequency)
tegra_update_cpu_speed(policy, freq_table[0].frequency); tegra_update_cpu_speed(policy, freq_table[0].frequency);
cpufreq_cpu_put(policy); cpufreq_cpu_put(policy);
} else if (event == PM_POST_SUSPEND) { } else if (event == PM_POST_SUSPEND) {
...@@ -189,8 +158,6 @@ static int tegra_cpu_init(struct cpufreq_policy *policy) ...@@ -189,8 +158,6 @@ static int tegra_cpu_init(struct cpufreq_policy *policy)
clk_prepare_enable(emc_clk); clk_prepare_enable(emc_clk);
clk_prepare_enable(cpu_clk); clk_prepare_enable(cpu_clk);
target_cpu_speed[policy->cpu] = tegra_getspeed(policy->cpu);
/* FIXME: what's the actual transition time? */ /* FIXME: what's the actual transition time? */
ret = cpufreq_generic_init(policy, freq_table, 300 * 1000); ret = cpufreq_generic_init(policy, freq_table, 300 * 1000);
if (ret) { if (ret) {
...@@ -202,6 +169,7 @@ static int tegra_cpu_init(struct cpufreq_policy *policy) ...@@ -202,6 +169,7 @@ static int tegra_cpu_init(struct cpufreq_policy *policy)
if (policy->cpu == 0) if (policy->cpu == 0)
register_pm_notifier(&tegra_cpu_pm_notifier); register_pm_notifier(&tegra_cpu_pm_notifier);
policy->clk = cpu_clk;
return 0; return 0;
} }
...@@ -217,7 +185,7 @@ static struct cpufreq_driver tegra_cpufreq_driver = { ...@@ -217,7 +185,7 @@ static struct cpufreq_driver tegra_cpufreq_driver = {
.flags = CPUFREQ_NEED_INITIAL_FREQ_CHECK, .flags = CPUFREQ_NEED_INITIAL_FREQ_CHECK,
.verify = cpufreq_generic_frequency_table_verify, .verify = cpufreq_generic_frequency_table_verify,
.target_index = tegra_target, .target_index = tegra_target,
.get = tegra_getspeed, .get = cpufreq_generic_get,
.init = tegra_cpu_init, .init = tegra_cpu_init,
.exit = tegra_cpu_exit, .exit = tegra_cpu_exit,
.name = "tegra", .name = "tegra",
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
* published by the Free Software Foundation. * published by the Free Software Foundation.
*/ */
#include <linux/err.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/init.h> #include <linux/init.h>
...@@ -33,28 +34,18 @@ static int ucv2_verify_speed(struct cpufreq_policy *policy) ...@@ -33,28 +34,18 @@ static int ucv2_verify_speed(struct cpufreq_policy *policy)
return 0; return 0;
} }
static unsigned int ucv2_getspeed(unsigned int cpu)
{
struct clk *mclk = clk_get(NULL, "MAIN_CLK");
if (cpu)
return 0;
return clk_get_rate(mclk)/1000;
}
static int ucv2_target(struct cpufreq_policy *policy, static int ucv2_target(struct cpufreq_policy *policy,
unsigned int target_freq, unsigned int target_freq,
unsigned int relation) unsigned int relation)
{ {
struct cpufreq_freqs freqs; struct cpufreq_freqs freqs;
struct clk *mclk = clk_get(NULL, "MAIN_CLK");
int ret; int ret;
freqs.old = policy->cur; freqs.old = policy->cur;
freqs.new = target_freq; freqs.new = target_freq;
cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
ret = clk_set_rate(mclk, target_freq * 1000); ret = clk_set_rate(policy->mclk, target_freq * 1000);
cpufreq_notify_post_transition(policy, &freqs, ret); cpufreq_notify_post_transition(policy, &freqs, ret);
return ret; return ret;
...@@ -64,9 +55,13 @@ static int __init ucv2_cpu_init(struct cpufreq_policy *policy) ...@@ -64,9 +55,13 @@ static int __init ucv2_cpu_init(struct cpufreq_policy *policy)
{ {
if (policy->cpu != 0) if (policy->cpu != 0)
return -EINVAL; return -EINVAL;
policy->min = policy->cpuinfo.min_freq = 250000; policy->min = policy->cpuinfo.min_freq = 250000;
policy->max = policy->cpuinfo.max_freq = 1000000; policy->max = policy->cpuinfo.max_freq = 1000000;
policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
policy->clk = clk_get(NULL, "MAIN_CLK");
if (IS_ERR(policy->clk))
return PTR_ERR(policy->clk);
return 0; return 0;
} }
...@@ -74,7 +69,7 @@ static struct cpufreq_driver ucv2_driver = { ...@@ -74,7 +69,7 @@ static struct cpufreq_driver ucv2_driver = {
.flags = CPUFREQ_STICKY, .flags = CPUFREQ_STICKY,
.verify = ucv2_verify_speed, .verify = ucv2_verify_speed,
.target = ucv2_target, .target = ucv2_target,
.get = ucv2_getspeed, .get = cpufreq_generic_get,
.init = ucv2_cpu_init, .init = ucv2_cpu_init,
.name = "UniCore-II", .name = "UniCore-II",
}; };
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#ifndef _LINUX_CPUFREQ_H #ifndef _LINUX_CPUFREQ_H
#define _LINUX_CPUFREQ_H #define _LINUX_CPUFREQ_H
#include <linux/clk.h>
#include <linux/cpumask.h> #include <linux/cpumask.h>
#include <linux/completion.h> #include <linux/completion.h>
#include <linux/kobject.h> #include <linux/kobject.h>
...@@ -66,6 +67,7 @@ struct cpufreq_policy { ...@@ -66,6 +67,7 @@ struct cpufreq_policy {
unsigned int cpu; /* cpu nr of CPU managing this policy */ unsigned int cpu; /* cpu nr of CPU managing this policy */
unsigned int last_cpu; /* cpu nr of previous CPU that managed unsigned int last_cpu; /* cpu nr of previous CPU that managed
* this policy */ * this policy */
struct clk *clk;
struct cpufreq_cpuinfo cpuinfo;/* see above */ struct cpufreq_cpuinfo cpuinfo;/* see above */
unsigned int min; /* in kHz */ unsigned int min; /* in kHz */
...@@ -470,6 +472,7 @@ void cpufreq_frequency_table_put_attr(unsigned int cpu); ...@@ -470,6 +472,7 @@ void cpufreq_frequency_table_put_attr(unsigned int cpu);
int cpufreq_table_validate_and_show(struct cpufreq_policy *policy, int cpufreq_table_validate_and_show(struct cpufreq_policy *policy,
struct cpufreq_frequency_table *table); struct cpufreq_frequency_table *table);
unsigned int cpufreq_generic_get(unsigned int cpu);
int cpufreq_generic_init(struct cpufreq_policy *policy, int cpufreq_generic_init(struct cpufreq_policy *policy,
struct cpufreq_frequency_table *table, struct cpufreq_frequency_table *table,
unsigned int transition_latency); unsigned int transition_latency);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment