]>
Commit | Line | Data |
---|---|---|
7c1a70e9 | 1 | /* |
7c1a70e9 | 2 | * Copyright (C) STMicroelectronics 2009 |
0baf066f | 3 | * Copyright (C) ST-Ericsson SA 2010-2012 |
7c1a70e9 MP |
4 | * |
5 | * License Terms: GNU General Public License v2 | |
7c1a70e9 MP |
6 | * Author: Sundar Iyer <sundar.iyer@stericsson.com> |
7 | * Author: Martin Persson <martin.persson@stericsson.com> | |
8 | * Author: Jonas Aaberg <jonas.aberg@stericsson.com> | |
7c1a70e9 | 9 | */ |
0baf066f | 10 | |
b4689444 | 11 | #include <linux/module.h> |
7c1a70e9 MP |
12 | #include <linux/kernel.h> |
13 | #include <linux/cpufreq.h> | |
19678ffb | 14 | #include <linux/cpu_cooling.h> |
7c1a70e9 | 15 | #include <linux/delay.h> |
72b2fd5c | 16 | #include <linux/slab.h> |
b4689444 | 17 | #include <linux/platform_device.h> |
78e30d12 | 18 | #include <linux/clk.h> |
7c1a70e9 | 19 | |
fdb44464 | 20 | static struct cpufreq_frequency_table *freq_table; |
78e30d12 | 21 | static struct clk *armss_clk; |
19678ffb | 22 | static struct thermal_cooling_device *cdev; |
72b2fd5c | 23 | |
edb10c11 | 24 | static int dbx500_cpufreq_target(struct cpufreq_policy *policy, |
9c0ebcf7 | 25 | unsigned int index) |
7c1a70e9 | 26 | { |
78e30d12 | 27 | /* update armss clk frequency */ |
d4019f0a | 28 | return clk_set_rate(armss_clk, freq_table[index].frequency * 1000); |
7c1a70e9 MP |
29 | } |
30 | ||
2760984f | 31 | static int dbx500_cpufreq_init(struct cpufreq_policy *policy) |
7c1a70e9 | 32 | { |
652ed95d | 33 | policy->clk = armss_clk; |
2b3dc761 | 34 | return cpufreq_generic_init(policy, freq_table, 20 * 1000); |
7c1a70e9 MP |
35 | } |
36 | ||
19678ffb VK |
37 | static int dbx500_cpufreq_exit(struct cpufreq_policy *policy) |
38 | { | |
39 | if (!IS_ERR(cdev)) | |
40 | cpufreq_cooling_unregister(cdev); | |
41 | return 0; | |
42 | } | |
43 | ||
44 | static void dbx500_cpufreq_ready(struct cpufreq_policy *policy) | |
45 | { | |
4d753aa7 | 46 | cdev = cpufreq_cooling_register(policy); |
19678ffb VK |
47 | if (IS_ERR(cdev)) |
48 | pr_err("Failed to register cooling device %ld\n", PTR_ERR(cdev)); | |
49 | else | |
50 | pr_info("Cooling device registered: %s\n", cdev->type); | |
51 | } | |
52 | ||
edb10c11 | 53 | static struct cpufreq_driver dbx500_cpufreq_driver = { |
ae6b4271 VK |
54 | .flags = CPUFREQ_STICKY | CPUFREQ_CONST_LOOPS | |
55 | CPUFREQ_NEED_INITIAL_FREQ_CHECK, | |
47150e98 | 56 | .verify = cpufreq_generic_frequency_table_verify, |
9c0ebcf7 | 57 | .target_index = dbx500_cpufreq_target, |
652ed95d | 58 | .get = cpufreq_generic_get, |
edb10c11 | 59 | .init = dbx500_cpufreq_init, |
19678ffb VK |
60 | .exit = dbx500_cpufreq_exit, |
61 | .ready = dbx500_cpufreq_ready, | |
edb10c11 | 62 | .name = "DBX500", |
47150e98 | 63 | .attr = cpufreq_generic_attr, |
7c1a70e9 MP |
64 | }; |
65 | ||
edb10c11 | 66 | static int dbx500_cpufreq_probe(struct platform_device *pdev) |
b4689444 | 67 | { |
041526f9 | 68 | struct cpufreq_frequency_table *pos; |
fdb44464 | 69 | |
3e27996c | 70 | freq_table = dev_get_platdata(&pdev->dev); |
fdb44464 | 71 | if (!freq_table) { |
edb10c11 | 72 | pr_err("dbx500-cpufreq: Failed to fetch cpufreq table\n"); |
fdb44464 UH |
73 | return -ENODEV; |
74 | } | |
75 | ||
3e27996c UH |
76 | armss_clk = clk_get(&pdev->dev, "armss"); |
77 | if (IS_ERR(armss_clk)) { | |
9291cf9d | 78 | pr_err("dbx500-cpufreq: Failed to get armss clk\n"); |
3e27996c UH |
79 | return PTR_ERR(armss_clk); |
80 | } | |
81 | ||
9291cf9d | 82 | pr_info("dbx500-cpufreq: Available frequencies:\n"); |
041526f9 SK |
83 | cpufreq_for_each_entry(pos, freq_table) |
84 | pr_info(" %d Mhz\n", pos->frequency / 1000); | |
3e27996c | 85 | |
edb10c11 | 86 | return cpufreq_register_driver(&dbx500_cpufreq_driver); |
b4689444 UH |
87 | } |
88 | ||
edb10c11 | 89 | static struct platform_driver dbx500_cpufreq_plat_driver = { |
b4689444 | 90 | .driver = { |
edb10c11 | 91 | .name = "cpufreq-ux500", |
b4689444 | 92 | }, |
edb10c11 | 93 | .probe = dbx500_cpufreq_probe, |
b4689444 UH |
94 | }; |
95 | ||
edb10c11 | 96 | static int __init dbx500_cpufreq_register(void) |
7c1a70e9 | 97 | { |
edb10c11 | 98 | return platform_driver_register(&dbx500_cpufreq_plat_driver); |
7c1a70e9 | 99 | } |
edb10c11 | 100 | device_initcall(dbx500_cpufreq_register); |
b4689444 UH |
101 | |
102 | MODULE_LICENSE("GPL v2"); | |
edb10c11 | 103 | MODULE_DESCRIPTION("cpufreq driver for DBX500"); |