aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-davinci/cpufreq.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-davinci/cpufreq.c')
-rw-r--r--arch/arm/mach-davinci/cpufreq.c36
1 files changed, 29 insertions, 7 deletions
diff --git a/arch/arm/mach-davinci/cpufreq.c b/arch/arm/mach-davinci/cpufreq.c
index d3fa6de1e20f..41669ecc1f91 100644
--- a/arch/arm/mach-davinci/cpufreq.c
+++ b/arch/arm/mach-davinci/cpufreq.c
@@ -34,6 +34,8 @@
34struct davinci_cpufreq { 34struct 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};
38static struct davinci_cpufreq cpufreq; 40static struct davinci_cpufreq cpufreq;
39 41
@@ -92,9 +94,7 @@ static int davinci_target(struct cpufreq_policy *policy,
92 if (freqs.old == freqs.new) 94 if (freqs.old == freqs.new)
93 return ret; 95 return ret;
94 96
95 cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, 97 dev_dbg(&cpufreq.dev, "transition: %u --> %u\n", freqs.old, freqs.new);
96 dev_driver_string(cpufreq.dev),
97 "transition: %u --> %u\n", freqs.old, freqs.new);
98 98
99 ret = cpufreq_frequency_table_target(policy, pdata->freq_table, 99 ret = cpufreq_frequency_table_target(policy, pdata->freq_table,
100 freqs.new, relation, &idx); 100 freqs.new, relation, &idx);
@@ -104,21 +104,33 @@ static int davinci_target(struct cpufreq_policy *policy,
104 cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); 104 cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
105 105
106 /* if moving to higher frequency, up the voltage beforehand */ 106 /* if moving to higher frequency, up the voltage beforehand */
107 if (pdata->set_voltage && freqs.new > freqs.old) 107 if (pdata->set_voltage && freqs.new > freqs.old) {
108 pdata->set_voltage(idx); 108 ret = pdata->set_voltage(idx);
109 if (ret)
110 goto out;
111 }
109 112
110 ret = clk_set_rate(armclk, idx); 113 ret = clk_set_rate(armclk, idx);
114 if (ret)
115 goto out;
116
117 if (cpufreq.asyncclk) {
118 ret = clk_set_rate(cpufreq.asyncclk, cpufreq.asyncrate);
119 if (ret)
120 goto out;
121 }
111 122
112 /* if moving to lower freq, lower the voltage after lowering freq */ 123 /* if moving to lower freq, lower the voltage after lowering freq */
113 if (pdata->set_voltage && freqs.new < freqs.old) 124 if (pdata->set_voltage && freqs.new < freqs.old)
114 pdata->set_voltage(idx); 125 pdata->set_voltage(idx);
115 126
127out:
116 cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); 128 cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
117 129
118 return ret; 130 return ret;
119} 131}
120 132
121static int __init davinci_cpu_init(struct cpufreq_policy *policy) 133static int davinci_cpu_init(struct cpufreq_policy *policy)
122{ 134{
123 int result = 0; 135 int result = 0;
124 struct davinci_cpufreq_config *pdata = cpufreq.dev->platform_data; 136 struct davinci_cpufreq_config *pdata = cpufreq.dev->platform_data;
@@ -153,7 +165,7 @@ static int __init davinci_cpu_init(struct cpufreq_policy *policy)
153 /* 165 /*
154 * Time measurement across the target() function yields ~1500-1800us 166 * Time measurement across the target() function yields ~1500-1800us
155 * time taken with no drivers on notification list. 167 * time taken with no drivers on notification list.
156 * Setting the latency to 2000 us to accomodate addition of drivers 168 * Setting the latency to 2000 us to accommodate addition of drivers
157 * to pre/post change notification list. 169 * to pre/post change notification list.
158 */ 170 */
159 policy->cpuinfo.transition_latency = 2000 * 1000; 171 policy->cpuinfo.transition_latency = 2000 * 1000;
@@ -185,6 +197,7 @@ static struct cpufreq_driver davinci_driver = {
185static int __init davinci_cpufreq_probe(struct platform_device *pdev) 197static int __init davinci_cpufreq_probe(struct platform_device *pdev)
186{ 198{
187 struct davinci_cpufreq_config *pdata = pdev->dev.platform_data; 199 struct davinci_cpufreq_config *pdata = pdev->dev.platform_data;
200 struct clk *asyncclk;
188 201
189 if (!pdata) 202 if (!pdata)
190 return -EINVAL; 203 return -EINVAL;
@@ -199,6 +212,12 @@ static int __init davinci_cpufreq_probe(struct platform_device *pdev)
199 return PTR_ERR(cpufreq.armclk); 212 return PTR_ERR(cpufreq.armclk);
200 } 213 }
201 214
215 asyncclk = clk_get(cpufreq.dev, "async");
216 if (!IS_ERR(asyncclk)) {
217 cpufreq.asyncclk = asyncclk;
218 cpufreq.asyncrate = clk_get_rate(asyncclk);
219 }
220
202 return cpufreq_register_driver(&davinci_driver); 221 return cpufreq_register_driver(&davinci_driver);
203} 222}
204 223
@@ -206,6 +225,9 @@ static int __exit davinci_cpufreq_remove(struct platform_device *pdev)
206{ 225{
207 clk_put(cpufreq.armclk); 226 clk_put(cpufreq.armclk);
208 227
228 if (cpufreq.asyncclk)
229 clk_put(cpufreq.asyncclk);
230
209 return cpufreq_unregister_driver(&davinci_driver); 231 return cpufreq_unregister_driver(&davinci_driver);
210} 232}
211 233