Commit 8a7b1227e303d7e927214ee0f260041aef44bb58
Committed by
Rafael J. Wysocki
1 parent
ceff98e333
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
cpufreq: davinci: move cpufreq driver to drivers/cpufreq
This patch moves cpufreq driver of ARM based davinci platform to drivers/cpufreq. Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org> Acked-by: Sekhar Nori <nsekhar@ti.com> Acked-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Showing 4 changed files with 232 additions and 234 deletions Side-by-side Diff
arch/arm/mach-davinci/Makefile
arch/arm/mach-davinci/cpufreq.c
1 | -/* | |
2 | - * CPU frequency scaling for DaVinci | |
3 | - * | |
4 | - * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ | |
5 | - * | |
6 | - * Based on linux/arch/arm/plat-omap/cpu-omap.c. Original Copyright follows: | |
7 | - * | |
8 | - * Copyright (C) 2005 Nokia Corporation | |
9 | - * Written by Tony Lindgren <tony@atomide.com> | |
10 | - * | |
11 | - * Based on cpu-sa1110.c, Copyright (C) 2001 Russell King | |
12 | - * | |
13 | - * Copyright (C) 2007-2008 Texas Instruments, Inc. | |
14 | - * Updated to support OMAP3 | |
15 | - * Rajendra Nayak <rnayak@ti.com> | |
16 | - * | |
17 | - * This program is free software; you can redistribute it and/or modify | |
18 | - * it under the terms of the GNU General Public License version 2 as | |
19 | - * published by the Free Software Foundation. | |
20 | - */ | |
21 | -#include <linux/types.h> | |
22 | -#include <linux/cpufreq.h> | |
23 | -#include <linux/init.h> | |
24 | -#include <linux/err.h> | |
25 | -#include <linux/clk.h> | |
26 | -#include <linux/platform_device.h> | |
27 | -#include <linux/export.h> | |
28 | - | |
29 | -#include <mach/hardware.h> | |
30 | -#include <mach/cpufreq.h> | |
31 | -#include <mach/common.h> | |
32 | - | |
33 | -#include "clock.h" | |
34 | - | |
35 | -struct davinci_cpufreq { | |
36 | - struct device *dev; | |
37 | - struct clk *armclk; | |
38 | - struct clk *asyncclk; | |
39 | - unsigned long asyncrate; | |
40 | -}; | |
41 | -static struct davinci_cpufreq cpufreq; | |
42 | - | |
43 | -static int davinci_verify_speed(struct cpufreq_policy *policy) | |
44 | -{ | |
45 | - struct davinci_cpufreq_config *pdata = cpufreq.dev->platform_data; | |
46 | - struct cpufreq_frequency_table *freq_table = pdata->freq_table; | |
47 | - struct clk *armclk = cpufreq.armclk; | |
48 | - | |
49 | - if (freq_table) | |
50 | - return cpufreq_frequency_table_verify(policy, freq_table); | |
51 | - | |
52 | - if (policy->cpu) | |
53 | - return -EINVAL; | |
54 | - | |
55 | - cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, | |
56 | - policy->cpuinfo.max_freq); | |
57 | - | |
58 | - policy->min = clk_round_rate(armclk, policy->min * 1000) / 1000; | |
59 | - policy->max = clk_round_rate(armclk, policy->max * 1000) / 1000; | |
60 | - cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, | |
61 | - policy->cpuinfo.max_freq); | |
62 | - return 0; | |
63 | -} | |
64 | - | |
65 | -static unsigned int davinci_getspeed(unsigned int cpu) | |
66 | -{ | |
67 | - if (cpu) | |
68 | - return 0; | |
69 | - | |
70 | - return clk_get_rate(cpufreq.armclk) / 1000; | |
71 | -} | |
72 | - | |
73 | -static int davinci_target(struct cpufreq_policy *policy, | |
74 | - unsigned int target_freq, unsigned int relation) | |
75 | -{ | |
76 | - int ret = 0; | |
77 | - unsigned int idx; | |
78 | - struct cpufreq_freqs freqs; | |
79 | - struct davinci_cpufreq_config *pdata = cpufreq.dev->platform_data; | |
80 | - struct clk *armclk = cpufreq.armclk; | |
81 | - | |
82 | - freqs.old = davinci_getspeed(0); | |
83 | - freqs.new = clk_round_rate(armclk, target_freq * 1000) / 1000; | |
84 | - | |
85 | - if (freqs.old == freqs.new) | |
86 | - return ret; | |
87 | - | |
88 | - dev_dbg(cpufreq.dev, "transition: %u --> %u\n", freqs.old, freqs.new); | |
89 | - | |
90 | - ret = cpufreq_frequency_table_target(policy, pdata->freq_table, | |
91 | - freqs.new, relation, &idx); | |
92 | - if (ret) | |
93 | - return -EINVAL; | |
94 | - | |
95 | - cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); | |
96 | - | |
97 | - /* if moving to higher frequency, up the voltage beforehand */ | |
98 | - if (pdata->set_voltage && freqs.new > freqs.old) { | |
99 | - ret = pdata->set_voltage(idx); | |
100 | - if (ret) | |
101 | - goto out; | |
102 | - } | |
103 | - | |
104 | - ret = clk_set_rate(armclk, idx); | |
105 | - if (ret) | |
106 | - goto out; | |
107 | - | |
108 | - if (cpufreq.asyncclk) { | |
109 | - ret = clk_set_rate(cpufreq.asyncclk, cpufreq.asyncrate); | |
110 | - if (ret) | |
111 | - goto out; | |
112 | - } | |
113 | - | |
114 | - /* if moving to lower freq, lower the voltage after lowering freq */ | |
115 | - if (pdata->set_voltage && freqs.new < freqs.old) | |
116 | - pdata->set_voltage(idx); | |
117 | - | |
118 | -out: | |
119 | - cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); | |
120 | - | |
121 | - return ret; | |
122 | -} | |
123 | - | |
124 | -static int davinci_cpu_init(struct cpufreq_policy *policy) | |
125 | -{ | |
126 | - int result = 0; | |
127 | - struct davinci_cpufreq_config *pdata = cpufreq.dev->platform_data; | |
128 | - struct cpufreq_frequency_table *freq_table = pdata->freq_table; | |
129 | - | |
130 | - if (policy->cpu != 0) | |
131 | - return -EINVAL; | |
132 | - | |
133 | - /* Finish platform specific initialization */ | |
134 | - if (pdata->init) { | |
135 | - result = pdata->init(); | |
136 | - if (result) | |
137 | - return result; | |
138 | - } | |
139 | - | |
140 | - policy->cur = davinci_getspeed(0); | |
141 | - | |
142 | - result = cpufreq_frequency_table_cpuinfo(policy, freq_table); | |
143 | - if (result) { | |
144 | - pr_err("%s: cpufreq_frequency_table_cpuinfo() failed", | |
145 | - __func__); | |
146 | - return result; | |
147 | - } | |
148 | - | |
149 | - cpufreq_frequency_table_get_attr(freq_table, policy->cpu); | |
150 | - | |
151 | - /* | |
152 | - * Time measurement across the target() function yields ~1500-1800us | |
153 | - * time taken with no drivers on notification list. | |
154 | - * Setting the latency to 2000 us to accommodate addition of drivers | |
155 | - * to pre/post change notification list. | |
156 | - */ | |
157 | - policy->cpuinfo.transition_latency = 2000 * 1000; | |
158 | - return 0; | |
159 | -} | |
160 | - | |
161 | -static int davinci_cpu_exit(struct cpufreq_policy *policy) | |
162 | -{ | |
163 | - cpufreq_frequency_table_put_attr(policy->cpu); | |
164 | - return 0; | |
165 | -} | |
166 | - | |
167 | -static struct freq_attr *davinci_cpufreq_attr[] = { | |
168 | - &cpufreq_freq_attr_scaling_available_freqs, | |
169 | - NULL, | |
170 | -}; | |
171 | - | |
172 | -static struct cpufreq_driver davinci_driver = { | |
173 | - .flags = CPUFREQ_STICKY, | |
174 | - .verify = davinci_verify_speed, | |
175 | - .target = davinci_target, | |
176 | - .get = davinci_getspeed, | |
177 | - .init = davinci_cpu_init, | |
178 | - .exit = davinci_cpu_exit, | |
179 | - .name = "davinci", | |
180 | - .attr = davinci_cpufreq_attr, | |
181 | -}; | |
182 | - | |
183 | -static int __init davinci_cpufreq_probe(struct platform_device *pdev) | |
184 | -{ | |
185 | - struct davinci_cpufreq_config *pdata = pdev->dev.platform_data; | |
186 | - struct clk *asyncclk; | |
187 | - | |
188 | - if (!pdata) | |
189 | - return -EINVAL; | |
190 | - if (!pdata->freq_table) | |
191 | - return -EINVAL; | |
192 | - | |
193 | - cpufreq.dev = &pdev->dev; | |
194 | - | |
195 | - cpufreq.armclk = clk_get(NULL, "arm"); | |
196 | - if (IS_ERR(cpufreq.armclk)) { | |
197 | - dev_err(cpufreq.dev, "Unable to get ARM clock\n"); | |
198 | - return PTR_ERR(cpufreq.armclk); | |
199 | - } | |
200 | - | |
201 | - asyncclk = clk_get(cpufreq.dev, "async"); | |
202 | - if (!IS_ERR(asyncclk)) { | |
203 | - cpufreq.asyncclk = asyncclk; | |
204 | - cpufreq.asyncrate = clk_get_rate(asyncclk); | |
205 | - } | |
206 | - | |
207 | - return cpufreq_register_driver(&davinci_driver); | |
208 | -} | |
209 | - | |
210 | -static int __exit davinci_cpufreq_remove(struct platform_device *pdev) | |
211 | -{ | |
212 | - clk_put(cpufreq.armclk); | |
213 | - | |
214 | - if (cpufreq.asyncclk) | |
215 | - clk_put(cpufreq.asyncclk); | |
216 | - | |
217 | - return cpufreq_unregister_driver(&davinci_driver); | |
218 | -} | |
219 | - | |
220 | -static struct platform_driver davinci_cpufreq_driver = { | |
221 | - .driver = { | |
222 | - .name = "cpufreq-davinci", | |
223 | - .owner = THIS_MODULE, | |
224 | - }, | |
225 | - .remove = __exit_p(davinci_cpufreq_remove), | |
226 | -}; | |
227 | - | |
228 | -int __init davinci_cpufreq_init(void) | |
229 | -{ | |
230 | - return platform_driver_probe(&davinci_cpufreq_driver, | |
231 | - davinci_cpufreq_probe); | |
232 | -} |
drivers/cpufreq/Makefile
... | ... | @@ -49,6 +49,7 @@ |
49 | 49 | # LITTLE drivers, so that it is probed last. |
50 | 50 | obj-$(CONFIG_ARM_DT_BL_CPUFREQ) += arm_big_little_dt.o |
51 | 51 | |
52 | +obj-$(CONFIG_ARCH_DAVINCI_DA850) += davinci-cpufreq.o | |
52 | 53 | obj-$(CONFIG_UX500_SOC_DB8500) += dbx500-cpufreq.o |
53 | 54 | obj-$(CONFIG_ARM_EXYNOS_CPUFREQ) += exynos-cpufreq.o |
54 | 55 | obj-$(CONFIG_ARM_EXYNOS4210_CPUFREQ) += exynos4210-cpufreq.o |
drivers/cpufreq/davinci-cpufreq.c
1 | +/* | |
2 | + * CPU frequency scaling for DaVinci | |
3 | + * | |
4 | + * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ | |
5 | + * | |
6 | + * Based on linux/arch/arm/plat-omap/cpu-omap.c. Original Copyright follows: | |
7 | + * | |
8 | + * Copyright (C) 2005 Nokia Corporation | |
9 | + * Written by Tony Lindgren <tony@atomide.com> | |
10 | + * | |
11 | + * Based on cpu-sa1110.c, Copyright (C) 2001 Russell King | |
12 | + * | |
13 | + * Copyright (C) 2007-2008 Texas Instruments, Inc. | |
14 | + * Updated to support OMAP3 | |
15 | + * Rajendra Nayak <rnayak@ti.com> | |
16 | + * | |
17 | + * This program is free software; you can redistribute it and/or modify | |
18 | + * it under the terms of the GNU General Public License version 2 as | |
19 | + * published by the Free Software Foundation. | |
20 | + */ | |
21 | +#include <linux/types.h> | |
22 | +#include <linux/cpufreq.h> | |
23 | +#include <linux/init.h> | |
24 | +#include <linux/err.h> | |
25 | +#include <linux/clk.h> | |
26 | +#include <linux/platform_device.h> | |
27 | +#include <linux/export.h> | |
28 | + | |
29 | +#include <mach/hardware.h> | |
30 | +#include <mach/cpufreq.h> | |
31 | +#include <mach/common.h> | |
32 | + | |
33 | +struct davinci_cpufreq { | |
34 | + struct device *dev; | |
35 | + struct clk *armclk; | |
36 | + struct clk *asyncclk; | |
37 | + unsigned long asyncrate; | |
38 | +}; | |
39 | +static struct davinci_cpufreq cpufreq; | |
40 | + | |
41 | +static int davinci_verify_speed(struct cpufreq_policy *policy) | |
42 | +{ | |
43 | + struct davinci_cpufreq_config *pdata = cpufreq.dev->platform_data; | |
44 | + struct cpufreq_frequency_table *freq_table = pdata->freq_table; | |
45 | + struct clk *armclk = cpufreq.armclk; | |
46 | + | |
47 | + if (freq_table) | |
48 | + return cpufreq_frequency_table_verify(policy, freq_table); | |
49 | + | |
50 | + if (policy->cpu) | |
51 | + return -EINVAL; | |
52 | + | |
53 | + cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, | |
54 | + policy->cpuinfo.max_freq); | |
55 | + | |
56 | + policy->min = clk_round_rate(armclk, policy->min * 1000) / 1000; | |
57 | + policy->max = clk_round_rate(armclk, policy->max * 1000) / 1000; | |
58 | + cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, | |
59 | + policy->cpuinfo.max_freq); | |
60 | + return 0; | |
61 | +} | |
62 | + | |
63 | +static unsigned int davinci_getspeed(unsigned int cpu) | |
64 | +{ | |
65 | + if (cpu) | |
66 | + return 0; | |
67 | + | |
68 | + return clk_get_rate(cpufreq.armclk) / 1000; | |
69 | +} | |
70 | + | |
71 | +static int davinci_target(struct cpufreq_policy *policy, | |
72 | + unsigned int target_freq, unsigned int relation) | |
73 | +{ | |
74 | + int ret = 0; | |
75 | + unsigned int idx; | |
76 | + struct cpufreq_freqs freqs; | |
77 | + struct davinci_cpufreq_config *pdata = cpufreq.dev->platform_data; | |
78 | + struct clk *armclk = cpufreq.armclk; | |
79 | + | |
80 | + freqs.old = davinci_getspeed(0); | |
81 | + freqs.new = clk_round_rate(armclk, target_freq * 1000) / 1000; | |
82 | + | |
83 | + if (freqs.old == freqs.new) | |
84 | + return ret; | |
85 | + | |
86 | + dev_dbg(cpufreq.dev, "transition: %u --> %u\n", freqs.old, freqs.new); | |
87 | + | |
88 | + ret = cpufreq_frequency_table_target(policy, pdata->freq_table, | |
89 | + freqs.new, relation, &idx); | |
90 | + if (ret) | |
91 | + return -EINVAL; | |
92 | + | |
93 | + cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); | |
94 | + | |
95 | + /* if moving to higher frequency, up the voltage beforehand */ | |
96 | + if (pdata->set_voltage && freqs.new > freqs.old) { | |
97 | + ret = pdata->set_voltage(idx); | |
98 | + if (ret) | |
99 | + goto out; | |
100 | + } | |
101 | + | |
102 | + ret = clk_set_rate(armclk, idx); | |
103 | + if (ret) | |
104 | + goto out; | |
105 | + | |
106 | + if (cpufreq.asyncclk) { | |
107 | + ret = clk_set_rate(cpufreq.asyncclk, cpufreq.asyncrate); | |
108 | + if (ret) | |
109 | + goto out; | |
110 | + } | |
111 | + | |
112 | + /* if moving to lower freq, lower the voltage after lowering freq */ | |
113 | + if (pdata->set_voltage && freqs.new < freqs.old) | |
114 | + pdata->set_voltage(idx); | |
115 | + | |
116 | +out: | |
117 | + cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE); | |
118 | + | |
119 | + return ret; | |
120 | +} | |
121 | + | |
122 | +static int davinci_cpu_init(struct cpufreq_policy *policy) | |
123 | +{ | |
124 | + int result = 0; | |
125 | + struct davinci_cpufreq_config *pdata = cpufreq.dev->platform_data; | |
126 | + struct cpufreq_frequency_table *freq_table = pdata->freq_table; | |
127 | + | |
128 | + if (policy->cpu != 0) | |
129 | + return -EINVAL; | |
130 | + | |
131 | + /* Finish platform specific initialization */ | |
132 | + if (pdata->init) { | |
133 | + result = pdata->init(); | |
134 | + if (result) | |
135 | + return result; | |
136 | + } | |
137 | + | |
138 | + policy->cur = davinci_getspeed(0); | |
139 | + | |
140 | + result = cpufreq_frequency_table_cpuinfo(policy, freq_table); | |
141 | + if (result) { | |
142 | + pr_err("%s: cpufreq_frequency_table_cpuinfo() failed", | |
143 | + __func__); | |
144 | + return result; | |
145 | + } | |
146 | + | |
147 | + cpufreq_frequency_table_get_attr(freq_table, policy->cpu); | |
148 | + | |
149 | + /* | |
150 | + * Time measurement across the target() function yields ~1500-1800us | |
151 | + * time taken with no drivers on notification list. | |
152 | + * Setting the latency to 2000 us to accommodate addition of drivers | |
153 | + * to pre/post change notification list. | |
154 | + */ | |
155 | + policy->cpuinfo.transition_latency = 2000 * 1000; | |
156 | + return 0; | |
157 | +} | |
158 | + | |
159 | +static int davinci_cpu_exit(struct cpufreq_policy *policy) | |
160 | +{ | |
161 | + cpufreq_frequency_table_put_attr(policy->cpu); | |
162 | + return 0; | |
163 | +} | |
164 | + | |
165 | +static struct freq_attr *davinci_cpufreq_attr[] = { | |
166 | + &cpufreq_freq_attr_scaling_available_freqs, | |
167 | + NULL, | |
168 | +}; | |
169 | + | |
170 | +static struct cpufreq_driver davinci_driver = { | |
171 | + .flags = CPUFREQ_STICKY, | |
172 | + .verify = davinci_verify_speed, | |
173 | + .target = davinci_target, | |
174 | + .get = davinci_getspeed, | |
175 | + .init = davinci_cpu_init, | |
176 | + .exit = davinci_cpu_exit, | |
177 | + .name = "davinci", | |
178 | + .attr = davinci_cpufreq_attr, | |
179 | +}; | |
180 | + | |
181 | +static int __init davinci_cpufreq_probe(struct platform_device *pdev) | |
182 | +{ | |
183 | + struct davinci_cpufreq_config *pdata = pdev->dev.platform_data; | |
184 | + struct clk *asyncclk; | |
185 | + | |
186 | + if (!pdata) | |
187 | + return -EINVAL; | |
188 | + if (!pdata->freq_table) | |
189 | + return -EINVAL; | |
190 | + | |
191 | + cpufreq.dev = &pdev->dev; | |
192 | + | |
193 | + cpufreq.armclk = clk_get(NULL, "arm"); | |
194 | + if (IS_ERR(cpufreq.armclk)) { | |
195 | + dev_err(cpufreq.dev, "Unable to get ARM clock\n"); | |
196 | + return PTR_ERR(cpufreq.armclk); | |
197 | + } | |
198 | + | |
199 | + asyncclk = clk_get(cpufreq.dev, "async"); | |
200 | + if (!IS_ERR(asyncclk)) { | |
201 | + cpufreq.asyncclk = asyncclk; | |
202 | + cpufreq.asyncrate = clk_get_rate(asyncclk); | |
203 | + } | |
204 | + | |
205 | + return cpufreq_register_driver(&davinci_driver); | |
206 | +} | |
207 | + | |
208 | +static int __exit davinci_cpufreq_remove(struct platform_device *pdev) | |
209 | +{ | |
210 | + clk_put(cpufreq.armclk); | |
211 | + | |
212 | + if (cpufreq.asyncclk) | |
213 | + clk_put(cpufreq.asyncclk); | |
214 | + | |
215 | + return cpufreq_unregister_driver(&davinci_driver); | |
216 | +} | |
217 | + | |
218 | +static struct platform_driver davinci_cpufreq_driver = { | |
219 | + .driver = { | |
220 | + .name = "cpufreq-davinci", | |
221 | + .owner = THIS_MODULE, | |
222 | + }, | |
223 | + .remove = __exit_p(davinci_cpufreq_remove), | |
224 | +}; | |
225 | + | |
226 | +int __init davinci_cpufreq_init(void) | |
227 | +{ | |
228 | + return platform_driver_probe(&davinci_cpufreq_driver, | |
229 | + davinci_cpufreq_probe); | |
230 | +} |