diff options
Diffstat (limited to 'arch/arm/mach-davinci/cpufreq.c')
-rw-r--r-- | arch/arm/mach-davinci/cpufreq.c | 28 |
1 files changed, 26 insertions, 2 deletions
diff --git a/arch/arm/mach-davinci/cpufreq.c b/arch/arm/mach-davinci/cpufreq.c index d3fa6de1e20f..343de73161fa 100644 --- a/arch/arm/mach-davinci/cpufreq.c +++ b/arch/arm/mach-davinci/cpufreq.c | |||
@@ -34,6 +34,8 @@ | |||
34 | struct davinci_cpufreq { | 34 | struct davinci_cpufreq { |
35 | struct device *dev; | 35 | struct device *dev; |
36 | struct clk *armclk; | 36 | struct clk *armclk; |
37 | struct clk *asyncclk; | ||
38 | unsigned long asyncrate; | ||
37 | }; | 39 | }; |
38 | static struct davinci_cpufreq cpufreq; | 40 | static struct davinci_cpufreq cpufreq; |
39 | 41 | ||
@@ -104,15 +106,27 @@ static int davinci_target(struct cpufreq_policy *policy, | |||
104 | cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); | 106 | cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); |
105 | 107 | ||
106 | /* if moving to higher frequency, up the voltage beforehand */ | 108 | /* if moving to higher frequency, up the voltage beforehand */ |
107 | if (pdata->set_voltage && freqs.new > freqs.old) | 109 | if (pdata->set_voltage && freqs.new > freqs.old) { |
108 | pdata->set_voltage(idx); | 110 | ret = pdata->set_voltage(idx); |
111 | if (ret) | ||
112 | goto out; | ||
113 | } | ||
109 | 114 | ||
110 | ret = clk_set_rate(armclk, idx); | 115 | ret = clk_set_rate(armclk, idx); |
116 | if (ret) | ||
117 | goto out; | ||
118 | |||
119 | if (cpufreq.asyncclk) { | ||
120 | ret = clk_set_rate(cpufreq.asyncclk, cpufreq.asyncrate); | ||
121 | if (ret) | ||
122 | goto out; | ||
123 | } | ||
111 | 124 | ||
112 | /* if moving to lower freq, lower the voltage after lowering freq */ | 125 | /* if moving to lower freq, lower the voltage after lowering freq */ |
113 | if (pdata->set_voltage && freqs.new < freqs.old) | 126 | if (pdata->set_voltage && freqs.new < freqs.old) |
114 | pdata->set_voltage(idx); | 127 | pdata->set_voltage(idx); |
115 | 128 | ||
129 | out: | ||
116 | cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); | 130 | cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); |
117 | 131 | ||
118 | return ret; | 132 | return ret; |
@@ -185,6 +199,7 @@ static struct cpufreq_driver davinci_driver = { | |||
185 | static int __init davinci_cpufreq_probe(struct platform_device *pdev) | 199 | static int __init davinci_cpufreq_probe(struct platform_device *pdev) |
186 | { | 200 | { |
187 | struct davinci_cpufreq_config *pdata = pdev->dev.platform_data; | 201 | struct davinci_cpufreq_config *pdata = pdev->dev.platform_data; |
202 | struct clk *asyncclk; | ||
188 | 203 | ||
189 | if (!pdata) | 204 | if (!pdata) |
190 | return -EINVAL; | 205 | return -EINVAL; |
@@ -199,6 +214,12 @@ static int __init davinci_cpufreq_probe(struct platform_device *pdev) | |||
199 | return PTR_ERR(cpufreq.armclk); | 214 | return PTR_ERR(cpufreq.armclk); |
200 | } | 215 | } |
201 | 216 | ||
217 | asyncclk = clk_get(cpufreq.dev, "async"); | ||
218 | if (!IS_ERR(asyncclk)) { | ||
219 | cpufreq.asyncclk = asyncclk; | ||
220 | cpufreq.asyncrate = clk_get_rate(asyncclk); | ||
221 | } | ||
222 | |||
202 | return cpufreq_register_driver(&davinci_driver); | 223 | return cpufreq_register_driver(&davinci_driver); |
203 | } | 224 | } |
204 | 225 | ||
@@ -206,6 +227,9 @@ static int __exit davinci_cpufreq_remove(struct platform_device *pdev) | |||
206 | { | 227 | { |
207 | clk_put(cpufreq.armclk); | 228 | clk_put(cpufreq.armclk); |
208 | 229 | ||
230 | if (cpufreq.asyncclk) | ||
231 | clk_put(cpufreq.asyncclk); | ||
232 | |||
209 | return cpufreq_unregister_driver(&davinci_driver); | 233 | return cpufreq_unregister_driver(&davinci_driver); |
210 | } | 234 | } |
211 | 235 | ||