aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authorViresh Kumar <viresh.kumar@linaro.org>2013-04-04 08:54:15 -0400
committerKukjin Kim <kgene.kim@samsung.com>2013-05-20 10:04:28 -0400
commitf023f8dd59bf93e29e9b9bd98a92eeef43b1a32a (patch)
tree404224a1a4b000b37cf5955d9090d0fe247eef20 /arch/arm
parentf722406faae2d073cc1d01063d1123c35425939e (diff)
cpufreq: s3c24xx: move cpufreq driver to drivers/cpufreq
This patch moves cpufreq driver of Samsung's ARM based s3c24xx platform to drivers/cpufreq. Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org> Acked-by: Arnd Bergmann <arnd@arndb.de> Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/Kconfig47
-rw-r--r--arch/arm/mach-s3c24xx/Kconfig66
-rw-r--r--arch/arm/mach-s3c24xx/Makefile6
-rw-r--r--arch/arm/mach-s3c24xx/cpufreq-debugfs.c198
-rw-r--r--arch/arm/mach-s3c24xx/cpufreq-s3c2410.c160
-rw-r--r--arch/arm/mach-s3c24xx/cpufreq-s3c2412.c258
-rw-r--r--arch/arm/mach-s3c24xx/cpufreq-s3c2440.c312
-rw-r--r--arch/arm/mach-s3c24xx/cpufreq.c711
-rw-r--r--arch/arm/mach-s3c24xx/include/mach/s3c2412.h (renamed from arch/arm/mach-s3c24xx/s3c2412.h)0
-rw-r--r--arch/arm/mach-s3c24xx/iotiming-s3c2412.c2
-rw-r--r--arch/arm/plat-samsung/include/plat/cpu-freq-core.h10
-rw-r--r--arch/arm/plat-samsung/include/plat/cpu-freq.h6
12 files changed, 36 insertions, 1740 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index d423d58f938d..f6762794fbb4 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -2053,53 +2053,6 @@ menu "CPU Power Management"
2053 2053
2054if ARCH_HAS_CPUFREQ 2054if ARCH_HAS_CPUFREQ
2055source "drivers/cpufreq/Kconfig" 2055source "drivers/cpufreq/Kconfig"
2056
2057config CPU_FREQ_S3C
2058 bool
2059 help
2060 Internal configuration node for common cpufreq on Samsung SoC
2061
2062config CPU_FREQ_S3C24XX
2063 bool "CPUfreq driver for Samsung S3C24XX series CPUs (EXPERIMENTAL)"
2064 depends on ARCH_S3C24XX && CPU_FREQ
2065 select CPU_FREQ_S3C
2066 help
2067 This enables the CPUfreq driver for the Samsung S3C24XX family
2068 of CPUs.
2069
2070 For details, take a look at <file:Documentation/cpu-freq>.
2071
2072 If in doubt, say N.
2073
2074config CPU_FREQ_S3C24XX_PLL
2075 bool "Support CPUfreq changing of PLL frequency (EXPERIMENTAL)"
2076 depends on CPU_FREQ_S3C24XX
2077 help
2078 Compile in support for changing the PLL frequency from the
2079 S3C24XX series CPUfreq driver. The PLL takes time to settle
2080 after a frequency change, so by default it is not enabled.
2081
2082 This also means that the PLL tables for the selected CPU(s) will
2083 be built which may increase the size of the kernel image.
2084
2085config CPU_FREQ_S3C24XX_DEBUG
2086 bool "Debug CPUfreq Samsung driver core"
2087 depends on CPU_FREQ_S3C24XX
2088 help
2089 Enable s3c_freq_dbg for the Samsung S3C CPUfreq core
2090
2091config CPU_FREQ_S3C24XX_IODEBUG
2092 bool "Debug CPUfreq Samsung driver IO timing"
2093 depends on CPU_FREQ_S3C24XX
2094 help
2095 Enable s3c_freq_iodbg for the Samsung S3C CPUfreq core
2096
2097config CPU_FREQ_S3C24XX_DEBUGFS
2098 bool "Export debugfs for CPUFreq"
2099 depends on CPU_FREQ_S3C24XX && DEBUG_FS
2100 help
2101 Export status information via debugfs.
2102
2103endif 2056endif
2104 2057
2105source "drivers/cpuidle/Kconfig" 2058source "drivers/cpuidle/Kconfig"
diff --git a/arch/arm/mach-s3c24xx/Kconfig b/arch/arm/mach-s3c24xx/Kconfig
index f2f7088bfd22..ed8aadc646f9 100644
--- a/arch/arm/mach-s3c24xx/Kconfig
+++ b/arch/arm/mach-s3c24xx/Kconfig
@@ -28,7 +28,7 @@ config CPU_S3C2410
28 select CPU_ARM920T 28 select CPU_ARM920T
29 select CPU_LLSERIAL_S3C2410 29 select CPU_LLSERIAL_S3C2410
30 select S3C2410_CLOCK 30 select S3C2410_CLOCK
31 select S3C2410_CPUFREQ if CPU_FREQ_S3C24XX 31 select ARM_S3C2410_CPUFREQ if ARM_S3C24XX_CPUFREQ
32 select S3C2410_PM if PM 32 select S3C2410_PM if PM
33 select SAMSUNG_HRT 33 select SAMSUNG_HRT
34 help 34 help
@@ -204,27 +204,38 @@ config S3C24XX_GPIO_EXTRA128
204 Add an extra 128 gpio numbers to the available GPIO pool. This is 204 Add an extra 128 gpio numbers to the available GPIO pool. This is
205 available for boards that need extra gpios for external devices. 205 available for boards that need extra gpios for external devices.
206 206
207config S3C24XX_PLL
208 bool "Support CPUfreq changing of PLL frequency (EXPERIMENTAL)"
209 depends on ARM_S3C24XX
210 help
211 Compile in support for changing the PLL frequency from the
212 S3C24XX series CPUfreq driver. The PLL takes time to settle
213 after a frequency change, so by default it is not enabled.
214
215 This also means that the PLL tables for the selected CPU(s) will
216 be built which may increase the size of the kernel image.
217
207# cpu frequency items common between s3c2410 and s3c2440/s3c2442 218# cpu frequency items common between s3c2410 and s3c2440/s3c2442
208 219
209config S3C2410_IOTIMING 220config S3C2410_IOTIMING
210 bool 221 bool
211 depends on CPU_FREQ_S3C24XX 222 depends on ARM_S3C24XX_CPUFREQ
212 help 223 help
213 Internal node to select io timing code that is common to the s3c2410 224 Internal node to select io timing code that is common to the s3c2410
214 and s3c2440/s3c2442 cpu frequency support. 225 and s3c2440/s3c2442 cpu frequency support.
215 226
216config S3C2410_CPUFREQ_UTILS 227config S3C2410_CPUFREQ_UTILS
217 bool 228 bool
218 depends on CPU_FREQ_S3C24XX 229 depends on ARM_S3C24XX_CPUFREQ
219 help 230 help
220 Internal node to select timing code that is common to the s3c2410 231 Internal node to select timing code that is common to the s3c2410
221 and s3c2440/s3c244 cpu frequency support. 232 and s3c2440/s3c244 cpu frequency support.
222 233
223# cpu frequency support common to s3c2412, s3c2413 and s3c2442 234# cpu frequency support common to s3c2412, s3c2413 and s3c2442
224 235
225config S3C2412_IOTIMING 236config S3C2412_IOTIMING
226 bool 237 bool
227 depends on CPU_FREQ_S3C24XX && (CPU_S3C2412 || CPU_S3C2443) 238 depends on ARM_S3C24XX_CPUFREQ && (CPU_S3C2412 || CPU_S3C2443)
228 help 239 help
229 Intel node to select io timing code that is common to the s3c2412 240 Intel node to select io timing code that is common to the s3c2412
230 and the s3c2443. 241 and the s3c2443.
@@ -233,16 +244,9 @@ config S3C2412_IOTIMING
233 244
234if CPU_S3C2410 245if CPU_S3C2410
235 246
236config S3C2410_CPUFREQ
237 bool
238 depends on CPU_FREQ_S3C24XX
239 select S3C2410_CPUFREQ_UTILS
240 help
241 CPU Frequency scaling support for S3C2410
242
243config S3C2410_PLL 247config S3C2410_PLL
244 bool 248 bool
245 depends on S3C2410_CPUFREQ && CPU_FREQ_S3C24XX_PLL 249 depends on ARM_S3C2410_CPUFREQ && S3C24XX_PLL
246 default y 250 default y
247 help 251 help
248 Select the PLL table for the S3C2410 252 Select the PLL table for the S3C2410
@@ -278,7 +282,7 @@ config ARCH_BAST
278 bool "Simtec Electronics BAST (EB2410ITX)" 282 bool "Simtec Electronics BAST (EB2410ITX)"
279 select ISA 283 select ISA
280 select MACH_BAST_IDE 284 select MACH_BAST_IDE
281 select S3C2410_IOTIMING if S3C2410_CPUFREQ 285 select S3C2410_IOTIMING if ARM_S3C2410_CPUFREQ
282 select S3C24XX_DCLK 286 select S3C24XX_DCLK
283 select S3C24XX_SIMTEC_NOR 287 select S3C24XX_SIMTEC_NOR
284 select S3C24XX_SIMTEC_PM if PM 288 select S3C24XX_SIMTEC_PM if PM
@@ -385,14 +389,6 @@ config CPU_S3C2412_ONLY
385 !CPU_S3C2442 && !CPU_S3C2443 389 !CPU_S3C2442 && !CPU_S3C2443
386 default y 390 default y
387 391
388config S3C2412_CPUFREQ
389 bool
390 depends on CPU_FREQ_S3C24XX
391 default y
392 select S3C2412_IOTIMING
393 help
394 CPU Frequency scaling support for S3C2412 and S3C2413 SoC CPUs.
395
396config S3C2412_DMA 392config S3C2412_DMA
397 bool 393 bool
398 help 394 help
@@ -494,14 +490,6 @@ endif # CPU_S3C2416
494 490
495if CPU_S3C2440 491if CPU_S3C2440
496 492
497config S3C2440_CPUFREQ
498 bool "S3C2440/S3C2442 CPU Frequency scaling support"
499 depends on CPU_FREQ_S3C24XX && (CPU_S3C2440 || CPU_S3C2442)
500 default y
501 select S3C2410_CPUFREQ_UTILS
502 help
503 CPU Frequency scaling support for S3C2440 and S3C2442 SoC CPUs.
504
505config S3C2440_DMA 493config S3C2440_DMA
506 bool 494 bool
507 help 495 help
@@ -521,15 +509,15 @@ config S3C2440_XTAL_16934400
521 509
522config S3C2440_PLL_12000000 510config S3C2440_PLL_12000000
523 bool 511 bool
524 depends on S3C2440_CPUFREQ && S3C2440_XTAL_12000000 512 depends on ARM_S3C2440_CPUFREQ && S3C2440_XTAL_12000000
525 default y if CPU_FREQ_S3C24XX_PLL 513 default y if S3C24XX_PLL
526 help 514 help
527 PLL tables for S3C2440 or S3C2442 CPUs with 12MHz crystals. 515 PLL tables for S3C2440 or S3C2442 CPUs with 12MHz crystals.
528 516
529config S3C2440_PLL_16934400 517config S3C2440_PLL_16934400
530 bool 518 bool
531 depends on S3C2440_CPUFREQ && S3C2440_XTAL_16934400 519 depends on ARM_S3C2440_CPUFREQ && S3C2440_XTAL_16934400
532 default y if CPU_FREQ_S3C24XX_PLL 520 default y if S3C24XX_PLL
533 help 521 help
534 PLL tables for S3C2440 or S3C2442 CPUs with 16.934MHz crystals. 522 PLL tables for S3C2440 or S3C2442 CPUs with 16.934MHz crystals.
535 523
@@ -583,7 +571,7 @@ config MACH_NEXCODER_2440
583 571
584config MACH_OSIRIS 572config MACH_OSIRIS
585 bool "Simtec IM2440D20 (OSIRIS) module" 573 bool "Simtec IM2440D20 (OSIRIS) module"
586 select S3C2410_IOTIMING if S3C2440_CPUFREQ 574 select S3C2410_IOTIMING if ARM_S3C2440_CPUFREQ
587 select S3C2440_XTAL_12000000 575 select S3C2440_XTAL_12000000
588 select S3C24XX_DCLK 576 select S3C24XX_DCLK
589 select S3C24XX_GPIO_EXTRA128 577 select S3C24XX_GPIO_EXTRA128
@@ -655,7 +643,7 @@ config MACH_RX1950
655 bool "HP iPAQ rx1950" 643 bool "HP iPAQ rx1950"
656 select I2C 644 select I2C
657 select PM_H1940 if PM 645 select PM_H1940 if PM
658 select S3C2410_IOTIMING if S3C2440_CPUFREQ 646 select S3C2410_IOTIMING if ARM_S3C2440_CPUFREQ
659 select S3C2440_XTAL_16934400 647 select S3C2440_XTAL_16934400
660 select S3C24XX_DCLK 648 select S3C24XX_DCLK
661 select S3C24XX_PWM 649 select S3C24XX_PWM
diff --git a/arch/arm/mach-s3c24xx/Makefile b/arch/arm/mach-s3c24xx/Makefile
index 6f46ecfc8396..a3b495a4bba0 100644
--- a/arch/arm/mach-s3c24xx/Makefile
+++ b/arch/arm/mach-s3c24xx/Makefile
@@ -17,13 +17,11 @@ obj- :=
17obj-y += common.o 17obj-y += common.o
18 18
19obj-$(CONFIG_CPU_S3C2410) += s3c2410.o 19obj-$(CONFIG_CPU_S3C2410) += s3c2410.o
20obj-$(CONFIG_S3C2410_CPUFREQ) += cpufreq-s3c2410.o
21obj-$(CONFIG_S3C2410_DMA) += dma-s3c2410.o 20obj-$(CONFIG_S3C2410_DMA) += dma-s3c2410.o
22obj-$(CONFIG_S3C2410_PLL) += pll-s3c2410.o 21obj-$(CONFIG_S3C2410_PLL) += pll-s3c2410.o
23obj-$(CONFIG_S3C2410_PM) += pm-s3c2410.o sleep-s3c2410.o 22obj-$(CONFIG_S3C2410_PM) += pm-s3c2410.o sleep-s3c2410.o
24 23
25obj-$(CONFIG_CPU_S3C2412) += s3c2412.o clock-s3c2412.o 24obj-$(CONFIG_CPU_S3C2412) += s3c2412.o clock-s3c2412.o
26obj-$(CONFIG_S3C2412_CPUFREQ) += cpufreq-s3c2412.o
27obj-$(CONFIG_S3C2412_DMA) += dma-s3c2412.o 25obj-$(CONFIG_S3C2412_DMA) += dma-s3c2412.o
28obj-$(CONFIG_S3C2412_PM) += pm-s3c2412.o 26obj-$(CONFIG_S3C2412_PM) += pm-s3c2412.o
29obj-$(CONFIG_S3C2412_PM_SLEEP) += sleep-s3c2412.o 27obj-$(CONFIG_S3C2412_PM_SLEEP) += sleep-s3c2412.o
@@ -34,7 +32,6 @@ obj-$(CONFIG_S3C2416_PM) += pm-s3c2416.o
34obj-$(CONFIG_CPU_S3C2440) += s3c2440.o clock-s3c2440.o 32obj-$(CONFIG_CPU_S3C2440) += s3c2440.o clock-s3c2440.o
35obj-$(CONFIG_CPU_S3C2442) += s3c2442.o 33obj-$(CONFIG_CPU_S3C2442) += s3c2442.o
36obj-$(CONFIG_CPU_S3C244X) += s3c244x.o clock-s3c244x.o 34obj-$(CONFIG_CPU_S3C244X) += s3c244x.o clock-s3c244x.o
37obj-$(CONFIG_S3C2440_CPUFREQ) += cpufreq-s3c2440.o
38obj-$(CONFIG_S3C2440_DMA) += dma-s3c2440.o 35obj-$(CONFIG_S3C2440_DMA) += dma-s3c2440.o
39obj-$(CONFIG_S3C2440_PLL_12000000) += pll-s3c2440-12000000.o 36obj-$(CONFIG_S3C2440_PLL_12000000) += pll-s3c2440-12000000.o
40obj-$(CONFIG_S3C2440_PLL_16934400) += pll-s3c2440-16934400.o 37obj-$(CONFIG_S3C2440_PLL_16934400) += pll-s3c2440-16934400.o
@@ -59,9 +56,6 @@ obj-$(CONFIG_S3C2412_IOTIMING) += iotiming-s3c2412.o
59obj-$(CONFIG_S3C2443_COMMON) += common-s3c2443.o 56obj-$(CONFIG_S3C2443_COMMON) += common-s3c2443.o
60obj-$(CONFIG_S3C2443_DMA) += dma-s3c2443.o 57obj-$(CONFIG_S3C2443_DMA) += dma-s3c2443.o
61 58
62obj-$(CONFIG_CPU_FREQ_S3C24XX) += cpufreq.o
63obj-$(CONFIG_CPU_FREQ_S3C24XX_DEBUGFS) += cpufreq-debugfs.o
64
65# 59#
66# machine support 60# machine support
67# following is ordered alphabetically by option text. 61# following is ordered alphabetically by option text.
diff --git a/arch/arm/mach-s3c24xx/cpufreq-debugfs.c b/arch/arm/mach-s3c24xx/cpufreq-debugfs.c
deleted file mode 100644
index 9b7b4289d66c..000000000000
--- a/arch/arm/mach-s3c24xx/cpufreq-debugfs.c
+++ /dev/null
@@ -1,198 +0,0 @@
1/*
2 * Copyright (c) 2009 Simtec Electronics
3 * http://armlinux.simtec.co.uk/
4 * Ben Dooks <ben@simtec.co.uk>
5 *
6 * S3C24XX CPU Frequency scaling - debugfs status support
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#include <linux/init.h>
14#include <linux/export.h>
15#include <linux/interrupt.h>
16#include <linux/ioport.h>
17#include <linux/cpufreq.h>
18#include <linux/debugfs.h>
19#include <linux/seq_file.h>
20#include <linux/err.h>
21
22#include <plat/cpu-freq-core.h>
23
24static struct dentry *dbgfs_root;
25static struct dentry *dbgfs_file_io;
26static struct dentry *dbgfs_file_info;
27static struct dentry *dbgfs_file_board;
28
29#define print_ns(x) ((x) / 10), ((x) % 10)
30
31static void show_max(struct seq_file *seq, struct s3c_freq *f)
32{
33 seq_printf(seq, "MAX: F=%lu, H=%lu, P=%lu, A=%lu\n",
34 f->fclk, f->hclk, f->pclk, f->armclk);
35}
36
37static int board_show(struct seq_file *seq, void *p)
38{
39 struct s3c_cpufreq_config *cfg;
40 struct s3c_cpufreq_board *brd;
41
42 cfg = s3c_cpufreq_getconfig();
43 if (!cfg) {
44 seq_printf(seq, "no configuration registered\n");
45 return 0;
46 }
47
48 brd = cfg->board;
49 if (!brd) {
50 seq_printf(seq, "no board definition set?\n");
51 return 0;
52 }
53
54 seq_printf(seq, "SDRAM refresh %u ns\n", brd->refresh);
55 seq_printf(seq, "auto_io=%u\n", brd->auto_io);
56 seq_printf(seq, "need_io=%u\n", brd->need_io);
57
58 show_max(seq, &brd->max);
59
60
61 return 0;
62}
63
64static int fops_board_open(struct inode *inode, struct file *file)
65{
66 return single_open(file, board_show, NULL);
67}
68
69static const struct file_operations fops_board = {
70 .open = fops_board_open,
71 .read = seq_read,
72 .llseek = seq_lseek,
73 .release = single_release,
74 .owner = THIS_MODULE,
75};
76
77static int info_show(struct seq_file *seq, void *p)
78{
79 struct s3c_cpufreq_config *cfg;
80
81 cfg = s3c_cpufreq_getconfig();
82 if (!cfg) {
83 seq_printf(seq, "no configuration registered\n");
84 return 0;
85 }
86
87 seq_printf(seq, " FCLK %ld Hz\n", cfg->freq.fclk);
88 seq_printf(seq, " HCLK %ld Hz (%lu.%lu ns)\n",
89 cfg->freq.hclk, print_ns(cfg->freq.hclk_tns));
90 seq_printf(seq, " PCLK %ld Hz\n", cfg->freq.hclk);
91 seq_printf(seq, "ARMCLK %ld Hz\n", cfg->freq.armclk);
92 seq_printf(seq, "\n");
93
94 show_max(seq, &cfg->max);
95
96 seq_printf(seq, "Divisors: P=%d, H=%d, A=%d, dvs=%s\n",
97 cfg->divs.h_divisor, cfg->divs.p_divisor,
98 cfg->divs.arm_divisor, cfg->divs.dvs ? "on" : "off");
99 seq_printf(seq, "\n");
100
101 seq_printf(seq, "lock_pll=%u\n", cfg->lock_pll);
102
103 return 0;
104}
105
106static int fops_info_open(struct inode *inode, struct file *file)
107{
108 return single_open(file, info_show, NULL);
109}
110
111static const struct file_operations fops_info = {
112 .open = fops_info_open,
113 .read = seq_read,
114 .llseek = seq_lseek,
115 .release = single_release,
116 .owner = THIS_MODULE,
117};
118
119static int io_show(struct seq_file *seq, void *p)
120{
121 void (*show_bank)(struct seq_file *, struct s3c_cpufreq_config *, union s3c_iobank *);
122 struct s3c_cpufreq_config *cfg;
123 struct s3c_iotimings *iot;
124 union s3c_iobank *iob;
125 int bank;
126
127 cfg = s3c_cpufreq_getconfig();
128 if (!cfg) {
129 seq_printf(seq, "no configuration registered\n");
130 return 0;
131 }
132
133 show_bank = cfg->info->debug_io_show;
134 if (!show_bank) {
135 seq_printf(seq, "no code to show bank timing\n");
136 return 0;
137 }
138
139 iot = s3c_cpufreq_getiotimings();
140 if (!iot) {
141 seq_printf(seq, "no io timings registered\n");
142 return 0;
143 }
144
145 seq_printf(seq, "hclk period is %lu.%lu ns\n", print_ns(cfg->freq.hclk_tns));
146
147 for (bank = 0; bank < MAX_BANKS; bank++) {
148 iob = &iot->bank[bank];
149
150 seq_printf(seq, "bank %d: ", bank);
151
152 if (!iob->io_2410) {
153 seq_printf(seq, "nothing set\n");
154 continue;
155 }
156
157 show_bank(seq, cfg, iob);
158 }
159
160 return 0;
161}
162
163static int fops_io_open(struct inode *inode, struct file *file)
164{
165 return single_open(file, io_show, NULL);
166}
167
168static const struct file_operations fops_io = {
169 .open = fops_io_open,
170 .read = seq_read,
171 .llseek = seq_lseek,
172 .release = single_release,
173 .owner = THIS_MODULE,
174};
175
176
177static int __init s3c_freq_debugfs_init(void)
178{
179 dbgfs_root = debugfs_create_dir("s3c-cpufreq", NULL);
180 if (IS_ERR(dbgfs_root)) {
181 printk(KERN_ERR "%s: error creating debugfs root\n", __func__);
182 return PTR_ERR(dbgfs_root);
183 }
184
185 dbgfs_file_io = debugfs_create_file("io-timing", S_IRUGO, dbgfs_root,
186 NULL, &fops_io);
187
188 dbgfs_file_info = debugfs_create_file("info", S_IRUGO, dbgfs_root,
189 NULL, &fops_info);
190
191 dbgfs_file_board = debugfs_create_file("board", S_IRUGO, dbgfs_root,
192 NULL, &fops_board);
193
194 return 0;
195}
196
197late_initcall(s3c_freq_debugfs_init);
198
diff --git a/arch/arm/mach-s3c24xx/cpufreq-s3c2410.c b/arch/arm/mach-s3c24xx/cpufreq-s3c2410.c
deleted file mode 100644
index cfa0dd8723ec..000000000000
--- a/arch/arm/mach-s3c24xx/cpufreq-s3c2410.c
+++ /dev/null
@@ -1,160 +0,0 @@
1/*
2 * Copyright (c) 2006-2008 Simtec Electronics
3 * http://armlinux.simtec.co.uk/
4 * Ben Dooks <ben@simtec.co.uk>
5 *
6 * S3C2410 CPU Frequency scaling
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#include <linux/init.h>
14#include <linux/module.h>
15#include <linux/interrupt.h>
16#include <linux/ioport.h>
17#include <linux/cpufreq.h>
18#include <linux/device.h>
19#include <linux/clk.h>
20#include <linux/err.h>
21#include <linux/io.h>
22
23#include <asm/mach/arch.h>
24#include <asm/mach/map.h>
25
26#include <mach/regs-clock.h>
27
28#include <plat/cpu.h>
29#include <plat/clock.h>
30#include <plat/cpu-freq-core.h>
31
32/* Note, 2410A has an extra mode for 1:4:4 ratio, bit 2 of CLKDIV */
33
34static void s3c2410_cpufreq_setdivs(struct s3c_cpufreq_config *cfg)
35{
36 u32 clkdiv = 0;
37
38 if (cfg->divs.h_divisor == 2)
39 clkdiv |= S3C2410_CLKDIVN_HDIVN;
40
41 if (cfg->divs.p_divisor != cfg->divs.h_divisor)
42 clkdiv |= S3C2410_CLKDIVN_PDIVN;
43
44 __raw_writel(clkdiv, S3C2410_CLKDIVN);
45}
46
47static int s3c2410_cpufreq_calcdivs(struct s3c_cpufreq_config *cfg)
48{
49 unsigned long hclk, fclk, pclk;
50 unsigned int hdiv, pdiv;
51 unsigned long hclk_max;
52
53 fclk = cfg->freq.fclk;
54 hclk_max = cfg->max.hclk;
55
56 cfg->freq.armclk = fclk;
57
58 s3c_freq_dbg("%s: fclk is %lu, max hclk %lu\n",
59 __func__, fclk, hclk_max);
60
61 hdiv = (fclk > cfg->max.hclk) ? 2 : 1;
62 hclk = fclk / hdiv;
63
64 if (hclk > cfg->max.hclk) {
65 s3c_freq_dbg("%s: hclk too big\n", __func__);
66 return -EINVAL;
67 }
68
69 pdiv = (hclk > cfg->max.pclk) ? 2 : 1;
70 pclk = hclk / pdiv;
71
72 if (pclk > cfg->max.pclk) {
73 s3c_freq_dbg("%s: pclk too big\n", __func__);
74 return -EINVAL;
75 }
76
77 pdiv *= hdiv;
78
79 /* record the result */
80 cfg->divs.p_divisor = pdiv;
81 cfg->divs.h_divisor = hdiv;
82
83 return 0;
84}
85
86static struct s3c_cpufreq_info s3c2410_cpufreq_info = {
87 .max = {
88 .fclk = 200000000,
89 .hclk = 100000000,
90 .pclk = 50000000,
91 },
92
93 /* transition latency is about 5ms worst-case, so
94 * set 10ms to be sure */
95 .latency = 10000000,
96
97 .locktime_m = 150,
98 .locktime_u = 150,
99 .locktime_bits = 12,
100
101 .need_pll = 1,
102
103 .name = "s3c2410",
104 .calc_iotiming = s3c2410_iotiming_calc,
105 .set_iotiming = s3c2410_iotiming_set,
106 .get_iotiming = s3c2410_iotiming_get,
107 .resume_clocks = s3c2410_setup_clocks,
108
109 .set_fvco = s3c2410_set_fvco,
110 .set_refresh = s3c2410_cpufreq_setrefresh,
111 .set_divs = s3c2410_cpufreq_setdivs,
112 .calc_divs = s3c2410_cpufreq_calcdivs,
113
114 .debug_io_show = s3c_cpufreq_debugfs_call(s3c2410_iotiming_debugfs),
115};
116
117static int s3c2410_cpufreq_add(struct device *dev,
118 struct subsys_interface *sif)
119{
120 return s3c_cpufreq_register(&s3c2410_cpufreq_info);
121}
122
123static struct subsys_interface s3c2410_cpufreq_interface = {
124 .name = "s3c2410_cpufreq",
125 .subsys = &s3c2410_subsys,
126 .add_dev = s3c2410_cpufreq_add,
127};
128
129static int __init s3c2410_cpufreq_init(void)
130{
131 return subsys_interface_register(&s3c2410_cpufreq_interface);
132}
133arch_initcall(s3c2410_cpufreq_init);
134
135static int s3c2410a_cpufreq_add(struct device *dev,
136 struct subsys_interface *sif)
137{
138 /* alter the maximum freq settings for S3C2410A. If a board knows
139 * it only has a maximum of 200, then it should register its own
140 * limits. */
141
142 s3c2410_cpufreq_info.max.fclk = 266000000;
143 s3c2410_cpufreq_info.max.hclk = 133000000;
144 s3c2410_cpufreq_info.max.pclk = 66500000;
145 s3c2410_cpufreq_info.name = "s3c2410a";
146
147 return s3c2410_cpufreq_add(dev, sif);
148}
149
150static struct subsys_interface s3c2410a_cpufreq_interface = {
151 .name = "s3c2410a_cpufreq",
152 .subsys = &s3c2410a_subsys,
153 .add_dev = s3c2410a_cpufreq_add,
154};
155
156static int __init s3c2410a_cpufreq_init(void)
157{
158 return subsys_interface_register(&s3c2410a_cpufreq_interface);
159}
160arch_initcall(s3c2410a_cpufreq_init);
diff --git a/arch/arm/mach-s3c24xx/cpufreq-s3c2412.c b/arch/arm/mach-s3c24xx/cpufreq-s3c2412.c
deleted file mode 100644
index 8bf0f3a77476..000000000000
--- a/arch/arm/mach-s3c24xx/cpufreq-s3c2412.c
+++ /dev/null
@@ -1,258 +0,0 @@
1/*
2 * Copyright 2008 Simtec Electronics
3 * http://armlinux.simtec.co.uk/
4 * Ben Dooks <ben@simtec.co.uk>
5 *
6 * S3C2412 CPU Frequency scalling
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#include <linux/init.h>
14#include <linux/module.h>
15#include <linux/interrupt.h>
16#include <linux/ioport.h>
17#include <linux/cpufreq.h>
18#include <linux/device.h>
19#include <linux/delay.h>
20#include <linux/clk.h>
21#include <linux/err.h>
22#include <linux/io.h>
23
24#include <asm/mach/arch.h>
25#include <asm/mach/map.h>
26
27#include <mach/regs-clock.h>
28
29#include <plat/cpu.h>
30#include <plat/clock.h>
31#include <plat/cpu-freq-core.h>
32
33#include "s3c2412.h"
34
35/* our clock resources. */
36static struct clk *xtal;
37static struct clk *fclk;
38static struct clk *hclk;
39static struct clk *armclk;
40
41/* HDIV: 1, 2, 3, 4, 6, 8 */
42
43static int s3c2412_cpufreq_calcdivs(struct s3c_cpufreq_config *cfg)
44{
45 unsigned int hdiv, pdiv, armdiv, dvs;
46 unsigned long hclk, fclk, armclk, armdiv_clk;
47 unsigned long hclk_max;
48
49 fclk = cfg->freq.fclk;
50 armclk = cfg->freq.armclk;
51 hclk_max = cfg->max.hclk;
52
53 /* We can't run hclk above armclk as at the best we have to
54 * have armclk and hclk in dvs mode. */
55
56 if (hclk_max > armclk)
57 hclk_max = armclk;
58
59 s3c_freq_dbg("%s: fclk=%lu, armclk=%lu, hclk_max=%lu\n",
60 __func__, fclk, armclk, hclk_max);
61 s3c_freq_dbg("%s: want f=%lu, arm=%lu, h=%lu, p=%lu\n",
62 __func__, cfg->freq.fclk, cfg->freq.armclk,
63 cfg->freq.hclk, cfg->freq.pclk);
64
65 armdiv = fclk / armclk;
66
67 if (armdiv < 1)
68 armdiv = 1;
69 if (armdiv > 2)
70 armdiv = 2;
71
72 cfg->divs.arm_divisor = armdiv;
73 armdiv_clk = fclk / armdiv;
74
75 hdiv = armdiv_clk / hclk_max;
76 if (hdiv < 1)
77 hdiv = 1;
78
79 cfg->freq.hclk = hclk = armdiv_clk / hdiv;
80
81 /* set dvs depending on whether we reached armclk or not. */
82 cfg->divs.dvs = dvs = armclk < armdiv_clk;
83
84 /* update the actual armclk we achieved. */
85 cfg->freq.armclk = dvs ? hclk : armdiv_clk;
86
87 s3c_freq_dbg("%s: armclk %lu, hclk %lu, armdiv %d, hdiv %d, dvs %d\n",
88 __func__, armclk, hclk, armdiv, hdiv, cfg->divs.dvs);
89
90 if (hdiv > 4)
91 goto invalid;
92
93 pdiv = (hclk > cfg->max.pclk) ? 2 : 1;
94
95 if ((hclk / pdiv) > cfg->max.pclk)
96 pdiv++;
97
98 cfg->freq.pclk = hclk / pdiv;
99
100 s3c_freq_dbg("%s: pdiv %d\n", __func__, pdiv);
101
102 if (pdiv > 2)
103 goto invalid;
104
105 pdiv *= hdiv;
106
107 /* store the result, and then return */
108
109 cfg->divs.h_divisor = hdiv * armdiv;
110 cfg->divs.p_divisor = pdiv * armdiv;
111
112 return 0;
113
114invalid:
115 return -EINVAL;
116}
117
118static void s3c2412_cpufreq_setdivs(struct s3c_cpufreq_config *cfg)
119{
120 unsigned long clkdiv;
121 unsigned long olddiv;
122
123 olddiv = clkdiv = __raw_readl(S3C2410_CLKDIVN);
124
125 /* clear off current clock info */
126
127 clkdiv &= ~S3C2412_CLKDIVN_ARMDIVN;
128 clkdiv &= ~S3C2412_CLKDIVN_HDIVN_MASK;
129 clkdiv &= ~S3C2412_CLKDIVN_PDIVN;
130
131 if (cfg->divs.arm_divisor == 2)
132 clkdiv |= S3C2412_CLKDIVN_ARMDIVN;
133
134 clkdiv |= ((cfg->divs.h_divisor / cfg->divs.arm_divisor) - 1);
135
136 if (cfg->divs.p_divisor != cfg->divs.h_divisor)
137 clkdiv |= S3C2412_CLKDIVN_PDIVN;
138
139 s3c_freq_dbg("%s: div %08lx => %08lx\n", __func__, olddiv, clkdiv);
140 __raw_writel(clkdiv, S3C2410_CLKDIVN);
141
142 clk_set_parent(armclk, cfg->divs.dvs ? hclk : fclk);
143}
144
145static void s3c2412_cpufreq_setrefresh(struct s3c_cpufreq_config *cfg)
146{
147 struct s3c_cpufreq_board *board = cfg->board;
148 unsigned long refresh;
149
150 s3c_freq_dbg("%s: refresh %u ns, hclk %lu\n", __func__,
151 board->refresh, cfg->freq.hclk);
152
153 /* Reduce both the refresh time (in ns) and the frequency (in MHz)
154 * by 10 each to ensure that we do not overflow 32 bit numbers. This
155 * should work for HCLK up to 133MHz and refresh period up to 30usec.
156 */
157
158 refresh = (board->refresh / 10);
159 refresh *= (cfg->freq.hclk / 100);
160 refresh /= (1 * 1000 * 1000); /* 10^6 */
161
162 s3c_freq_dbg("%s: setting refresh 0x%08lx\n", __func__, refresh);
163 __raw_writel(refresh, S3C2412_REFRESH);
164}
165
166/* set the default cpu frequency information, based on an 200MHz part
167 * as we have no other way of detecting the speed rating in software.
168 */
169
170static struct s3c_cpufreq_info s3c2412_cpufreq_info = {
171 .max = {
172 .fclk = 200000000,
173 .hclk = 100000000,
174 .pclk = 50000000,
175 },
176
177 .latency = 5000000, /* 5ms */
178
179 .locktime_m = 150,
180 .locktime_u = 150,
181 .locktime_bits = 16,
182
183 .name = "s3c2412",
184 .set_refresh = s3c2412_cpufreq_setrefresh,
185 .set_divs = s3c2412_cpufreq_setdivs,
186 .calc_divs = s3c2412_cpufreq_calcdivs,
187
188 .calc_iotiming = s3c2412_iotiming_calc,
189 .set_iotiming = s3c2412_iotiming_set,
190 .get_iotiming = s3c2412_iotiming_get,
191
192 .resume_clocks = s3c2412_setup_clocks,
193
194 .debug_io_show = s3c_cpufreq_debugfs_call(s3c2412_iotiming_debugfs),
195};
196
197static int s3c2412_cpufreq_add(struct device *dev,
198 struct subsys_interface *sif)
199{
200 unsigned long fclk_rate;
201
202 hclk = clk_get(NULL, "hclk");
203 if (IS_ERR(hclk)) {
204 printk(KERN_ERR "%s: cannot find hclk clock\n", __func__);
205 return -ENOENT;
206 }
207
208 fclk = clk_get(NULL, "fclk");
209 if (IS_ERR(fclk)) {
210 printk(KERN_ERR "%s: cannot find fclk clock\n", __func__);
211 goto err_fclk;
212 }
213
214 fclk_rate = clk_get_rate(fclk);
215 if (fclk_rate > 200000000) {
216 printk(KERN_INFO
217 "%s: fclk %ld MHz, assuming 266MHz capable part\n",
218 __func__, fclk_rate / 1000000);
219 s3c2412_cpufreq_info.max.fclk = 266000000;
220 s3c2412_cpufreq_info.max.hclk = 133000000;
221 s3c2412_cpufreq_info.max.pclk = 66000000;
222 }
223
224 armclk = clk_get(NULL, "armclk");
225 if (IS_ERR(armclk)) {
226 printk(KERN_ERR "%s: cannot find arm clock\n", __func__);
227 goto err_armclk;
228 }
229
230 xtal = clk_get(NULL, "xtal");
231 if (IS_ERR(xtal)) {
232 printk(KERN_ERR "%s: cannot find xtal clock\n", __func__);
233 goto err_xtal;
234 }
235
236 return s3c_cpufreq_register(&s3c2412_cpufreq_info);
237
238err_xtal:
239 clk_put(armclk);
240err_armclk:
241 clk_put(fclk);
242err_fclk:
243 clk_put(hclk);
244
245 return -ENOENT;
246}
247
248static struct subsys_interface s3c2412_cpufreq_interface = {
249 .name = "s3c2412_cpufreq",
250 .subsys = &s3c2412_subsys,
251 .add_dev = s3c2412_cpufreq_add,
252};
253
254static int s3c2412_cpufreq_init(void)
255{
256 return subsys_interface_register(&s3c2412_cpufreq_interface);
257}
258arch_initcall(s3c2412_cpufreq_init);
diff --git a/arch/arm/mach-s3c24xx/cpufreq-s3c2440.c b/arch/arm/mach-s3c24xx/cpufreq-s3c2440.c
deleted file mode 100644
index 72b2cc8a5a85..000000000000
--- a/arch/arm/mach-s3c24xx/cpufreq-s3c2440.c
+++ /dev/null
@@ -1,312 +0,0 @@
1/*
2 * Copyright (c) 2006-2009 Simtec Electronics
3 * http://armlinux.simtec.co.uk/
4 * Ben Dooks <ben@simtec.co.uk>
5 * Vincent Sanders <vince@simtec.co.uk>
6 *
7 * S3C2440/S3C2442 CPU Frequency scaling
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12*/
13
14#include <linux/init.h>
15#include <linux/module.h>
16#include <linux/interrupt.h>
17#include <linux/ioport.h>
18#include <linux/cpufreq.h>
19#include <linux/device.h>
20#include <linux/delay.h>
21#include <linux/clk.h>
22#include <linux/err.h>
23#include <linux/io.h>
24
25#include <mach/hardware.h>
26
27#include <asm/mach/arch.h>
28#include <asm/mach/map.h>
29
30#include <mach/regs-clock.h>
31
32#include <plat/cpu.h>
33#include <plat/cpu-freq-core.h>
34#include <plat/clock.h>
35
36static struct clk *xtal;
37static struct clk *fclk;
38static struct clk *hclk;
39static struct clk *armclk;
40
41/* HDIV: 1, 2, 3, 4, 6, 8 */
42
43static inline int within_khz(unsigned long a, unsigned long b)
44{
45 long diff = a - b;
46
47 return (diff >= -1000 && diff <= 1000);
48}
49
50/**
51 * s3c2440_cpufreq_calcdivs - calculate divider settings
52 * @cfg: The cpu frequency settings.
53 *
54 * Calcualte the divider values for the given frequency settings
55 * specified in @cfg. The values are stored in @cfg for later use
56 * by the relevant set routine if the request settings can be reached.
57 */
58int s3c2440_cpufreq_calcdivs(struct s3c_cpufreq_config *cfg)
59{
60 unsigned int hdiv, pdiv;
61 unsigned long hclk, fclk, armclk;
62 unsigned long hclk_max;
63
64 fclk = cfg->freq.fclk;
65 armclk = cfg->freq.armclk;
66 hclk_max = cfg->max.hclk;
67
68 s3c_freq_dbg("%s: fclk is %lu, armclk %lu, max hclk %lu\n",
69 __func__, fclk, armclk, hclk_max);
70
71 if (armclk > fclk) {
72 printk(KERN_WARNING "%s: armclk > fclk\n", __func__);
73 armclk = fclk;
74 }
75
76 /* if we are in DVS, we need HCLK to be <= ARMCLK */
77 if (armclk < fclk && armclk < hclk_max)
78 hclk_max = armclk;
79
80 for (hdiv = 1; hdiv < 9; hdiv++) {
81 if (hdiv == 5 || hdiv == 7)
82 hdiv++;
83
84 hclk = (fclk / hdiv);
85 if (hclk <= hclk_max || within_khz(hclk, hclk_max))
86 break;
87 }
88
89 s3c_freq_dbg("%s: hclk %lu, div %d\n", __func__, hclk, hdiv);
90
91 if (hdiv > 8)
92 goto invalid;
93
94 pdiv = (hclk > cfg->max.pclk) ? 2 : 1;
95
96 if ((hclk / pdiv) > cfg->max.pclk)
97 pdiv++;
98
99 s3c_freq_dbg("%s: pdiv %d\n", __func__, pdiv);
100
101 if (pdiv > 2)
102 goto invalid;
103
104 pdiv *= hdiv;
105
106 /* calculate a valid armclk */
107
108 if (armclk < hclk)
109 armclk = hclk;
110
111 /* if we're running armclk lower than fclk, this really means
112 * that the system should go into dvs mode, which means that
113 * armclk is connected to hclk. */
114 if (armclk < fclk) {
115 cfg->divs.dvs = 1;
116 armclk = hclk;
117 } else
118 cfg->divs.dvs = 0;
119
120 cfg->freq.armclk = armclk;
121
122 /* store the result, and then return */
123
124 cfg->divs.h_divisor = hdiv;
125 cfg->divs.p_divisor = pdiv;
126
127 return 0;
128
129 invalid:
130 return -EINVAL;
131}
132
133#define CAMDIVN_HCLK_HALF (S3C2440_CAMDIVN_HCLK3_HALF | \
134 S3C2440_CAMDIVN_HCLK4_HALF)
135
136/**
137 * s3c2440_cpufreq_setdivs - set the cpu frequency divider settings
138 * @cfg: The cpu frequency settings.
139 *
140 * Set the divisors from the settings in @cfg, which where generated
141 * during the calculation phase by s3c2440_cpufreq_calcdivs().
142 */
143static void s3c2440_cpufreq_setdivs(struct s3c_cpufreq_config *cfg)
144{
145 unsigned long clkdiv, camdiv;
146
147 s3c_freq_dbg("%s: divsiors: h=%d, p=%d\n", __func__,
148 cfg->divs.h_divisor, cfg->divs.p_divisor);
149
150 clkdiv = __raw_readl(S3C2410_CLKDIVN);
151 camdiv = __raw_readl(S3C2440_CAMDIVN);
152
153 clkdiv &= ~(S3C2440_CLKDIVN_HDIVN_MASK | S3C2440_CLKDIVN_PDIVN);
154 camdiv &= ~CAMDIVN_HCLK_HALF;
155
156 switch (cfg->divs.h_divisor) {
157 case 1:
158 clkdiv |= S3C2440_CLKDIVN_HDIVN_1;
159 break;
160
161 case 2:
162 clkdiv |= S3C2440_CLKDIVN_HDIVN_2;
163 break;
164
165 case 6:
166 camdiv |= S3C2440_CAMDIVN_HCLK3_HALF;
167 case 3:
168 clkdiv |= S3C2440_CLKDIVN_HDIVN_3_6;
169 break;
170
171 case 8:
172 camdiv |= S3C2440_CAMDIVN_HCLK4_HALF;
173 case 4:
174 clkdiv |= S3C2440_CLKDIVN_HDIVN_4_8;
175 break;
176
177 default:
178 BUG(); /* we don't expect to get here. */
179 }
180
181 if (cfg->divs.p_divisor != cfg->divs.h_divisor)
182 clkdiv |= S3C2440_CLKDIVN_PDIVN;
183
184 /* todo - set pclk. */
185
186 /* Write the divisors first with hclk intentionally halved so that
187 * when we write clkdiv we will under-frequency instead of over. We
188 * then make a short delay and remove the hclk halving if necessary.
189 */
190
191 __raw_writel(camdiv | CAMDIVN_HCLK_HALF, S3C2440_CAMDIVN);
192 __raw_writel(clkdiv, S3C2410_CLKDIVN);
193
194 ndelay(20);
195 __raw_writel(camdiv, S3C2440_CAMDIVN);
196
197 clk_set_parent(armclk, cfg->divs.dvs ? hclk : fclk);
198}
199
200static int run_freq_for(unsigned long max_hclk, unsigned long fclk,
201 int *divs,
202 struct cpufreq_frequency_table *table,
203 size_t table_size)
204{
205 unsigned long freq;
206 int index = 0;
207 int div;
208
209 for (div = *divs; div > 0; div = *divs++) {
210 freq = fclk / div;
211
212 if (freq > max_hclk && div != 1)
213 continue;
214
215 freq /= 1000; /* table is in kHz */
216 index = s3c_cpufreq_addfreq(table, index, table_size, freq);
217 if (index < 0)
218 break;
219 }
220
221 return index;
222}
223
224static int hclk_divs[] = { 1, 2, 3, 4, 6, 8, -1 };
225
226static int s3c2440_cpufreq_calctable(struct s3c_cpufreq_config *cfg,
227 struct cpufreq_frequency_table *table,
228 size_t table_size)
229{
230 int ret;
231
232 WARN_ON(cfg->info == NULL);
233 WARN_ON(cfg->board == NULL);
234
235 ret = run_freq_for(cfg->info->max.hclk,
236 cfg->info->max.fclk,
237 hclk_divs,
238 table, table_size);
239
240 s3c_freq_dbg("%s: returning %d\n", __func__, ret);
241
242 return ret;
243}
244
245struct s3c_cpufreq_info s3c2440_cpufreq_info = {
246 .max = {
247 .fclk = 400000000,
248 .hclk = 133333333,
249 .pclk = 66666666,
250 },
251
252 .locktime_m = 300,
253 .locktime_u = 300,
254 .locktime_bits = 16,
255
256 .name = "s3c244x",
257 .calc_iotiming = s3c2410_iotiming_calc,
258 .set_iotiming = s3c2410_iotiming_set,
259 .get_iotiming = s3c2410_iotiming_get,
260 .set_fvco = s3c2410_set_fvco,
261
262 .set_refresh = s3c2410_cpufreq_setrefresh,
263 .set_divs = s3c2440_cpufreq_setdivs,
264 .calc_divs = s3c2440_cpufreq_calcdivs,
265 .calc_freqtable = s3c2440_cpufreq_calctable,
266
267 .resume_clocks = s3c244x_setup_clocks,
268
269 .debug_io_show = s3c_cpufreq_debugfs_call(s3c2410_iotiming_debugfs),
270};
271
272static int s3c2440_cpufreq_add(struct device *dev,
273 struct subsys_interface *sif)
274{
275 xtal = s3c_cpufreq_clk_get(NULL, "xtal");
276 hclk = s3c_cpufreq_clk_get(NULL, "hclk");
277 fclk = s3c_cpufreq_clk_get(NULL, "fclk");
278 armclk = s3c_cpufreq_clk_get(NULL, "armclk");
279
280 if (IS_ERR(xtal) || IS_ERR(hclk) || IS_ERR(fclk) || IS_ERR(armclk)) {
281 printk(KERN_ERR "%s: failed to get clocks\n", __func__);
282 return -ENOENT;
283 }
284
285 return s3c_cpufreq_register(&s3c2440_cpufreq_info);
286}
287
288static struct subsys_interface s3c2440_cpufreq_interface = {
289 .name = "s3c2440_cpufreq",
290 .subsys = &s3c2440_subsys,
291 .add_dev = s3c2440_cpufreq_add,
292};
293
294static int s3c2440_cpufreq_init(void)
295{
296 return subsys_interface_register(&s3c2440_cpufreq_interface);
297}
298
299/* arch_initcall adds the clocks we need, so use subsys_initcall. */
300subsys_initcall(s3c2440_cpufreq_init);
301
302static struct subsys_interface s3c2442_cpufreq_interface = {
303 .name = "s3c2442_cpufreq",
304 .subsys = &s3c2442_subsys,
305 .add_dev = s3c2440_cpufreq_add,
306};
307
308static int s3c2442_cpufreq_init(void)
309{
310 return subsys_interface_register(&s3c2442_cpufreq_interface);
311}
312subsys_initcall(s3c2442_cpufreq_init);
diff --git a/arch/arm/mach-s3c24xx/cpufreq.c b/arch/arm/mach-s3c24xx/cpufreq.c
deleted file mode 100644
index 3c0e78ede0da..000000000000
--- a/arch/arm/mach-s3c24xx/cpufreq.c
+++ /dev/null
@@ -1,711 +0,0 @@
1/*
2 * Copyright (c) 2006-2008 Simtec Electronics
3 * http://armlinux.simtec.co.uk/
4 * Ben Dooks <ben@simtec.co.uk>
5 *
6 * S3C24XX CPU Frequency scaling
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#include <linux/init.h>
14#include <linux/module.h>
15#include <linux/interrupt.h>
16#include <linux/ioport.h>
17#include <linux/cpufreq.h>
18#include <linux/cpu.h>
19#include <linux/clk.h>
20#include <linux/err.h>
21#include <linux/io.h>
22#include <linux/device.h>
23#include <linux/sysfs.h>
24#include <linux/slab.h>
25
26#include <asm/mach/arch.h>
27#include <asm/mach/map.h>
28
29#include <plat/cpu.h>
30#include <plat/clock.h>
31#include <plat/cpu-freq-core.h>
32
33#include <mach/regs-clock.h>
34
35/* note, cpufreq support deals in kHz, no Hz */
36
37static struct cpufreq_driver s3c24xx_driver;
38static struct s3c_cpufreq_config cpu_cur;
39static struct s3c_iotimings s3c24xx_iotiming;
40static struct cpufreq_frequency_table *pll_reg;
41static unsigned int last_target = ~0;
42static unsigned int ftab_size;
43static struct cpufreq_frequency_table *ftab;
44
45static struct clk *_clk_mpll;
46static struct clk *_clk_xtal;
47static struct clk *clk_fclk;
48static struct clk *clk_hclk;
49static struct clk *clk_pclk;
50static struct clk *clk_arm;
51
52#ifdef CONFIG_CPU_FREQ_S3C24XX_DEBUGFS
53struct s3c_cpufreq_config *s3c_cpufreq_getconfig(void)
54{
55 return &cpu_cur;
56}
57
58struct s3c_iotimings *s3c_cpufreq_getiotimings(void)
59{
60 return &s3c24xx_iotiming;
61}
62#endif /* CONFIG_CPU_FREQ_S3C24XX_DEBUGFS */
63
64static void s3c_cpufreq_getcur(struct s3c_cpufreq_config *cfg)
65{
66 unsigned long fclk, pclk, hclk, armclk;
67
68 cfg->freq.fclk = fclk = clk_get_rate(clk_fclk);
69 cfg->freq.hclk = hclk = clk_get_rate(clk_hclk);
70 cfg->freq.pclk = pclk = clk_get_rate(clk_pclk);
71 cfg->freq.armclk = armclk = clk_get_rate(clk_arm);
72
73 cfg->pll.index = __raw_readl(S3C2410_MPLLCON);
74 cfg->pll.frequency = fclk;
75
76 cfg->freq.hclk_tns = 1000000000 / (cfg->freq.hclk / 10);
77
78 cfg->divs.h_divisor = fclk / hclk;
79 cfg->divs.p_divisor = fclk / pclk;
80}
81
82static inline void s3c_cpufreq_calc(struct s3c_cpufreq_config *cfg)
83{
84 unsigned long pll = cfg->pll.frequency;
85
86 cfg->freq.fclk = pll;
87 cfg->freq.hclk = pll / cfg->divs.h_divisor;
88 cfg->freq.pclk = pll / cfg->divs.p_divisor;
89
90 /* convert hclk into 10ths of nanoseconds for io calcs */
91 cfg->freq.hclk_tns = 1000000000 / (cfg->freq.hclk / 10);
92}
93
94static inline int closer(unsigned int target, unsigned int n, unsigned int c)
95{
96 int diff_cur = abs(target - c);
97 int diff_new = abs(target - n);
98
99 return (diff_new < diff_cur);
100}
101
102static void s3c_cpufreq_show(const char *pfx,
103 struct s3c_cpufreq_config *cfg)
104{
105 s3c_freq_dbg("%s: Fvco=%u, F=%lu, A=%lu, H=%lu (%u), P=%lu (%u)\n",
106 pfx, cfg->pll.frequency, cfg->freq.fclk, cfg->freq.armclk,
107 cfg->freq.hclk, cfg->divs.h_divisor,
108 cfg->freq.pclk, cfg->divs.p_divisor);
109}
110
111/* functions to wrapper the driver info calls to do the cpu specific work */
112
113static void s3c_cpufreq_setio(struct s3c_cpufreq_config *cfg)
114{
115 if (cfg->info->set_iotiming)
116 (cfg->info->set_iotiming)(cfg, &s3c24xx_iotiming);
117}
118
119static int s3c_cpufreq_calcio(struct s3c_cpufreq_config *cfg)
120{
121 if (cfg->info->calc_iotiming)
122 return (cfg->info->calc_iotiming)(cfg, &s3c24xx_iotiming);
123
124 return 0;
125}
126
127static void s3c_cpufreq_setrefresh(struct s3c_cpufreq_config *cfg)
128{
129 (cfg->info->set_refresh)(cfg);
130}
131
132static void s3c_cpufreq_setdivs(struct s3c_cpufreq_config *cfg)
133{
134 (cfg->info->set_divs)(cfg);
135}
136
137static int s3c_cpufreq_calcdivs(struct s3c_cpufreq_config *cfg)
138{
139 return (cfg->info->calc_divs)(cfg);
140}
141
142static void s3c_cpufreq_setfvco(struct s3c_cpufreq_config *cfg)
143{
144 (cfg->info->set_fvco)(cfg);
145}
146
147static inline void s3c_cpufreq_resume_clocks(void)
148{
149 cpu_cur.info->resume_clocks();
150}
151
152static inline void s3c_cpufreq_updateclk(struct clk *clk,
153 unsigned int freq)
154{
155 clk_set_rate(clk, freq);
156}
157
158static int s3c_cpufreq_settarget(struct cpufreq_policy *policy,
159 unsigned int target_freq,
160 struct cpufreq_frequency_table *pll)
161{
162 struct s3c_cpufreq_freqs freqs;
163 struct s3c_cpufreq_config cpu_new;
164 unsigned long flags;
165
166 cpu_new = cpu_cur; /* copy new from current */
167
168 s3c_cpufreq_show("cur", &cpu_cur);
169
170 /* TODO - check for DMA currently outstanding */
171
172 cpu_new.pll = pll ? *pll : cpu_cur.pll;
173
174 if (pll)
175 freqs.pll_changing = 1;
176
177 /* update our frequencies */
178
179 cpu_new.freq.armclk = target_freq;
180 cpu_new.freq.fclk = cpu_new.pll.frequency;
181
182 if (s3c_cpufreq_calcdivs(&cpu_new) < 0) {
183 printk(KERN_ERR "no divisors for %d\n", target_freq);
184 goto err_notpossible;
185 }
186
187 s3c_freq_dbg("%s: got divs\n", __func__);
188
189 s3c_cpufreq_calc(&cpu_new);
190
191 s3c_freq_dbg("%s: calculated frequencies for new\n", __func__);
192
193 if (cpu_new.freq.hclk != cpu_cur.freq.hclk) {
194 if (s3c_cpufreq_calcio(&cpu_new) < 0) {
195 printk(KERN_ERR "%s: no IO timings\n", __func__);
196 goto err_notpossible;
197 }
198 }
199
200 s3c_cpufreq_show("new", &cpu_new);
201
202 /* setup our cpufreq parameters */
203
204 freqs.old = cpu_cur.freq;
205 freqs.new = cpu_new.freq;
206
207 freqs.freqs.old = cpu_cur.freq.armclk / 1000;
208 freqs.freqs.new = cpu_new.freq.armclk / 1000;
209
210 /* update f/h/p clock settings before we issue the change
211 * notification, so that drivers do not need to do anything
212 * special if they want to recalculate on CPUFREQ_PRECHANGE. */
213
214 s3c_cpufreq_updateclk(_clk_mpll, cpu_new.pll.frequency);
215 s3c_cpufreq_updateclk(clk_fclk, cpu_new.freq.fclk);
216 s3c_cpufreq_updateclk(clk_hclk, cpu_new.freq.hclk);
217 s3c_cpufreq_updateclk(clk_pclk, cpu_new.freq.pclk);
218
219 /* start the frequency change */
220 cpufreq_notify_transition(policy, &freqs.freqs, CPUFREQ_PRECHANGE);
221
222 /* If hclk is staying the same, then we do not need to
223 * re-write the IO or the refresh timings whilst we are changing
224 * speed. */
225
226 local_irq_save(flags);
227
228 /* is our memory clock slowing down? */
229 if (cpu_new.freq.hclk < cpu_cur.freq.hclk) {
230 s3c_cpufreq_setrefresh(&cpu_new);
231 s3c_cpufreq_setio(&cpu_new);
232 }
233
234 if (cpu_new.freq.fclk == cpu_cur.freq.fclk) {
235 /* not changing PLL, just set the divisors */
236
237 s3c_cpufreq_setdivs(&cpu_new);
238 } else {
239 if (cpu_new.freq.fclk < cpu_cur.freq.fclk) {
240 /* slow the cpu down, then set divisors */
241
242 s3c_cpufreq_setfvco(&cpu_new);
243 s3c_cpufreq_setdivs(&cpu_new);
244 } else {
245 /* set the divisors, then speed up */
246
247 s3c_cpufreq_setdivs(&cpu_new);
248 s3c_cpufreq_setfvco(&cpu_new);
249 }
250 }
251
252 /* did our memory clock speed up */
253 if (cpu_new.freq.hclk > cpu_cur.freq.hclk) {
254 s3c_cpufreq_setrefresh(&cpu_new);
255 s3c_cpufreq_setio(&cpu_new);
256 }
257
258 /* update our current settings */
259 cpu_cur = cpu_new;
260
261 local_irq_restore(flags);
262
263 /* notify everyone we've done this */
264 cpufreq_notify_transition(policy, &freqs.freqs, CPUFREQ_POSTCHANGE);
265
266 s3c_freq_dbg("%s: finished\n", __func__);
267 return 0;
268
269 err_notpossible:
270 printk(KERN_ERR "no compatible settings for %d\n", target_freq);
271 return -EINVAL;
272}
273
274/* s3c_cpufreq_target
275 *
276 * called by the cpufreq core to adjust the frequency that the CPU
277 * is currently running at.
278 */
279
280static int s3c_cpufreq_target(struct cpufreq_policy *policy,
281 unsigned int target_freq,
282 unsigned int relation)
283{
284 struct cpufreq_frequency_table *pll;
285 unsigned int index;
286
287 /* avoid repeated calls which cause a needless amout of duplicated
288 * logging output (and CPU time as the calculation process is
289 * done) */
290 if (target_freq == last_target)
291 return 0;
292
293 last_target = target_freq;
294
295 s3c_freq_dbg("%s: policy %p, target %u, relation %u\n",
296 __func__, policy, target_freq, relation);
297
298 if (ftab) {
299 if (cpufreq_frequency_table_target(policy, ftab,
300 target_freq, relation,
301 &index)) {
302 s3c_freq_dbg("%s: table failed\n", __func__);
303 return -EINVAL;
304 }
305
306 s3c_freq_dbg("%s: adjust %d to entry %d (%u)\n", __func__,
307 target_freq, index, ftab[index].frequency);
308 target_freq = ftab[index].frequency;
309 }
310
311 target_freq *= 1000; /* convert target to Hz */
312
313 /* find the settings for our new frequency */
314
315 if (!pll_reg || cpu_cur.lock_pll) {
316 /* either we've not got any PLL values, or we've locked
317 * to the current one. */
318 pll = NULL;
319 } else {
320 struct cpufreq_policy tmp_policy;
321 int ret;
322
323 /* we keep the cpu pll table in Hz, to ensure we get an
324 * accurate value for the PLL output. */
325
326 tmp_policy.min = policy->min * 1000;
327 tmp_policy.max = policy->max * 1000;
328 tmp_policy.cpu = policy->cpu;
329
330 /* cpufreq_frequency_table_target uses a pointer to 'index'
331 * which is the number of the table entry, not the value of
332 * the table entry's index field. */
333
334 ret = cpufreq_frequency_table_target(&tmp_policy, pll_reg,
335 target_freq, relation,
336 &index);
337
338 if (ret < 0) {
339 printk(KERN_ERR "%s: no PLL available\n", __func__);
340 goto err_notpossible;
341 }
342
343 pll = pll_reg + index;
344
345 s3c_freq_dbg("%s: target %u => %u\n",
346 __func__, target_freq, pll->frequency);
347
348 target_freq = pll->frequency;
349 }
350
351 return s3c_cpufreq_settarget(policy, target_freq, pll);
352
353 err_notpossible:
354 printk(KERN_ERR "no compatible settings for %d\n", target_freq);
355 return -EINVAL;
356}
357
358static unsigned int s3c_cpufreq_get(unsigned int cpu)
359{
360 return clk_get_rate(clk_arm) / 1000;
361}
362
363struct clk *s3c_cpufreq_clk_get(struct device *dev, const char *name)
364{
365 struct clk *clk;
366
367 clk = clk_get(dev, name);
368 if (IS_ERR(clk))
369 printk(KERN_ERR "cpufreq: failed to get clock '%s'\n", name);
370
371 return clk;
372}
373
374static int s3c_cpufreq_init(struct cpufreq_policy *policy)
375{
376 printk(KERN_INFO "%s: initialising policy %p\n", __func__, policy);
377
378 if (policy->cpu != 0)
379 return -EINVAL;
380
381 policy->cur = s3c_cpufreq_get(0);
382 policy->min = policy->cpuinfo.min_freq = 0;
383 policy->max = policy->cpuinfo.max_freq = cpu_cur.info->max.fclk / 1000;
384 policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
385
386 /* feed the latency information from the cpu driver */
387 policy->cpuinfo.transition_latency = cpu_cur.info->latency;
388
389 if (ftab)
390 cpufreq_frequency_table_cpuinfo(policy, ftab);
391
392 return 0;
393}
394
395static __init int s3c_cpufreq_initclks(void)
396{
397 _clk_mpll = s3c_cpufreq_clk_get(NULL, "mpll");
398 _clk_xtal = s3c_cpufreq_clk_get(NULL, "xtal");
399 clk_fclk = s3c_cpufreq_clk_get(NULL, "fclk");
400 clk_hclk = s3c_cpufreq_clk_get(NULL, "hclk");
401 clk_pclk = s3c_cpufreq_clk_get(NULL, "pclk");
402 clk_arm = s3c_cpufreq_clk_get(NULL, "armclk");
403
404 if (IS_ERR(clk_fclk) || IS_ERR(clk_hclk) || IS_ERR(clk_pclk) ||
405 IS_ERR(_clk_mpll) || IS_ERR(clk_arm) || IS_ERR(_clk_xtal)) {
406 printk(KERN_ERR "%s: could not get clock(s)\n", __func__);
407 return -ENOENT;
408 }
409
410 printk(KERN_INFO "%s: clocks f=%lu,h=%lu,p=%lu,a=%lu\n", __func__,
411 clk_get_rate(clk_fclk) / 1000,
412 clk_get_rate(clk_hclk) / 1000,
413 clk_get_rate(clk_pclk) / 1000,
414 clk_get_rate(clk_arm) / 1000);
415
416 return 0;
417}
418
419static int s3c_cpufreq_verify(struct cpufreq_policy *policy)
420{
421 if (policy->cpu != 0)
422 return -EINVAL;
423
424 return 0;
425}
426
427#ifdef CONFIG_PM
428static struct cpufreq_frequency_table suspend_pll;
429static unsigned int suspend_freq;
430
431static int s3c_cpufreq_suspend(struct cpufreq_policy *policy)
432{
433 suspend_pll.frequency = clk_get_rate(_clk_mpll);
434 suspend_pll.index = __raw_readl(S3C2410_MPLLCON);
435 suspend_freq = s3c_cpufreq_get(0) * 1000;
436
437 return 0;
438}
439
440static int s3c_cpufreq_resume(struct cpufreq_policy *policy)
441{
442 int ret;
443
444 s3c_freq_dbg("%s: resuming with policy %p\n", __func__, policy);
445
446 last_target = ~0; /* invalidate last_target setting */
447
448 /* first, find out what speed we resumed at. */
449 s3c_cpufreq_resume_clocks();
450
451 /* whilst we will be called later on, we try and re-set the
452 * cpu frequencies as soon as possible so that we do not end
453 * up resuming devices and then immediately having to re-set
454 * a number of settings once these devices have restarted.
455 *
456 * as a note, it is expected devices are not used until they
457 * have been un-suspended and at that time they should have
458 * used the updated clock settings.
459 */
460
461 ret = s3c_cpufreq_settarget(NULL, suspend_freq, &suspend_pll);
462 if (ret) {
463 printk(KERN_ERR "%s: failed to reset pll/freq\n", __func__);
464 return ret;
465 }
466
467 return 0;
468}
469#else
470#define s3c_cpufreq_resume NULL
471#define s3c_cpufreq_suspend NULL
472#endif
473
474static struct cpufreq_driver s3c24xx_driver = {
475 .flags = CPUFREQ_STICKY,
476 .verify = s3c_cpufreq_verify,
477 .target = s3c_cpufreq_target,
478 .get = s3c_cpufreq_get,
479 .init = s3c_cpufreq_init,
480 .suspend = s3c_cpufreq_suspend,
481 .resume = s3c_cpufreq_resume,
482 .name = "s3c24xx",
483};
484
485
486int __init s3c_cpufreq_register(struct s3c_cpufreq_info *info)
487{
488 if (!info || !info->name) {
489 printk(KERN_ERR "%s: failed to pass valid information\n",
490 __func__);
491 return -EINVAL;
492 }
493
494 printk(KERN_INFO "S3C24XX CPU Frequency driver, %s cpu support\n",
495 info->name);
496
497 /* check our driver info has valid data */
498
499 BUG_ON(info->set_refresh == NULL);
500 BUG_ON(info->set_divs == NULL);
501 BUG_ON(info->calc_divs == NULL);
502
503 /* info->set_fvco is optional, depending on whether there
504 * is a need to set the clock code. */
505
506 cpu_cur.info = info;
507
508 /* Note, driver registering should probably update locktime */
509
510 return 0;
511}
512
513int __init s3c_cpufreq_setboard(struct s3c_cpufreq_board *board)
514{
515 struct s3c_cpufreq_board *ours;
516
517 if (!board) {
518 printk(KERN_INFO "%s: no board data\n", __func__);
519 return -EINVAL;
520 }
521
522 /* Copy the board information so that each board can make this
523 * initdata. */
524
525 ours = kzalloc(sizeof(struct s3c_cpufreq_board), GFP_KERNEL);
526 if (ours == NULL) {
527 printk(KERN_ERR "%s: no memory\n", __func__);
528 return -ENOMEM;
529 }
530
531 *ours = *board;
532 cpu_cur.board = ours;
533
534 return 0;
535}
536
537int __init s3c_cpufreq_auto_io(void)
538{
539 int ret;
540
541 if (!cpu_cur.info->get_iotiming) {
542 printk(KERN_ERR "%s: get_iotiming undefined\n", __func__);
543 return -ENOENT;
544 }
545
546 printk(KERN_INFO "%s: working out IO settings\n", __func__);
547
548 ret = (cpu_cur.info->get_iotiming)(&cpu_cur, &s3c24xx_iotiming);
549 if (ret)
550 printk(KERN_ERR "%s: failed to get timings\n", __func__);
551
552 return ret;
553}
554
555/* if one or is zero, then return the other, otherwise return the min */
556#define do_min(_a, _b) ((_a) == 0 ? (_b) : (_b) == 0 ? (_a) : min(_a, _b))
557
558/**
559 * s3c_cpufreq_freq_min - find the minimum settings for the given freq.
560 * @dst: The destination structure
561 * @a: One argument.
562 * @b: The other argument.
563 *
564 * Create a minimum of each frequency entry in the 'struct s3c_freq',
565 * unless the entry is zero when it is ignored and the non-zero argument
566 * used.
567 */
568static void s3c_cpufreq_freq_min(struct s3c_freq *dst,
569 struct s3c_freq *a, struct s3c_freq *b)
570{
571 dst->fclk = do_min(a->fclk, b->fclk);
572 dst->hclk = do_min(a->hclk, b->hclk);
573 dst->pclk = do_min(a->pclk, b->pclk);
574 dst->armclk = do_min(a->armclk, b->armclk);
575}
576
577static inline u32 calc_locktime(u32 freq, u32 time_us)
578{
579 u32 result;
580
581 result = freq * time_us;
582 result = DIV_ROUND_UP(result, 1000 * 1000);
583
584 return result;
585}
586
587static void s3c_cpufreq_update_loctkime(void)
588{
589 unsigned int bits = cpu_cur.info->locktime_bits;
590 u32 rate = (u32)clk_get_rate(_clk_xtal);
591 u32 val;
592
593 if (bits == 0) {
594 WARN_ON(1);
595 return;
596 }
597
598 val = calc_locktime(rate, cpu_cur.info->locktime_u) << bits;
599 val |= calc_locktime(rate, cpu_cur.info->locktime_m);
600
601 printk(KERN_INFO "%s: new locktime is 0x%08x\n", __func__, val);
602 __raw_writel(val, S3C2410_LOCKTIME);
603}
604
605static int s3c_cpufreq_build_freq(void)
606{
607 int size, ret;
608
609 if (!cpu_cur.info->calc_freqtable)
610 return -EINVAL;
611
612 kfree(ftab);
613 ftab = NULL;
614
615 size = cpu_cur.info->calc_freqtable(&cpu_cur, NULL, 0);
616 size++;
617
618 ftab = kmalloc(sizeof(struct cpufreq_frequency_table) * size, GFP_KERNEL);
619 if (!ftab) {
620 printk(KERN_ERR "%s: no memory for tables\n", __func__);
621 return -ENOMEM;
622 }
623
624 ftab_size = size;
625
626 ret = cpu_cur.info->calc_freqtable(&cpu_cur, ftab, size);
627 s3c_cpufreq_addfreq(ftab, ret, size, CPUFREQ_TABLE_END);
628
629 return 0;
630}
631
632static int __init s3c_cpufreq_initcall(void)
633{
634 int ret = 0;
635
636 if (cpu_cur.info && cpu_cur.board) {
637 ret = s3c_cpufreq_initclks();
638 if (ret)
639 goto out;
640
641 /* get current settings */
642 s3c_cpufreq_getcur(&cpu_cur);
643 s3c_cpufreq_show("cur", &cpu_cur);
644
645 if (cpu_cur.board->auto_io) {
646 ret = s3c_cpufreq_auto_io();
647 if (ret) {
648 printk(KERN_ERR "%s: failed to get io timing\n",
649 __func__);
650 goto out;
651 }
652 }
653
654 if (cpu_cur.board->need_io && !cpu_cur.info->set_iotiming) {
655 printk(KERN_ERR "%s: no IO support registered\n",
656 __func__);
657 ret = -EINVAL;
658 goto out;
659 }
660
661 if (!cpu_cur.info->need_pll)
662 cpu_cur.lock_pll = 1;
663
664 s3c_cpufreq_update_loctkime();
665
666 s3c_cpufreq_freq_min(&cpu_cur.max, &cpu_cur.board->max,
667 &cpu_cur.info->max);
668
669 if (cpu_cur.info->calc_freqtable)
670 s3c_cpufreq_build_freq();
671
672 ret = cpufreq_register_driver(&s3c24xx_driver);
673 }
674
675 out:
676 return ret;
677}
678
679late_initcall(s3c_cpufreq_initcall);
680
681/**
682 * s3c_plltab_register - register CPU PLL table.
683 * @plls: The list of PLL entries.
684 * @plls_no: The size of the PLL entries @plls.
685 *
686 * Register the given set of PLLs with the system.
687 */
688int __init s3c_plltab_register(struct cpufreq_frequency_table *plls,
689 unsigned int plls_no)
690{
691 struct cpufreq_frequency_table *vals;
692 unsigned int size;
693
694 size = sizeof(struct cpufreq_frequency_table) * (plls_no + 1);
695
696 vals = kmalloc(size, GFP_KERNEL);
697 if (vals) {
698 memcpy(vals, plls, size);
699 pll_reg = vals;
700
701 /* write a terminating entry, we don't store it in the
702 * table that is stored in the kernel */
703 vals += plls_no;
704 vals->frequency = CPUFREQ_TABLE_END;
705
706 printk(KERN_INFO "cpufreq: %d PLL entries\n", plls_no);
707 } else
708 printk(KERN_ERR "cpufreq: no memory for PLL tables\n");
709
710 return vals ? 0 : -ENOMEM;
711}
diff --git a/arch/arm/mach-s3c24xx/s3c2412.h b/arch/arm/mach-s3c24xx/include/mach/s3c2412.h
index 548ced42cbb7..548ced42cbb7 100644
--- a/arch/arm/mach-s3c24xx/s3c2412.h
+++ b/arch/arm/mach-s3c24xx/include/mach/s3c2412.h
diff --git a/arch/arm/mach-s3c24xx/iotiming-s3c2412.c b/arch/arm/mach-s3c24xx/iotiming-s3c2412.c
index 663436d9db01..bd064c05c473 100644
--- a/arch/arm/mach-s3c24xx/iotiming-s3c2412.c
+++ b/arch/arm/mach-s3c24xx/iotiming-s3c2412.c
@@ -31,7 +31,7 @@
31#include <plat/cpu-freq-core.h> 31#include <plat/cpu-freq-core.h>
32#include <plat/clock.h> 32#include <plat/clock.h>
33 33
34#include "s3c2412.h" 34#include <mach/s3c2412.h>
35 35
36#define print_ns(x) ((x) / 10), ((x) % 10) 36#define print_ns(x) ((x) / 10), ((x) % 10)
37 37
diff --git a/arch/arm/plat-samsung/include/plat/cpu-freq-core.h b/arch/arm/plat-samsung/include/plat/cpu-freq-core.h
index 95509d8eb140..d7e17150028a 100644
--- a/arch/arm/plat-samsung/include/plat/cpu-freq-core.h
+++ b/arch/arm/plat-samsung/include/plat/cpu-freq-core.h
@@ -202,7 +202,7 @@ extern int s3c_plltab_register(struct cpufreq_frequency_table *plls,
202extern struct s3c_cpufreq_config *s3c_cpufreq_getconfig(void); 202extern struct s3c_cpufreq_config *s3c_cpufreq_getconfig(void);
203extern struct s3c_iotimings *s3c_cpufreq_getiotimings(void); 203extern struct s3c_iotimings *s3c_cpufreq_getiotimings(void);
204 204
205#ifdef CONFIG_CPU_FREQ_S3C24XX_DEBUGFS 205#ifdef CONFIG_ARM_S3C24XX_CPUFREQ_DEBUGFS
206#define s3c_cpufreq_debugfs_call(x) x 206#define s3c_cpufreq_debugfs_call(x) x
207#else 207#else
208#define s3c_cpufreq_debugfs_call(x) NULL 208#define s3c_cpufreq_debugfs_call(x) NULL
@@ -259,17 +259,17 @@ extern void s3c2412_iotiming_set(struct s3c_cpufreq_config *cfg,
259#define s3c2412_iotiming_set NULL 259#define s3c2412_iotiming_set NULL
260#endif /* CONFIG_S3C2412_IOTIMING */ 260#endif /* CONFIG_S3C2412_IOTIMING */
261 261
262#ifdef CONFIG_CPU_FREQ_S3C24XX_DEBUG 262#ifdef CONFIG_ARM_S3C24XX_CPUFREQ_DEBUG
263#define s3c_freq_dbg(x...) printk(KERN_INFO x) 263#define s3c_freq_dbg(x...) printk(KERN_INFO x)
264#else 264#else
265#define s3c_freq_dbg(x...) do { if (0) printk(x); } while (0) 265#define s3c_freq_dbg(x...) do { if (0) printk(x); } while (0)
266#endif /* CONFIG_CPU_FREQ_S3C24XX_DEBUG */ 266#endif /* CONFIG_ARM_S3C24XX_CPUFREQ_DEBUG */
267 267
268#ifdef CONFIG_CPU_FREQ_S3C24XX_IODEBUG 268#ifdef CONFIG_ARM_S3C24XX_CPUFREQ_IODEBUG
269#define s3c_freq_iodbg(x...) printk(KERN_INFO x) 269#define s3c_freq_iodbg(x...) printk(KERN_INFO x)
270#else 270#else
271#define s3c_freq_iodbg(x...) do { if (0) printk(x); } while (0) 271#define s3c_freq_iodbg(x...) do { if (0) printk(x); } while (0)
272#endif /* CONFIG_CPU_FREQ_S3C24XX_IODEBUG */ 272#endif /* CONFIG_ARM_S3C24XX_CPUFREQ_IODEBUG */
273 273
274static inline int s3c_cpufreq_addfreq(struct cpufreq_frequency_table *table, 274static inline int s3c_cpufreq_addfreq(struct cpufreq_frequency_table *table,
275 int index, size_t table_size, 275 int index, size_t table_size,
diff --git a/arch/arm/plat-samsung/include/plat/cpu-freq.h b/arch/arm/plat-samsung/include/plat/cpu-freq.h
index 80c4a809c721..85517ab962ae 100644
--- a/arch/arm/plat-samsung/include/plat/cpu-freq.h
+++ b/arch/arm/plat-samsung/include/plat/cpu-freq.h
@@ -126,7 +126,7 @@ struct s3c_cpufreq_board {
126}; 126};
127 127
128/* Things depending on frequency scaling. */ 128/* Things depending on frequency scaling. */
129#ifdef CONFIG_CPU_FREQ_S3C 129#ifdef CONFIG_ARM_S3C_CPUFREQ
130#define __init_or_cpufreq 130#define __init_or_cpufreq
131#else 131#else
132#define __init_or_cpufreq __init 132#define __init_or_cpufreq __init
@@ -134,7 +134,7 @@ struct s3c_cpufreq_board {
134 134
135/* Board functions */ 135/* Board functions */
136 136
137#ifdef CONFIG_CPU_FREQ_S3C 137#ifdef CONFIG_ARM_S3C_CPUFREQ
138extern int s3c_cpufreq_setboard(struct s3c_cpufreq_board *board); 138extern int s3c_cpufreq_setboard(struct s3c_cpufreq_board *board);
139#else 139#else
140 140
@@ -142,4 +142,4 @@ static inline int s3c_cpufreq_setboard(struct s3c_cpufreq_board *board)
142{ 142{
143 return 0; 143 return 0;
144} 144}
145#endif /* CONFIG_CPU_FREQ_S3C */ 145#endif /* CONFIG_ARM_S3C_CPUFREQ */