summaryrefslogtreecommitdiffstats
path: root/recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0007-OMAP-cpufreq-Split-OMAP1-and-OMAP2PLUS-CPUfreq-drive.patch
diff options
context:
space:
mode:
Diffstat (limited to 'recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0007-OMAP-cpufreq-Split-OMAP1-and-OMAP2PLUS-CPUfreq-drive.patch')
-rw-r--r--recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0007-OMAP-cpufreq-Split-OMAP1-and-OMAP2PLUS-CPUfreq-drive.patch673
1 files changed, 0 insertions, 673 deletions
diff --git a/recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0007-OMAP-cpufreq-Split-OMAP1-and-OMAP2PLUS-CPUfreq-drive.patch b/recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0007-OMAP-cpufreq-Split-OMAP1-and-OMAP2PLUS-CPUfreq-drive.patch
deleted file mode 100644
index 25a9de92..00000000
--- a/recipes-kernel/linux/linux-3.0/pm-wip/cpufreq/0007-OMAP-cpufreq-Split-OMAP1-and-OMAP2PLUS-CPUfreq-drive.patch
+++ /dev/null
@@ -1,673 +0,0 @@
1From 972aa97a8a36946ebe2274e27c317e524de2cd5c Mon Sep 17 00:00:00 2001
2From: Santosh Shilimkar <santosh.shilimkar@ti.com>
3Date: Mon, 14 Mar 2011 17:08:48 +0530
4Subject: [PATCH 07/19] OMAP: cpufreq: Split OMAP1 and OMAP2PLUS CPUfreq drivers.
5
6This patch is an attempt to cleanup the #ifdeferry in the
7omap CPUfreq drivers.
8
9The split betwenn OMAP1 and OMAP2PLUS is logical because
10 - OMAP1 doesn't support opp layer.
11 - OMAP1 build is seperate from omap2plus.
12
13Includes minor header/copyright updates reported by Todd Poynor.
14
15Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
16Cc: Kevin Hilman <khilman@ti.com>
17Cc: Vishwanath BS <vishwanath.bs@ti.com>
18Cc: Todd Poynor <toddpoynor@google.com>
19Cc: Nishanth Menon <nm@ti.com>
20Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
21---
22 arch/arm/mach-omap1/Makefile | 3 +
23 arch/arm/mach-omap1/omap1-cpufreq.c | 175 ++++++++++++++++++++++++++
24 arch/arm/mach-omap2/Makefile | 3 +
25 arch/arm/mach-omap2/omap2plus-cpufreq.c | 201 ++++++++++++++++++++++++++++++
26 arch/arm/plat-omap/Makefile | 1 -
27 arch/arm/plat-omap/cpu-omap.c | 204 -------------------------------
28 6 files changed, 382 insertions(+), 205 deletions(-)
29 create mode 100644 arch/arm/mach-omap1/omap1-cpufreq.c
30 create mode 100644 arch/arm/mach-omap2/omap2plus-cpufreq.c
31 delete mode 100644 arch/arm/plat-omap/cpu-omap.c
32
33diff --git a/arch/arm/mach-omap1/Makefile b/arch/arm/mach-omap1/Makefile
34index 5b114d1..9600410 100644
35--- a/arch/arm/mach-omap1/Makefile
36+++ b/arch/arm/mach-omap1/Makefile
37@@ -10,6 +10,9 @@ obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o
38
39 obj-$(CONFIG_OMAP_32K_TIMER) += timer32k.o
40
41+# CPUFREQ driver
42+obj-$(CONFIG_CPU_FREQ) += omap1-cpufreq.o
43+
44 # Power Management
45 obj-$(CONFIG_PM) += pm.o sleep.o
46
47diff --git a/arch/arm/mach-omap1/omap1-cpufreq.c b/arch/arm/mach-omap1/omap1-cpufreq.c
48new file mode 100644
49index 0000000..7c5216e
50--- /dev/null
51+++ b/arch/arm/mach-omap1/omap1-cpufreq.c
52@@ -0,0 +1,175 @@
53+/*
54+ * OMAP1 cpufreq driver
55+ *
56+ * CPU frequency scaling for OMAP
57+ *
58+ * Copyright (C) 2005 Nokia Corporation
59+ * Written by Tony Lindgren <tony@atomide.com>
60+ *
61+ * Based on cpu-sa1110.c, Copyright (C) 2001 Russell King
62+ *
63+ * Copyright (C) 2007-2008 Texas Instruments, Inc.
64+ * Rajendra Nayak <rnayak@ti.com>
65+ *
66+ * This program is free software; you can redistribute it and/or modify
67+ * it under the terms of the GNU General Public License version 2 as
68+ * published by the Free Software Foundation.
69+ */
70+#include <linux/types.h>
71+#include <linux/kernel.h>
72+#include <linux/sched.h>
73+#include <linux/cpufreq.h>
74+#include <linux/delay.h>
75+#include <linux/init.h>
76+#include <linux/err.h>
77+#include <linux/clk.h>
78+#include <linux/io.h>
79+#include <linux/opp.h>
80+
81+#include <asm/system.h>
82+
83+#include <plat/clock.h>
84+#include <plat/omap-pm.h>
85+
86+#include <mach/hardware.h>
87+
88+#define VERY_HI_RATE 900000000
89+
90+static struct cpufreq_frequency_table *freq_table;
91+static struct clk *mpu_clk;
92+
93+static int omap_verify_speed(struct cpufreq_policy *policy)
94+{
95+ if (freq_table)
96+ return cpufreq_frequency_table_verify(policy, freq_table);
97+
98+ if (policy->cpu)
99+ return -EINVAL;
100+
101+ cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
102+ policy->cpuinfo.max_freq);
103+
104+ policy->min = clk_round_rate(mpu_clk, policy->min * 1000) / 1000;
105+ policy->max = clk_round_rate(mpu_clk, policy->max * 1000) / 1000;
106+ cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
107+ policy->cpuinfo.max_freq);
108+ return 0;
109+}
110+
111+static unsigned int omap_getspeed(unsigned int cpu)
112+{
113+ unsigned long rate;
114+
115+ if (cpu)
116+ return 0;
117+
118+ rate = clk_get_rate(mpu_clk) / 1000;
119+ return rate;
120+}
121+
122+static int omap_target(struct cpufreq_policy *policy,
123+ unsigned int target_freq,
124+ unsigned int relation)
125+{
126+ struct cpufreq_freqs freqs;
127+ int ret = 0;
128+
129+ /* Ensure desired rate is within allowed range. Some govenors
130+ * (ondemand) will just pass target_freq=0 to get the minimum. */
131+ if (target_freq < policy->min)
132+ target_freq = policy->min;
133+ if (target_freq > policy->max)
134+ target_freq = policy->max;
135+
136+ freqs.old = omap_getspeed(0);
137+ freqs.new = clk_round_rate(mpu_clk, target_freq * 1000) / 1000;
138+ freqs.cpu = 0;
139+
140+ if (freqs.old == freqs.new)
141+ return ret;
142+
143+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
144+
145+#ifdef CONFIG_CPU_FREQ_DEBUG
146+ pr_info("cpufreq-omap: transition: %u --> %u\n", freqs.old, freqs.new);
147+#endif
148+ ret = clk_set_rate(mpu_clk, freqs.new * 1000);
149+
150+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
151+
152+ return ret;
153+}
154+
155+static int __init omap_cpu_init(struct cpufreq_policy *policy)
156+{
157+ int result = 0;
158+
159+ mpu_clk = clk_get(NULL, "mpu");
160+ if (IS_ERR(mpu_clk))
161+ return PTR_ERR(mpu_clk);
162+
163+ if (policy->cpu != 0)
164+ return -EINVAL;
165+
166+ policy->cur = policy->min = policy->max = omap_getspeed(0);
167+
168+ clk_init_cpufreq_table(&freq_table);
169+
170+ if (freq_table) {
171+ result = cpufreq_frequency_table_cpuinfo(policy, freq_table);
172+ if (!result)
173+ cpufreq_frequency_table_get_attr(freq_table,
174+ policy->cpu);
175+ } else {
176+ policy->cpuinfo.min_freq = clk_round_rate(mpu_clk, 0) / 1000;
177+ policy->cpuinfo.max_freq = clk_round_rate(mpu_clk,
178+ VERY_HI_RATE) / 1000;
179+ }
180+
181+ policy->min = policy->cpuinfo.min_freq;
182+ policy->max = policy->cpuinfo.max_freq;
183+ policy->cur = omap_getspeed(0);
184+
185+ /* FIXME: what's the actual transition time? */
186+ policy->cpuinfo.transition_latency = 300 * 1000;
187+
188+ return 0;
189+}
190+
191+static int omap_cpu_exit(struct cpufreq_policy *policy)
192+{
193+ clk_exit_cpufreq_table(&freq_table);
194+ clk_put(mpu_clk);
195+ return 0;
196+}
197+
198+static struct freq_attr *omap_cpufreq_attr[] = {
199+ &cpufreq_freq_attr_scaling_available_freqs,
200+ NULL,
201+};
202+
203+static struct cpufreq_driver omap_driver = {
204+ .flags = CPUFREQ_STICKY,
205+ .verify = omap_verify_speed,
206+ .target = omap_target,
207+ .get = omap_getspeed,
208+ .init = omap_cpu_init,
209+ .exit = omap_cpu_exit,
210+ .name = "omap1",
211+ .attr = omap_cpufreq_attr,
212+};
213+
214+static int __init omap_cpufreq_init(void)
215+{
216+ return cpufreq_register_driver(&omap_driver);
217+}
218+
219+static void __exit omap_cpufreq_exit(void)
220+{
221+ cpufreq_unregister_driver(&omap_driver);
222+}
223+
224+MODULE_DESCRIPTION("cpufreq driver for OMAP1 SOCs");
225+MODULE_LICENSE("GPL");
226+module_init(omap_cpufreq_init);
227+module_exit(omap_cpufreq_exit);
228diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
229index 8e79ca5..7927dd6 100644
230--- a/arch/arm/mach-omap2/Makefile
231+++ b/arch/arm/mach-omap2/Makefile
232@@ -56,6 +56,9 @@ obj-$(CONFIG_ARCH_OMAP3) += opp3xxx_data.o
233 obj-$(CONFIG_ARCH_OMAP4) += opp4xxx_data.o
234 endif
235
236+# CPUFREQ driver
237+obj-$(CONFIG_CPU_FREQ) += omap2plus-cpufreq.o
238+
239 # Power Management
240 ifeq ($(CONFIG_PM),y)
241 obj-$(CONFIG_ARCH_OMAP2) += pm24xx.o
242diff --git a/arch/arm/mach-omap2/omap2plus-cpufreq.c b/arch/arm/mach-omap2/omap2plus-cpufreq.c
243new file mode 100644
244index 0000000..27f641b
245--- /dev/null
246+++ b/arch/arm/mach-omap2/omap2plus-cpufreq.c
247@@ -0,0 +1,201 @@
248+/*
249+ * OMAP2PLUS cpufreq driver
250+ *
251+ * CPU frequency scaling for OMAP
252+ *
253+ * Copyright (C) 2005 Nokia Corporation
254+ * Written by Tony Lindgren <tony@atomide.com>
255+ *
256+ * Based on cpu-sa1110.c, Copyright (C) 2001 Russell King
257+ *
258+ * Copyright (C) 2007-2011 Texas Instruments, Inc.
259+ * Updated to support OMAP3
260+ * Rajendra Nayak <rnayak@ti.com>
261+ *
262+ * This program is free software; you can redistribute it and/or modify
263+ * it under the terms of the GNU General Public License version 2 as
264+ * published by the Free Software Foundation.
265+ */
266+#include <linux/types.h>
267+#include <linux/kernel.h>
268+#include <linux/sched.h>
269+#include <linux/cpufreq.h>
270+#include <linux/delay.h>
271+#include <linux/init.h>
272+#include <linux/err.h>
273+#include <linux/clk.h>
274+#include <linux/io.h>
275+#include <linux/opp.h>
276+
277+#include <asm/system.h>
278+#include <asm/smp_plat.h>
279+
280+#include <plat/clock.h>
281+#include <plat/omap-pm.h>
282+#include <plat/common.h>
283+
284+#include <mach/hardware.h>
285+
286+#define VERY_HI_RATE 900000000
287+
288+static struct cpufreq_frequency_table *freq_table;
289+static struct clk *mpu_clk;
290+
291+static int omap_verify_speed(struct cpufreq_policy *policy)
292+{
293+ if (freq_table)
294+ return cpufreq_frequency_table_verify(policy, freq_table);
295+
296+ if (policy->cpu)
297+ return -EINVAL;
298+
299+ cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
300+ policy->cpuinfo.max_freq);
301+
302+ policy->min = clk_round_rate(mpu_clk, policy->min * 1000) / 1000;
303+ policy->max = clk_round_rate(mpu_clk, policy->max * 1000) / 1000;
304+ cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
305+ policy->cpuinfo.max_freq);
306+ return 0;
307+}
308+
309+static unsigned int omap_getspeed(unsigned int cpu)
310+{
311+ unsigned long rate;
312+
313+ if (cpu)
314+ return 0;
315+
316+ rate = clk_get_rate(mpu_clk) / 1000;
317+ return rate;
318+}
319+
320+static int omap_target(struct cpufreq_policy *policy,
321+ unsigned int target_freq,
322+ unsigned int relation)
323+{
324+ int ret = 0;
325+ struct cpufreq_freqs freqs;
326+
327+ /* Ensure desired rate is within allowed range. Some govenors
328+ * (ondemand) will just pass target_freq=0 to get the minimum. */
329+ if (target_freq < policy->min)
330+ target_freq = policy->min;
331+ if (target_freq > policy->max)
332+ target_freq = policy->max;
333+
334+ freqs.old = omap_getspeed(0);
335+ freqs.new = clk_round_rate(mpu_clk, target_freq * 1000) / 1000;
336+ freqs.cpu = 0;
337+
338+ if (freqs.old == freqs.new)
339+ return ret;
340+
341+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
342+
343+#ifdef CONFIG_CPU_FREQ_DEBUG
344+ pr_info("cpufreq-omap: transition: %u --> %u\n", freqs.old, freqs.new);
345+#endif
346+
347+ ret = clk_set_rate(mpu_clk, freqs.new * 1000);
348+
349+ /*
350+ * Generic CPUFREQ driver jiffy update is under !SMP. So jiffies
351+ * won't get updated when UP machine cpufreq build with
352+ * CONFIG_SMP enabled. Below code is added only to manage that
353+ * scenario
354+ */
355+ if (!is_smp())
356+ loops_per_jiffy =
357+ cpufreq_scale(loops_per_jiffy, freqs.old, freqs.new);
358+
359+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
360+
361+ return ret;
362+}
363+
364+static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
365+{
366+ int result = 0;
367+ struct device *mpu_dev;
368+
369+ if (cpu_is_omap24xx())
370+ mpu_clk = clk_get(NULL, "virt_prcm_set");
371+ else if (cpu_is_omap34xx())
372+ mpu_clk = clk_get(NULL, "dpll1_ck");
373+ else if (cpu_is_omap34xx())
374+ mpu_clk = clk_get(NULL, "dpll_mpu_ck");
375+
376+ if (IS_ERR(mpu_clk))
377+ return PTR_ERR(mpu_clk);
378+
379+ if (policy->cpu != 0)
380+ return -EINVAL;
381+
382+ policy->cur = policy->min = policy->max = omap_getspeed(0);
383+
384+ mpu_dev = omap2_get_mpuss_device();
385+ if (!mpu_dev) {
386+ pr_warning("%s: unable to get the mpu device\n", __func__);
387+ return -EINVAL;
388+ }
389+ opp_init_cpufreq_table(mpu_dev, &freq_table);
390+
391+ if (freq_table) {
392+ result = cpufreq_frequency_table_cpuinfo(policy, freq_table);
393+ if (!result)
394+ cpufreq_frequency_table_get_attr(freq_table,
395+ policy->cpu);
396+ } else {
397+ policy->cpuinfo.min_freq = clk_round_rate(mpu_clk, 0) / 1000;
398+ policy->cpuinfo.max_freq = clk_round_rate(mpu_clk,
399+ VERY_HI_RATE) / 1000;
400+ }
401+
402+ policy->min = policy->cpuinfo.min_freq;
403+ policy->max = policy->cpuinfo.max_freq;
404+ policy->cur = omap_getspeed(0);
405+
406+ /* FIXME: what's the actual transition time? */
407+ policy->cpuinfo.transition_latency = 300 * 1000;
408+
409+ return 0;
410+}
411+
412+static int omap_cpu_exit(struct cpufreq_policy *policy)
413+{
414+ clk_exit_cpufreq_table(&freq_table);
415+ clk_put(mpu_clk);
416+ return 0;
417+}
418+
419+static struct freq_attr *omap_cpufreq_attr[] = {
420+ &cpufreq_freq_attr_scaling_available_freqs,
421+ NULL,
422+};
423+
424+static struct cpufreq_driver omap_driver = {
425+ .flags = CPUFREQ_STICKY,
426+ .verify = omap_verify_speed,
427+ .target = omap_target,
428+ .get = omap_getspeed,
429+ .init = omap_cpu_init,
430+ .exit = omap_cpu_exit,
431+ .name = "omap2plus",
432+ .attr = omap_cpufreq_attr,
433+};
434+
435+static int __init omap_cpufreq_init(void)
436+{
437+ return cpufreq_register_driver(&omap_driver);
438+}
439+
440+static void __exit omap_cpufreq_exit(void)
441+{
442+ cpufreq_unregister_driver(&omap_driver);
443+}
444+
445+MODULE_DESCRIPTION("cpufreq driver for OMAP2PLUS SOCs");
446+MODULE_LICENSE("GPL");
447+module_init(omap_cpufreq_init);
448+module_exit(omap_cpufreq_exit);
449diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-omap/Makefile
450index f0233e6..4ef7493 100644
451--- a/arch/arm/plat-omap/Makefile
452+++ b/arch/arm/plat-omap/Makefile
453@@ -21,7 +21,6 @@ obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o
454 obj-$(CONFIG_OMAP_IOMMU) += iommu.o iovmm.o
455 obj-$(CONFIG_OMAP_IOMMU_DEBUG) += iommu-debug.o
456
457-obj-$(CONFIG_CPU_FREQ) += cpu-omap.o
458 obj-$(CONFIG_OMAP_DM_TIMER) += dmtimer.o
459 obj-$(CONFIG_OMAP_DEBUG_DEVICES) += debug-devices.o
460 obj-$(CONFIG_OMAP_DEBUG_LEDS) += debug-leds.o
461diff --git a/arch/arm/plat-omap/cpu-omap.c b/arch/arm/plat-omap/cpu-omap.c
462deleted file mode 100644
463index 9cd2709..0000000
464--- a/arch/arm/plat-omap/cpu-omap.c
465+++ /dev/null
466@@ -1,204 +0,0 @@
467-/*
468- * linux/arch/arm/plat-omap/cpu-omap.c
469- *
470- * CPU frequency scaling for OMAP
471- *
472- * Copyright (C) 2005 Nokia Corporation
473- * Written by Tony Lindgren <tony@atomide.com>
474- *
475- * Based on cpu-sa1110.c, Copyright (C) 2001 Russell King
476- *
477- * Copyright (C) 2007-2008 Texas Instruments, Inc.
478- * Updated to support OMAP3
479- * Rajendra Nayak <rnayak@ti.com>
480- *
481- * This program is free software; you can redistribute it and/or modify
482- * it under the terms of the GNU General Public License version 2 as
483- * published by the Free Software Foundation.
484- */
485-#include <linux/types.h>
486-#include <linux/kernel.h>
487-#include <linux/sched.h>
488-#include <linux/cpufreq.h>
489-#include <linux/delay.h>
490-#include <linux/init.h>
491-#include <linux/err.h>
492-#include <linux/clk.h>
493-#include <linux/io.h>
494-#include <linux/opp.h>
495-
496-#include <mach/hardware.h>
497-#include <plat/clock.h>
498-#include <asm/system.h>
499-
500-#if defined(CONFIG_ARCH_OMAP3) && !defined(CONFIG_OMAP_PM_NONE)
501-#include <plat/omap-pm.h>
502-#include <plat/common.h>
503-#endif
504-
505-#define VERY_HI_RATE 900000000
506-
507-static struct cpufreq_frequency_table *freq_table;
508-
509-#ifdef CONFIG_ARCH_OMAP1
510-#define MPU_CLK "mpu"
511-#elif defined(CONFIG_ARCH_OMAP3)
512-#define MPU_CLK "arm_fck"
513-#else
514-#define MPU_CLK "virt_prcm_set"
515-#endif
516-
517-static struct clk *mpu_clk;
518-
519-/* TODO: Add support for SDRAM timing changes */
520-
521-static int omap_verify_speed(struct cpufreq_policy *policy)
522-{
523- if (freq_table)
524- return cpufreq_frequency_table_verify(policy, freq_table);
525-
526- if (policy->cpu)
527- return -EINVAL;
528-
529- cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
530- policy->cpuinfo.max_freq);
531-
532- policy->min = clk_round_rate(mpu_clk, policy->min * 1000) / 1000;
533- policy->max = clk_round_rate(mpu_clk, policy->max * 1000) / 1000;
534- cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
535- policy->cpuinfo.max_freq);
536- return 0;
537-}
538-
539-static unsigned int omap_getspeed(unsigned int cpu)
540-{
541- unsigned long rate;
542-
543- if (cpu)
544- return 0;
545-
546- rate = clk_get_rate(mpu_clk) / 1000;
547- return rate;
548-}
549-
550-static int omap_target(struct cpufreq_policy *policy,
551- unsigned int target_freq,
552- unsigned int relation)
553-{
554-#ifdef CONFIG_ARCH_OMAP1
555- struct cpufreq_freqs freqs;
556-#endif
557-#if defined(CONFIG_ARCH_OMAP3) && !defined(CONFIG_OMAP_PM_NONE)
558- unsigned long freq;
559- struct device *mpu_dev = omap2_get_mpuss_device();
560-#endif
561- int ret = 0;
562-
563- /* Ensure desired rate is within allowed range. Some govenors
564- * (ondemand) will just pass target_freq=0 to get the minimum. */
565- if (target_freq < policy->min)
566- target_freq = policy->min;
567- if (target_freq > policy->max)
568- target_freq = policy->max;
569-
570-#ifdef CONFIG_ARCH_OMAP1
571- freqs.old = omap_getspeed(0);
572- freqs.new = clk_round_rate(mpu_clk, target_freq * 1000) / 1000;
573- freqs.cpu = 0;
574-
575- if (freqs.old == freqs.new)
576- return ret;
577- cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
578-#ifdef CONFIG_CPU_FREQ_DEBUG
579- printk(KERN_DEBUG "cpufreq-omap: transition: %u --> %u\n",
580- freqs.old, freqs.new);
581-#endif
582- ret = clk_set_rate(mpu_clk, freqs.new * 1000);
583- cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
584-#elif defined(CONFIG_ARCH_OMAP3) && !defined(CONFIG_OMAP_PM_NONE)
585- freq = target_freq * 1000;
586- if (opp_find_freq_ceil(mpu_dev, &freq))
587- omap_pm_cpu_set_freq(freq);
588-#endif
589- return ret;
590-}
591-
592-static int __cpuinit omap_cpu_init(struct cpufreq_policy *policy)
593-{
594- int result = 0;
595-
596- mpu_clk = clk_get(NULL, MPU_CLK);
597- if (IS_ERR(mpu_clk))
598- return PTR_ERR(mpu_clk);
599-
600- if (policy->cpu != 0)
601- return -EINVAL;
602-
603- policy->cur = policy->min = policy->max = omap_getspeed(0);
604-
605- if (!cpu_is_omap34xx()) {
606- clk_init_cpufreq_table(&freq_table);
607- } else {
608- struct device *mpu_dev = omap2_get_mpuss_device();
609-
610- opp_init_cpufreq_table(mpu_dev, &freq_table);
611- }
612-
613- if (freq_table) {
614- result = cpufreq_frequency_table_cpuinfo(policy, freq_table);
615- if (!result)
616- cpufreq_frequency_table_get_attr(freq_table,
617- policy->cpu);
618- } else {
619- policy->cpuinfo.min_freq = clk_round_rate(mpu_clk, 0) / 1000;
620- policy->cpuinfo.max_freq = clk_round_rate(mpu_clk,
621- VERY_HI_RATE) / 1000;
622- }
623-
624- policy->min = policy->cpuinfo.min_freq;
625- policy->max = policy->cpuinfo.max_freq;
626- policy->cur = omap_getspeed(0);
627-
628- /* FIXME: what's the actual transition time? */
629- policy->cpuinfo.transition_latency = 300 * 1000;
630-
631- return 0;
632-}
633-
634-static int omap_cpu_exit(struct cpufreq_policy *policy)
635-{
636- clk_exit_cpufreq_table(&freq_table);
637- clk_put(mpu_clk);
638- return 0;
639-}
640-
641-static struct freq_attr *omap_cpufreq_attr[] = {
642- &cpufreq_freq_attr_scaling_available_freqs,
643- NULL,
644-};
645-
646-static struct cpufreq_driver omap_driver = {
647- .flags = CPUFREQ_STICKY,
648- .verify = omap_verify_speed,
649- .target = omap_target,
650- .get = omap_getspeed,
651- .init = omap_cpu_init,
652- .exit = omap_cpu_exit,
653- .name = "omap",
654- .attr = omap_cpufreq_attr,
655-};
656-
657-static int __init omap_cpufreq_init(void)
658-{
659- return cpufreq_register_driver(&omap_driver);
660-}
661-
662-late_initcall(omap_cpufreq_init);
663-
664-/*
665- * if ever we want to remove this, upon cleanup call:
666- *
667- * cpufreq_unregister_driver()
668- * cpufreq_frequency_table_put_attr()
669- */
670-
671--
6721.7.2.5
673