summaryrefslogtreecommitdiff
path: root/drivers/cpufreq/s3c64xx-cpufreq.c
diff options
context:
space:
mode:
authorScott Wood <scottwood@freescale.com>2014-04-07 23:49:35 (GMT)
committerScott Wood <scottwood@freescale.com>2014-04-07 23:49:35 (GMT)
commit62b8c978ee6b8d135d9e7953221de58000dba986 (patch)
tree683b04b2e627f6710c22c151b23c8cc9a165315e /drivers/cpufreq/s3c64xx-cpufreq.c
parent78fd82238d0e5716578c326404184a27ba67fd6e (diff)
downloadlinux-fsl-qoriq-62b8c978ee6b8d135d9e7953221de58000dba986.tar.xz
Rewind v3.13-rc3+ (78fd82238d0e5716) to v3.12
Diffstat (limited to 'drivers/cpufreq/s3c64xx-cpufreq.c')
-rw-r--r--drivers/cpufreq/s3c64xx-cpufreq.c81
1 files changed, 59 insertions, 22 deletions
diff --git a/drivers/cpufreq/s3c64xx-cpufreq.c b/drivers/cpufreq/s3c64xx-cpufreq.c
index 67e302e..15631f9 100644
--- a/drivers/cpufreq/s3c64xx-cpufreq.c
+++ b/drivers/cpufreq/s3c64xx-cpufreq.c
@@ -54,6 +54,14 @@ static struct cpufreq_frequency_table s3c64xx_freq_table[] = {
};
#endif
+static int s3c64xx_cpufreq_verify_speed(struct cpufreq_policy *policy)
+{
+ if (policy->cpu != 0)
+ return -EINVAL;
+
+ return cpufreq_frequency_table_verify(policy, s3c64xx_freq_table);
+}
+
static unsigned int s3c64xx_cpufreq_get_speed(unsigned int cpu)
{
if (cpu != 0)
@@ -63,48 +71,66 @@ static unsigned int s3c64xx_cpufreq_get_speed(unsigned int cpu)
}
static int s3c64xx_cpufreq_set_target(struct cpufreq_policy *policy,
- unsigned int index)
+ unsigned int target_freq,
+ unsigned int relation)
{
- struct s3c64xx_dvfs *dvfs;
- unsigned int old_freq, new_freq;
int ret;
+ unsigned int i;
+ struct cpufreq_freqs freqs;
+ struct s3c64xx_dvfs *dvfs;
+
+ ret = cpufreq_frequency_table_target(policy, s3c64xx_freq_table,
+ target_freq, relation, &i);
+ if (ret != 0)
+ return ret;
+
+ freqs.old = clk_get_rate(armclk) / 1000;
+ freqs.new = s3c64xx_freq_table[i].frequency;
+ freqs.flags = 0;
+ dvfs = &s3c64xx_dvfs_table[s3c64xx_freq_table[i].driver_data];
- old_freq = clk_get_rate(armclk) / 1000;
- new_freq = s3c64xx_freq_table[index].frequency;
- dvfs = &s3c64xx_dvfs_table[s3c64xx_freq_table[index].driver_data];
+ if (freqs.old == freqs.new)
+ return 0;
+
+ pr_debug("Transition %d-%dkHz\n", freqs.old, freqs.new);
+
+ cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
#ifdef CONFIG_REGULATOR
- if (vddarm && new_freq > old_freq) {
+ if (vddarm && freqs.new > freqs.old) {
ret = regulator_set_voltage(vddarm,
dvfs->vddarm_min,
dvfs->vddarm_max);
if (ret != 0) {
pr_err("Failed to set VDDARM for %dkHz: %d\n",
- new_freq, ret);
- return ret;
+ freqs.new, ret);
+ freqs.new = freqs.old;
+ goto post_notify;
}
}
#endif
- ret = clk_set_rate(armclk, new_freq * 1000);
+ ret = clk_set_rate(armclk, freqs.new * 1000);
if (ret < 0) {
pr_err("Failed to set rate %dkHz: %d\n",
- new_freq, ret);
- return ret;
+ freqs.new, ret);
+ freqs.new = freqs.old;
}
+post_notify:
+ cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
+ if (ret)
+ goto err;
+
#ifdef CONFIG_REGULATOR
- if (vddarm && new_freq < old_freq) {
+ if (vddarm && freqs.new < freqs.old) {
ret = regulator_set_voltage(vddarm,
dvfs->vddarm_min,
dvfs->vddarm_max);
if (ret != 0) {
pr_err("Failed to set VDDARM for %dkHz: %d\n",
- new_freq, ret);
- if (clk_set_rate(armclk, old_freq * 1000) < 0)
- pr_err("Failed to restore original clock rate\n");
-
- return ret;
+ freqs.new, ret);
+ goto err_clk;
}
}
#endif
@@ -113,6 +139,14 @@ static int s3c64xx_cpufreq_set_target(struct cpufreq_policy *policy,
clk_get_rate(armclk) / 1000);
return 0;
+
+err_clk:
+ if (clk_set_rate(armclk, freqs.old * 1000) < 0)
+ pr_err("Failed to restore original clock rate\n");
+err:
+ cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
+
+ return ret;
}
#ifdef CONFIG_REGULATOR
@@ -209,12 +243,15 @@ static int s3c64xx_cpufreq_driver_init(struct cpufreq_policy *policy)
freq++;
}
+ policy->cur = clk_get_rate(armclk) / 1000;
+
/* Datasheet says PLL stabalisation time (if we were to use
* the PLLs, which we don't currently) is ~300us worst case,
* but add some fudge.
*/
- ret = cpufreq_generic_init(policy, s3c64xx_freq_table,
- (500 * 1000) + regulator_latency);
+ policy->cpuinfo.transition_latency = (500 * 1000) + regulator_latency;
+
+ ret = cpufreq_frequency_table_cpuinfo(policy, s3c64xx_freq_table);
if (ret != 0) {
pr_err("Failed to configure frequency table: %d\n",
ret);
@@ -227,8 +264,8 @@ static int s3c64xx_cpufreq_driver_init(struct cpufreq_policy *policy)
static struct cpufreq_driver s3c64xx_cpufreq_driver = {
.flags = 0,
- .verify = cpufreq_generic_frequency_table_verify,
- .target_index = s3c64xx_cpufreq_set_target,
+ .verify = s3c64xx_cpufreq_verify_speed,
+ .target = s3c64xx_cpufreq_set_target,
.get = s3c64xx_cpufreq_get_speed,
.init = s3c64xx_cpufreq_driver_init,
.name = "s3c",