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