aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Walleij <linus.walleij@linaro.org>2013-06-17 16:52:32 -0400
committerLinus Walleij <linus.walleij@linaro.org>2013-10-16 08:10:03 -0400
commitbdac7eacc43d2e4f2e2b9d5e70050138f5d07d62 (patch)
treea3648bbe35ac04b1bc57bfb2701375c25d2467c9
parentbb4dbefe4c6ae3685152d03e318e093d5f6f795a (diff)
cpufreq: probe the Integrator cpufreq driver from DT
This makes the Integrator cpufreq driver probe from the core module device tree node through it's registered platforms device, getting the memory base from the device tree, remapping it and removing dependencies to <mach/platform.h> and <mach/hardware.h> by moving the two affected CM register offsets into the driver. Acked-by: Viresh Kumar <viresh.kumar@linaro.org> Acked-by: Rafael J. Wysocki <rjw@sisk.pl> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-rw-r--r--drivers/cpufreq/integrator-cpufreq.c61
1 files changed, 43 insertions, 18 deletions
diff --git a/drivers/cpufreq/integrator-cpufreq.c b/drivers/cpufreq/integrator-cpufreq.c
index f7c99df0880b..3d79bca47433 100644
--- a/drivers/cpufreq/integrator-cpufreq.c
+++ b/drivers/cpufreq/integrator-cpufreq.c
@@ -15,18 +15,19 @@
15#include <linux/smp.h> 15#include <linux/smp.h>
16#include <linux/init.h> 16#include <linux/init.h>
17#include <linux/io.h> 17#include <linux/io.h>
18#include <linux/platform_device.h>
19#include <linux/of.h>
20#include <linux/of_address.h>
18 21
19#include <mach/hardware.h>
20#include <mach/platform.h>
21#include <asm/mach-types.h> 22#include <asm/mach-types.h>
22#include <asm/hardware/icst.h> 23#include <asm/hardware/icst.h>
23 24
24static struct cpufreq_driver integrator_driver; 25static void __iomem *cm_base;
26/* The cpufreq driver only use the OSC register */
27#define INTEGRATOR_HDR_OSC_OFFSET 0x08
28#define INTEGRATOR_HDR_LOCK_OFFSET 0x14
25 29
26#define CM_ID __io_address(INTEGRATOR_HDR_ID) 30static struct cpufreq_driver integrator_driver;
27#define CM_OSC __io_address(INTEGRATOR_HDR_OSC)
28#define CM_STAT __io_address(INTEGRATOR_HDR_STAT)
29#define CM_LOCK __io_address(INTEGRATOR_HDR_LOCK)
30 31
31static const struct icst_params lclk_params = { 32static const struct icst_params lclk_params = {
32 .ref = 24000000, 33 .ref = 24000000,
@@ -100,7 +101,7 @@ static int integrator_set_target(struct cpufreq_policy *policy,
100 BUG_ON(cpu != smp_processor_id()); 101 BUG_ON(cpu != smp_processor_id());
101 102
102 /* get current setting */ 103 /* get current setting */
103 cm_osc = __raw_readl(CM_OSC); 104 cm_osc = __raw_readl(cm_base + INTEGRATOR_HDR_OSC_OFFSET);
104 105
105 if (machine_is_integrator()) { 106 if (machine_is_integrator()) {
106 vco.s = (cm_osc >> 8) & 7; 107 vco.s = (cm_osc >> 8) & 7;
@@ -128,7 +129,7 @@ static int integrator_set_target(struct cpufreq_policy *policy,
128 129
129 cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE); 130 cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
130 131
131 cm_osc = __raw_readl(CM_OSC); 132 cm_osc = __raw_readl(cm_base + INTEGRATOR_HDR_OSC_OFFSET);
132 133
133 if (machine_is_integrator()) { 134 if (machine_is_integrator()) {
134 cm_osc &= 0xfffff800; 135 cm_osc &= 0xfffff800;
@@ -138,9 +139,9 @@ static int integrator_set_target(struct cpufreq_policy *policy,
138 } 139 }
139 cm_osc |= vco.v; 140 cm_osc |= vco.v;
140 141
141 __raw_writel(0xa05f, CM_LOCK); 142 __raw_writel(0xa05f, cm_base + INTEGRATOR_HDR_LOCK_OFFSET);
142 __raw_writel(cm_osc, CM_OSC); 143 __raw_writel(cm_osc, cm_base + INTEGRATOR_HDR_OSC_OFFSET);
143 __raw_writel(0, CM_LOCK); 144 __raw_writel(0, cm_base + INTEGRATOR_HDR_LOCK_OFFSET);
144 145
145 /* 146 /*
146 * Restore the CPUs allowed mask. 147 * Restore the CPUs allowed mask.
@@ -165,7 +166,7 @@ static unsigned int integrator_get(unsigned int cpu)
165 BUG_ON(cpu != smp_processor_id()); 166 BUG_ON(cpu != smp_processor_id());
166 167
167 /* detect memory etc. */ 168 /* detect memory etc. */
168 cm_osc = __raw_readl(CM_OSC); 169 cm_osc = __raw_readl(cm_base + INTEGRATOR_HDR_OSC_OFFSET);
169 170
170 if (machine_is_integrator()) { 171 if (machine_is_integrator()) {
171 vco.s = (cm_osc >> 8) & 7; 172 vco.s = (cm_osc >> 8) & 7;
@@ -202,19 +203,43 @@ static struct cpufreq_driver integrator_driver = {
202 .name = "integrator", 203 .name = "integrator",
203}; 204};
204 205
205static int __init integrator_cpu_init(void) 206static int __init integrator_cpufreq_probe(struct platform_device *pdev)
206{ 207{
208 struct resource *res;
209
210 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
211 if (!res)
212 return -ENODEV;
213
214 cm_base = devm_ioremap(&pdev->dev, res->start, resource_size(res));
215 if (!cm_base)
216 return -ENODEV;
217
207 return cpufreq_register_driver(&integrator_driver); 218 return cpufreq_register_driver(&integrator_driver);
208} 219}
209 220
210static void __exit integrator_cpu_exit(void) 221static void __exit integrator_cpufreq_remove(struct platform_device *pdev)
211{ 222{
212 cpufreq_unregister_driver(&integrator_driver); 223 cpufreq_unregister_driver(&integrator_driver);
213} 224}
214 225
226static const struct of_device_id integrator_cpufreq_match[] = {
227 { .compatible = "arm,core-module-integrator"},
228 { },
229};
230
231static struct platform_driver integrator_cpufreq_driver = {
232 .driver = {
233 .name = "integrator-cpufreq",
234 .owner = THIS_MODULE,
235 .of_match_table = integrator_cpufreq_match,
236 },
237 .remove = __exit_p(integrator_cpufreq_remove),
238};
239
240module_platform_driver_probe(integrator_cpufreq_driver,
241 integrator_cpufreq_probe);
242
215MODULE_AUTHOR ("Russell M. King"); 243MODULE_AUTHOR ("Russell M. King");
216MODULE_DESCRIPTION ("cpufreq driver for ARM Integrator CPUs"); 244MODULE_DESCRIPTION ("cpufreq driver for ARM Integrator CPUs");
217MODULE_LICENSE ("GPL"); 245MODULE_LICENSE ("GPL");
218
219module_init(integrator_cpu_init);
220module_exit(integrator_cpu_exit);