aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/cpufreq/exynos5440-cpufreq.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-11-13 23:41:48 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2013-11-13 23:41:48 -0500
commitf9300eaaac1ca300083ad41937923a90cc3a2394 (patch)
tree724b72ad729a8b85c09d2d54f8ca7d8ba22d774f /drivers/cpufreq/exynos5440-cpufreq.c
parent7f2dc5c4bcbff035b0d03f7aa78a182664b21e47 (diff)
parentfaddf2f5d278f1656e9444961bdd8d9db4deb5bf (diff)
Merge tag 'pm+acpi-3.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull ACPI and power management updates from Rafael J Wysocki: - New power capping framework and the the Intel Running Average Power Limit (RAPL) driver using it from Srinivas Pandruvada and Jacob Pan. - Addition of the in-kernel switching feature to the arm_big_little cpufreq driver from Viresh Kumar and Nicolas Pitre. - cpufreq support for iMac G5 from Aaro Koskinen. - Baytrail processors support for intel_pstate from Dirk Brandewie. - cpufreq support for Midway/ECX-2000 from Mark Langsdorf. - ARM vexpress/TC2 cpufreq support from Sudeep KarkadaNagesha. - ACPI power management support for the I2C and SPI bus types from Mika Westerberg and Lv Zheng. - cpufreq core fixes and cleanups from Viresh Kumar, Srivatsa S Bhat, Stratos Karafotis, Xiaoguang Chen, Lan Tianyu. - cpufreq drivers updates (mostly fixes and cleanups) from Viresh Kumar, Aaro Koskinen, Jungseok Lee, Sudeep KarkadaNagesha, Lukasz Majewski, Manish Badarkhe, Hans-Christian Egtvedt, Evgeny Kapaev. - intel_pstate updates from Dirk Brandewie and Adrian Huang. - ACPICA update to version 20130927 includig fixes and cleanups and some reduction of divergences between the ACPICA code in the kernel and ACPICA upstream in order to improve the automatic ACPICA patch generation process. From Bob Moore, Lv Zheng, Tomasz Nowicki, Naresh Bhat, Bjorn Helgaas, David E Box. - ACPI IPMI driver fixes and cleanups from Lv Zheng. - ACPI hotplug fixes and cleanups from Bjorn Helgaas, Toshi Kani, Zhang Yanfei, Rafael J Wysocki. - Conversion of the ACPI AC driver to the platform bus type and multiple driver fixes and cleanups related to ACPI from Zhang Rui. - ACPI processor driver fixes and cleanups from Hanjun Guo, Jiang Liu, Bartlomiej Zolnierkiewicz, Mathieu Rhéaume, Rafael J Wysocki. - Fixes and cleanups and new blacklist entries related to the ACPI video support from Aaron Lu, Felipe Contreras, Lennart Poettering, Kirill Tkhai. - cpuidle core cleanups from Viresh Kumar and Lorenzo Pieralisi. - cpuidle drivers fixes and cleanups from Daniel Lezcano, Jingoo Han, Bartlomiej Zolnierkiewicz, Prarit Bhargava. - devfreq updates from Sachin Kamat, Dan Carpenter, Manish Badarkhe. - Operation Performance Points (OPP) core updates from Nishanth Menon. - Runtime power management core fix from Rafael J Wysocki and update from Ulf Hansson. - Hibernation fixes from Aaron Lu and Rafael J Wysocki. - Device suspend/resume lockup detection mechanism from Benoit Goby. - Removal of unused proc directories created for various ACPI drivers from Lan Tianyu. - ACPI LPSS driver fix and new device IDs for the ACPI platform scan handler from Heikki Krogerus and Jarkko Nikula. - New ACPI _OSI blacklist entry for Toshiba NB100 from Levente Kurusa. - Assorted fixes and cleanups related to ACPI from Andy Shevchenko, Al Stone, Bartlomiej Zolnierkiewicz, Colin Ian King, Dan Carpenter, Felipe Contreras, Jianguo Wu, Lan Tianyu, Yinghai Lu, Mathias Krause, Liu Chuansheng. - Assorted PM fixes and cleanups from Andy Shevchenko, Thierry Reding, Jean-Christophe Plagniol-Villard. * tag 'pm+acpi-3.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (386 commits) cpufreq: conservative: fix requested_freq reduction issue ACPI / hotplug: Consolidate deferred execution of ACPI hotplug routines PM / runtime: Use pm_runtime_put_sync() in __device_release_driver() ACPI / event: remove unneeded NULL pointer check Revert "ACPI / video: Ignore BIOS initial backlight value for HP 250 G1" ACPI / video: Quirk initial backlight level 0 ACPI / video: Fix initial level validity test intel_pstate: skip the driver if ACPI has power mgmt option PM / hibernate: Avoid overflow in hibernate_preallocate_memory() ACPI / hotplug: Do not execute "insert in progress" _OST ACPI / hotplug: Carry out PCI root eject directly ACPI / hotplug: Merge device hot-removal routines ACPI / hotplug: Make acpi_bus_hot_remove_device() internal ACPI / hotplug: Simplify device ejection routines ACPI / hotplug: Fix handle_root_bridge_removal() ACPI / hotplug: Refuse to hot-remove all objects with disabled hotplug ACPI / scan: Start matching drivers after trying scan handlers ACPI: Remove acpi_pci_slot_init() headers from internal.h ACPI / blacklist: fix name of ThinkPad Edge E530 PowerCap: Fix build error with option -Werror=format-security ... Conflicts: arch/arm/mach-omap2/opp.c drivers/Kconfig drivers/spi/spi.c
Diffstat (limited to 'drivers/cpufreq/exynos5440-cpufreq.c')
-rw-r--r--drivers/cpufreq/exynos5440-cpufreq.c67
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
212static int exynos_verify_speed(struct cpufreq_policy *policy)
213{
214 return cpufreq_frequency_table_verify(policy,
215 dvfs_info->freq_table);
216}
217
218static unsigned int exynos_getspeed(unsigned int cpu) 212static 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
223static int exynos_target(struct cpufreq_policy *policy, 217static 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 }
254out:
255 mutex_unlock(&cpufreq_lock); 238 mutex_unlock(&cpufreq_lock);
256 return ret; 239 return 0;
257} 240}
258 241
259static void exynos_cpufreq_work(struct work_struct *work) 242static void exynos_cpufreq_work(struct work_struct *work)
@@ -324,30 +307,19 @@ static void exynos_sort_descend_freq_table(void)
324 307
325static int exynos_cpufreq_cpu_init(struct cpufreq_policy *policy) 308static 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
344static struct cpufreq_driver exynos_driver = { 314static 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
353static const struct of_device_id exynos_cpufreq_match[] = { 325static 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
456err_free_table: 429err_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);
458err_put_node: 431err_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:
464static int exynos_cpufreq_remove(struct platform_device *pdev) 437static 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