diff options
Diffstat (limited to 'drivers/cpufreq/exynos5440-cpufreq.c')
-rw-r--r-- | drivers/cpufreq/exynos5440-cpufreq.c | 67 |
1 files changed, 20 insertions, 47 deletions
diff --git a/drivers/cpufreq/exynos5440-cpufreq.c b/drivers/cpufreq/exynos5440-cpufreq.c index be5380ecdcd4..76bef8b078cb 100644 --- a/drivers/cpufreq/exynos5440-cpufreq.c +++ b/drivers/cpufreq/exynos5440-cpufreq.c | |||
@@ -20,7 +20,7 @@ | |||
20 | #include <linux/module.h> | 20 | #include <linux/module.h> |
21 | #include <linux/of_address.h> | 21 | #include <linux/of_address.h> |
22 | #include <linux/of_irq.h> | 22 | #include <linux/of_irq.h> |
23 | #include <linux/opp.h> | 23 | #include <linux/pm_opp.h> |
24 | #include <linux/platform_device.h> | 24 | #include <linux/platform_device.h> |
25 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
26 | 26 | ||
@@ -118,12 +118,12 @@ static int init_div_table(void) | |||
118 | struct cpufreq_frequency_table *freq_tbl = dvfs_info->freq_table; | 118 | struct cpufreq_frequency_table *freq_tbl = dvfs_info->freq_table; |
119 | unsigned int tmp, clk_div, ema_div, freq, volt_id; | 119 | unsigned int tmp, clk_div, ema_div, freq, volt_id; |
120 | int i = 0; | 120 | int i = 0; |
121 | struct opp *opp; | 121 | struct dev_pm_opp *opp; |
122 | 122 | ||
123 | rcu_read_lock(); | 123 | rcu_read_lock(); |
124 | for (i = 0; freq_tbl[i].frequency != CPUFREQ_TABLE_END; i++) { | 124 | for (i = 0; freq_tbl[i].frequency != CPUFREQ_TABLE_END; i++) { |
125 | 125 | ||
126 | opp = opp_find_freq_exact(dvfs_info->dev, | 126 | opp = dev_pm_opp_find_freq_exact(dvfs_info->dev, |
127 | freq_tbl[i].frequency * 1000, true); | 127 | freq_tbl[i].frequency * 1000, true); |
128 | if (IS_ERR(opp)) { | 128 | if (IS_ERR(opp)) { |
129 | rcu_read_unlock(); | 129 | rcu_read_unlock(); |
@@ -142,7 +142,7 @@ static int init_div_table(void) | |||
142 | << P0_7_CSCLKDEV_SHIFT; | 142 | << P0_7_CSCLKDEV_SHIFT; |
143 | 143 | ||
144 | /* Calculate EMA */ | 144 | /* Calculate EMA */ |
145 | volt_id = opp_get_voltage(opp); | 145 | volt_id = dev_pm_opp_get_voltage(opp); |
146 | volt_id = (MAX_VOLTAGE - volt_id) / VOLTAGE_STEP; | 146 | volt_id = (MAX_VOLTAGE - volt_id) / VOLTAGE_STEP; |
147 | if (volt_id < PMIC_HIGH_VOLT) { | 147 | if (volt_id < PMIC_HIGH_VOLT) { |
148 | ema_div = (CPUEMA_HIGH << P0_7_CPUEMA_SHIFT) | | 148 | ema_div = (CPUEMA_HIGH << P0_7_CPUEMA_SHIFT) | |
@@ -209,38 +209,22 @@ static void exynos_enable_dvfs(void) | |||
209 | dvfs_info->base + XMU_DVFS_CTRL); | 209 | dvfs_info->base + XMU_DVFS_CTRL); |
210 | } | 210 | } |
211 | 211 | ||
212 | static int exynos_verify_speed(struct cpufreq_policy *policy) | ||
213 | { | ||
214 | return cpufreq_frequency_table_verify(policy, | ||
215 | dvfs_info->freq_table); | ||
216 | } | ||
217 | |||
218 | static unsigned int exynos_getspeed(unsigned int cpu) | 212 | static unsigned int exynos_getspeed(unsigned int cpu) |
219 | { | 213 | { |
220 | return dvfs_info->cur_frequency; | 214 | return dvfs_info->cur_frequency; |
221 | } | 215 | } |
222 | 216 | ||
223 | static int exynos_target(struct cpufreq_policy *policy, | 217 | static int exynos_target(struct cpufreq_policy *policy, unsigned int index) |
224 | unsigned int target_freq, | ||
225 | unsigned int relation) | ||
226 | { | 218 | { |
227 | unsigned int index, tmp; | 219 | unsigned int tmp; |
228 | int ret = 0, i; | 220 | int i; |
229 | struct cpufreq_frequency_table *freq_table = dvfs_info->freq_table; | 221 | struct cpufreq_frequency_table *freq_table = dvfs_info->freq_table; |
230 | 222 | ||
231 | mutex_lock(&cpufreq_lock); | 223 | mutex_lock(&cpufreq_lock); |
232 | 224 | ||
233 | ret = cpufreq_frequency_table_target(policy, freq_table, | ||
234 | target_freq, relation, &index); | ||
235 | if (ret) | ||
236 | goto out; | ||
237 | |||
238 | freqs.old = dvfs_info->cur_frequency; | 225 | freqs.old = dvfs_info->cur_frequency; |
239 | freqs.new = freq_table[index].frequency; | 226 | freqs.new = freq_table[index].frequency; |
240 | 227 | ||
241 | if (freqs.old == freqs.new) | ||
242 | goto out; | ||
243 | |||
244 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); | 228 | cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); |
245 | 229 | ||
246 | /* Set the target frequency in all C0_3_PSTATE register */ | 230 | /* Set the target frequency in all C0_3_PSTATE register */ |
@@ -251,9 +235,8 @@ static int exynos_target(struct cpufreq_policy *policy, | |||
251 | 235 | ||
252 | __raw_writel(tmp, dvfs_info->base + XMU_C0_3_PSTATE + i * 4); | 236 | __raw_writel(tmp, dvfs_info->base + XMU_C0_3_PSTATE + i * 4); |
253 | } | 237 | } |
254 | out: | ||
255 | mutex_unlock(&cpufreq_lock); | 238 | mutex_unlock(&cpufreq_lock); |
256 | return ret; | 239 | return 0; |
257 | } | 240 | } |
258 | 241 | ||
259 | static void exynos_cpufreq_work(struct work_struct *work) | 242 | static void exynos_cpufreq_work(struct work_struct *work) |
@@ -324,30 +307,19 @@ static void exynos_sort_descend_freq_table(void) | |||
324 | 307 | ||
325 | static int exynos_cpufreq_cpu_init(struct cpufreq_policy *policy) | 308 | static int exynos_cpufreq_cpu_init(struct cpufreq_policy *policy) |
326 | { | 309 | { |
327 | int ret; | 310 | return cpufreq_generic_init(policy, dvfs_info->freq_table, |
328 | 311 | dvfs_info->latency); | |
329 | ret = cpufreq_frequency_table_cpuinfo(policy, dvfs_info->freq_table); | ||
330 | if (ret) { | ||
331 | dev_err(dvfs_info->dev, "Invalid frequency table: %d\n", ret); | ||
332 | return ret; | ||
333 | } | ||
334 | |||
335 | policy->cur = dvfs_info->cur_frequency; | ||
336 | policy->cpuinfo.transition_latency = dvfs_info->latency; | ||
337 | cpumask_setall(policy->cpus); | ||
338 | |||
339 | cpufreq_frequency_table_get_attr(dvfs_info->freq_table, policy->cpu); | ||
340 | |||
341 | return 0; | ||
342 | } | 312 | } |
343 | 313 | ||
344 | static struct cpufreq_driver exynos_driver = { | 314 | static struct cpufreq_driver exynos_driver = { |
345 | .flags = CPUFREQ_STICKY, | 315 | .flags = CPUFREQ_STICKY | CPUFREQ_ASYNC_NOTIFICATION, |
346 | .verify = exynos_verify_speed, | 316 | .verify = cpufreq_generic_frequency_table_verify, |
347 | .target = exynos_target, | 317 | .target_index = exynos_target, |
348 | .get = exynos_getspeed, | 318 | .get = exynos_getspeed, |
349 | .init = exynos_cpufreq_cpu_init, | 319 | .init = exynos_cpufreq_cpu_init, |
320 | .exit = cpufreq_generic_exit, | ||
350 | .name = CPUFREQ_NAME, | 321 | .name = CPUFREQ_NAME, |
322 | .attr = cpufreq_generic_attr, | ||
351 | }; | 323 | }; |
352 | 324 | ||
353 | static const struct of_device_id exynos_cpufreq_match[] = { | 325 | static const struct of_device_id exynos_cpufreq_match[] = { |
@@ -399,13 +371,14 @@ static int exynos_cpufreq_probe(struct platform_device *pdev) | |||
399 | goto err_put_node; | 371 | goto err_put_node; |
400 | } | 372 | } |
401 | 373 | ||
402 | ret = opp_init_cpufreq_table(dvfs_info->dev, &dvfs_info->freq_table); | 374 | ret = dev_pm_opp_init_cpufreq_table(dvfs_info->dev, |
375 | &dvfs_info->freq_table); | ||
403 | if (ret) { | 376 | if (ret) { |
404 | dev_err(dvfs_info->dev, | 377 | dev_err(dvfs_info->dev, |
405 | "failed to init cpufreq table: %d\n", ret); | 378 | "failed to init cpufreq table: %d\n", ret); |
406 | goto err_put_node; | 379 | goto err_put_node; |
407 | } | 380 | } |
408 | dvfs_info->freq_count = opp_get_opp_count(dvfs_info->dev); | 381 | dvfs_info->freq_count = dev_pm_opp_get_opp_count(dvfs_info->dev); |
409 | exynos_sort_descend_freq_table(); | 382 | exynos_sort_descend_freq_table(); |
410 | 383 | ||
411 | if (of_property_read_u32(np, "clock-latency", &dvfs_info->latency)) | 384 | if (of_property_read_u32(np, "clock-latency", &dvfs_info->latency)) |
@@ -454,7 +427,7 @@ static int exynos_cpufreq_probe(struct platform_device *pdev) | |||
454 | return 0; | 427 | return 0; |
455 | 428 | ||
456 | err_free_table: | 429 | err_free_table: |
457 | opp_free_cpufreq_table(dvfs_info->dev, &dvfs_info->freq_table); | 430 | dev_pm_opp_free_cpufreq_table(dvfs_info->dev, &dvfs_info->freq_table); |
458 | err_put_node: | 431 | err_put_node: |
459 | of_node_put(np); | 432 | of_node_put(np); |
460 | dev_err(&pdev->dev, "%s: failed initialization\n", __func__); | 433 | dev_err(&pdev->dev, "%s: failed initialization\n", __func__); |
@@ -464,7 +437,7 @@ err_put_node: | |||
464 | static int exynos_cpufreq_remove(struct platform_device *pdev) | 437 | static int exynos_cpufreq_remove(struct platform_device *pdev) |
465 | { | 438 | { |
466 | cpufreq_unregister_driver(&exynos_driver); | 439 | cpufreq_unregister_driver(&exynos_driver); |
467 | opp_free_cpufreq_table(dvfs_info->dev, &dvfs_info->freq_table); | 440 | dev_pm_opp_free_cpufreq_table(dvfs_info->dev, &dvfs_info->freq_table); |
468 | return 0; | 441 | return 0; |
469 | } | 442 | } |
470 | 443 | ||