diff options
author | Scott Wood <scottwood@freescale.com> | 2014-04-07 23:49:35 (GMT) |
---|---|---|
committer | Scott Wood <scottwood@freescale.com> | 2014-04-07 23:49:35 (GMT) |
commit | 62b8c978ee6b8d135d9e7953221de58000dba986 (patch) | |
tree | 683b04b2e627f6710c22c151b23c8cc9a165315e /drivers/cpufreq/s3c64xx-cpufreq.c | |
parent | 78fd82238d0e5716578c326404184a27ba67fd6e (diff) | |
download | linux-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.c | 81 |
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", |