diff options
author | Viresh Kumar <viresh.kumar@linaro.org> | 2013-08-14 10:08:24 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2013-10-30 19:11:08 -0400 |
commit | d4019f0a92ab802f385cc9c8ad3ab7b5449712cb (patch) | |
tree | ebd06695585e457ae1bf219653452b111e7508db /drivers/cpufreq/s3c64xx-cpufreq.c | |
parent | 7dbf694db6ac7c759599316d50d7050efcbd512a (diff) |
cpufreq: move freq change notifications to cpufreq core
Most of the drivers do following in their ->target_index() routines:
struct cpufreq_freqs freqs;
freqs.old = old freq...
freqs.new = new freq...
cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
/* Change rate here */
cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
This is replicated over all cpufreq drivers today and there doesn't exists a
good enough reason why this shouldn't be moved to cpufreq core instead.
There are few special cases though, like exynos5440, which doesn't do everything
on the call to ->target_index() routine and call some kind of bottom halves for
doing this work, work/tasklet/etc..
They may continue doing notification from their own code as flag:
CPUFREQ_ASYNC_NOTIFICATION is already set for them.
All drivers are also modified in this patch to avoid breaking 'git bisect', as
double notification would happen otherwise.
Acked-by: Hans-Christian Egtvedt <egtvedt@samfundet.no>
Acked-by: Jesper Nilsson <jesper.nilsson@axis.com>
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Acked-by: Russell King <linux@arm.linux.org.uk>
Acked-by: Stephen Warren <swarren@nvidia.com>
Tested-by: Andrew Lunn <andrew@lunn.ch>
Tested-by: Nicolas Pitre <nicolas.pitre@linaro.org>
Reviewed-by: Lan Tianyu <tianyu.lan@intel.com>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/cpufreq/s3c64xx-cpufreq.c')
-rw-r--r-- | drivers/cpufreq/s3c64xx-cpufreq.c | 48 |
1 files changed, 16 insertions, 32 deletions
diff --git a/drivers/cpufreq/s3c64xx-cpufreq.c b/drivers/cpufreq/s3c64xx-cpufreq.c index 8bdcf32a4418..67e302eeefec 100644 --- a/drivers/cpufreq/s3c64xx-cpufreq.c +++ b/drivers/cpufreq/s3c64xx-cpufreq.c | |||
@@ -65,54 +65,46 @@ static unsigned int s3c64xx_cpufreq_get_speed(unsigned int cpu) | |||
65 | static int s3c64xx_cpufreq_set_target(struct cpufreq_policy *policy, | 65 | static int s3c64xx_cpufreq_set_target(struct cpufreq_policy *policy, |
66 | unsigned int index) | 66 | unsigned int index) |
67 | { | 67 | { |
68 | int ret; | ||
69 | struct cpufreq_freqs freqs; | ||
70 | struct s3c64xx_dvfs *dvfs; | 68 | struct s3c64xx_dvfs *dvfs; |
69 | unsigned int old_freq, new_freq; | ||
70 | int ret; | ||
71 | 71 | ||
72 | freqs.old = clk_get_rate(armclk) / 1000; | 72 | old_freq = clk_get_rate(armclk) / 1000; |
73 | freqs.new = s3c64xx_freq_table[index].frequency; | 73 | new_freq = s3c64xx_freq_table[index].frequency; |
74 | freqs.flags = 0; | ||
75 | dvfs = &s3c64xx_dvfs_table[s3c64xx_freq_table[index].driver_data]; | 74 | dvfs = &s3c64xx_dvfs_table[s3c64xx_freq_table[index].driver_data]; |
76 | 75 | ||
77 | pr_debug("Transition %d-%dkHz\n", freqs.old, freqs.new); | ||
78 | |||
79 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); | ||
80 | |||
81 | #ifdef CONFIG_REGULATOR | 76 | #ifdef CONFIG_REGULATOR |
82 | if (vddarm && freqs.new > freqs.old) { | 77 | if (vddarm && new_freq > old_freq) { |
83 | ret = regulator_set_voltage(vddarm, | 78 | ret = regulator_set_voltage(vddarm, |
84 | dvfs->vddarm_min, | 79 | dvfs->vddarm_min, |
85 | dvfs->vddarm_max); | 80 | dvfs->vddarm_max); |
86 | if (ret != 0) { | 81 | if (ret != 0) { |
87 | pr_err("Failed to set VDDARM for %dkHz: %d\n", | 82 | pr_err("Failed to set VDDARM for %dkHz: %d\n", |
88 | freqs.new, ret); | 83 | new_freq, ret); |
89 | freqs.new = freqs.old; | 84 | return ret; |
90 | goto post_notify; | ||
91 | } | 85 | } |
92 | } | 86 | } |
93 | #endif | 87 | #endif |
94 | 88 | ||
95 | ret = clk_set_rate(armclk, freqs.new * 1000); | 89 | ret = clk_set_rate(armclk, new_freq * 1000); |
96 | if (ret < 0) { | 90 | if (ret < 0) { |
97 | pr_err("Failed to set rate %dkHz: %d\n", | 91 | pr_err("Failed to set rate %dkHz: %d\n", |
98 | freqs.new, ret); | 92 | new_freq, ret); |
99 | freqs.new = freqs.old; | 93 | return ret; |
100 | } | 94 | } |
101 | 95 | ||
102 | post_notify: | ||
103 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); | ||
104 | if (ret) | ||
105 | goto err; | ||
106 | |||
107 | #ifdef CONFIG_REGULATOR | 96 | #ifdef CONFIG_REGULATOR |
108 | if (vddarm && freqs.new < freqs.old) { | 97 | if (vddarm && new_freq < old_freq) { |
109 | ret = regulator_set_voltage(vddarm, | 98 | ret = regulator_set_voltage(vddarm, |
110 | dvfs->vddarm_min, | 99 | dvfs->vddarm_min, |
111 | dvfs->vddarm_max); | 100 | dvfs->vddarm_max); |
112 | if (ret != 0) { | 101 | if (ret != 0) { |
113 | pr_err("Failed to set VDDARM for %dkHz: %d\n", | 102 | pr_err("Failed to set VDDARM for %dkHz: %d\n", |
114 | freqs.new, ret); | 103 | new_freq, ret); |
115 | goto err_clk; | 104 | if (clk_set_rate(armclk, old_freq * 1000) < 0) |
105 | pr_err("Failed to restore original clock rate\n"); | ||
106 | |||
107 | return ret; | ||
116 | } | 108 | } |
117 | } | 109 | } |
118 | #endif | 110 | #endif |
@@ -121,14 +113,6 @@ post_notify: | |||
121 | clk_get_rate(armclk) / 1000); | 113 | clk_get_rate(armclk) / 1000); |
122 | 114 | ||
123 | return 0; | 115 | return 0; |
124 | |||
125 | err_clk: | ||
126 | if (clk_set_rate(armclk, freqs.old * 1000) < 0) | ||
127 | pr_err("Failed to restore original clock rate\n"); | ||
128 | err: | ||
129 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); | ||
130 | |||
131 | return ret; | ||
132 | } | 116 | } |
133 | 117 | ||
134 | #ifdef CONFIG_REGULATOR | 118 | #ifdef CONFIG_REGULATOR |