.. | .. |
---|
1 | 1 | /* |
---|
2 | 2 | * System Control and Power Interface (SCPI) based CPUFreq Interface driver |
---|
3 | 3 | * |
---|
4 | | - * It provides necessary ops to arm_big_little cpufreq driver. |
---|
5 | | - * |
---|
6 | 4 | * Copyright (C) 2015 ARM Ltd. |
---|
7 | 5 | * Sudeep Holla <sudeep.holla@arm.com> |
---|
8 | 6 | * |
---|
.. | .. |
---|
22 | 20 | #include <linux/cpu.h> |
---|
23 | 21 | #include <linux/cpufreq.h> |
---|
24 | 22 | #include <linux/cpumask.h> |
---|
25 | | -#include <linux/cpu_cooling.h> |
---|
26 | | -#include <linux/energy_model.h> |
---|
27 | 23 | #include <linux/export.h> |
---|
28 | 24 | #include <linux/module.h> |
---|
29 | 25 | #include <linux/of_platform.h> |
---|
.. | .. |
---|
35 | 31 | struct scpi_data { |
---|
36 | 32 | struct clk *clk; |
---|
37 | 33 | struct device *cpu_dev; |
---|
38 | | - struct thermal_cooling_device *cdev; |
---|
39 | 34 | }; |
---|
40 | 35 | |
---|
41 | 36 | static struct scpi_ops *scpi_ops; |
---|
.. | .. |
---|
52 | 47 | static int |
---|
53 | 48 | scpi_cpufreq_set_target(struct cpufreq_policy *policy, unsigned int index) |
---|
54 | 49 | { |
---|
55 | | - unsigned long freq = policy->freq_table[index].frequency; |
---|
| 50 | + u64 rate = policy->freq_table[index].frequency * 1000; |
---|
56 | 51 | struct scpi_data *priv = policy->driver_data; |
---|
57 | | - u64 rate = freq * 1000; |
---|
58 | 52 | int ret; |
---|
59 | 53 | |
---|
60 | 54 | ret = clk_set_rate(priv->clk, rate); |
---|
.. | .. |
---|
64 | 58 | |
---|
65 | 59 | if (clk_get_rate(priv->clk) != rate) |
---|
66 | 60 | return -EIO; |
---|
67 | | - |
---|
68 | | - arch_set_freq_scale(policy->related_cpus, freq, |
---|
69 | | - policy->cpuinfo.max_freq); |
---|
70 | 61 | |
---|
71 | 62 | return 0; |
---|
72 | 63 | } |
---|
.. | .. |
---|
99 | 90 | |
---|
100 | 91 | static int scpi_cpufreq_init(struct cpufreq_policy *policy) |
---|
101 | 92 | { |
---|
102 | | - int ret, nr_opp; |
---|
| 93 | + int ret; |
---|
103 | 94 | unsigned int latency; |
---|
104 | 95 | struct device *cpu_dev; |
---|
105 | 96 | struct scpi_data *priv; |
---|
106 | 97 | struct cpufreq_frequency_table *freq_table; |
---|
107 | | - struct em_data_callback em_cb = EM_DATA_CB(of_dev_pm_opp_get_cpu_power); |
---|
108 | 98 | |
---|
109 | 99 | cpu_dev = get_cpu_device(policy->cpu); |
---|
110 | 100 | if (!cpu_dev) { |
---|
.. | .. |
---|
137 | 127 | ret = -EPROBE_DEFER; |
---|
138 | 128 | goto out_free_opp; |
---|
139 | 129 | } |
---|
140 | | - nr_opp = ret; |
---|
141 | 130 | |
---|
142 | 131 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); |
---|
143 | 132 | if (!priv) { |
---|
.. | .. |
---|
174 | 163 | |
---|
175 | 164 | policy->fast_switch_possible = false; |
---|
176 | 165 | |
---|
177 | | - em_register_perf_domain(policy->cpus, nr_opp, &em_cb); |
---|
| 166 | + dev_pm_opp_of_register_em(cpu_dev, policy->cpus); |
---|
178 | 167 | |
---|
179 | 168 | return 0; |
---|
180 | 169 | |
---|
.. | .. |
---|
183 | 172 | out_free_priv: |
---|
184 | 173 | kfree(priv); |
---|
185 | 174 | out_free_opp: |
---|
186 | | - dev_pm_opp_cpumask_remove_table(policy->cpus); |
---|
| 175 | + dev_pm_opp_remove_all_dynamic(cpu_dev); |
---|
187 | 176 | |
---|
188 | 177 | return ret; |
---|
189 | 178 | } |
---|
.. | .. |
---|
192 | 181 | { |
---|
193 | 182 | struct scpi_data *priv = policy->driver_data; |
---|
194 | 183 | |
---|
195 | | - cpufreq_cooling_unregister(priv->cdev); |
---|
196 | 184 | clk_put(priv->clk); |
---|
197 | 185 | dev_pm_opp_free_cpufreq_table(priv->cpu_dev, &policy->freq_table); |
---|
| 186 | + dev_pm_opp_remove_all_dynamic(priv->cpu_dev); |
---|
198 | 187 | kfree(priv); |
---|
199 | | - dev_pm_opp_cpumask_remove_table(policy->related_cpus); |
---|
200 | 188 | |
---|
201 | 189 | return 0; |
---|
202 | | -} |
---|
203 | | - |
---|
204 | | -static void scpi_cpufreq_ready(struct cpufreq_policy *policy) |
---|
205 | | -{ |
---|
206 | | - struct scpi_data *priv = policy->driver_data; |
---|
207 | | - |
---|
208 | | - priv->cdev = of_cpufreq_cooling_register(policy); |
---|
209 | 190 | } |
---|
210 | 191 | |
---|
211 | 192 | static struct cpufreq_driver scpi_cpufreq_driver = { |
---|
212 | 193 | .name = "scpi-cpufreq", |
---|
213 | 194 | .flags = CPUFREQ_STICKY | CPUFREQ_HAVE_GOVERNOR_PER_POLICY | |
---|
214 | | - CPUFREQ_NEED_INITIAL_FREQ_CHECK, |
---|
| 195 | + CPUFREQ_NEED_INITIAL_FREQ_CHECK | |
---|
| 196 | + CPUFREQ_IS_COOLING_DEV, |
---|
215 | 197 | .verify = cpufreq_generic_frequency_table_verify, |
---|
216 | 198 | .attr = cpufreq_generic_attr, |
---|
217 | 199 | .get = scpi_cpufreq_get_rate, |
---|
218 | 200 | .init = scpi_cpufreq_init, |
---|
219 | 201 | .exit = scpi_cpufreq_exit, |
---|
220 | | - .ready = scpi_cpufreq_ready, |
---|
221 | 202 | .target_index = scpi_cpufreq_set_target, |
---|
222 | 203 | }; |
---|
223 | 204 | |
---|