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 | ||
