aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/plat-s3c/init.c
diff options
context:
space:
mode:
authorBen Dooks <ben-linux@fluff.org>2008-10-21 09:06:31 -0400
committerBen Dooks <ben-linux@fluff.org>2008-12-15 16:45:57 -0500
commit74b265d4e0555b9fc9cc75eb8876140ecf8c6b8a (patch)
treeb3503c64574d7921cc29b213056628c1c4bc83f2 /arch/arm/plat-s3c/init.c
parent2cd493fc10a5ad628dce8471ae72cf0882506735 (diff)
[ARM] S3C24XX: Move initialisation code to arch/arm/plat-s3c
We need to add plat-s3c to the build to get the headers that will go in here once moved from include/asm-arm so we may as well put some useful common s3c code in here to stop the errors generated form having nothing built. The cpu setup is now passed the cpu idcode and the table of supported cpus to s3c_init_cpu() to abstract the cpu identification out of the initial io setup. As well as moving the cpu initialisation code, we move the map of the board specific items up to the calling code as none of the map_io() functions actually do anything other than pass this to iotable_init(). This patch does not rename any of the init functions that will be common to s3c24xx and any other s3c architectures as this can be done at a later date as it will touch all the board support files which use functions such as s3c24xx_init_clocks() and s3c24xx_init_uarts(). Note, the header arch/arm/plat-s3c24xx/include/plat/cpu.h still has functions that are used by both the cpu and board initialisation functions. This means that each board has definitions specific to the cpu support included and the vice-versa. Signed-off-by: Ben Dooks <ben-linux@fluff.org>
Diffstat (limited to 'arch/arm/plat-s3c/init.c')
-rw-r--r--arch/arm/plat-s3c/init.c161
1 files changed, 161 insertions, 0 deletions
diff --git a/arch/arm/plat-s3c/init.c b/arch/arm/plat-s3c/init.c
new file mode 100644
index 000000000000..85f086ee930a
--- /dev/null
+++ b/arch/arm/plat-s3c/init.c
@@ -0,0 +1,161 @@
1/* linux/arch/arm/plat-s3c/init.c
2 *
3 * Copyright (c) 2008 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 * http://armlinux.simtec.co.uk/
6 *
7 * S3C series CPU initialisation
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/serial_core.h>
19#include <linux/platform_device.h>
20#include <linux/delay.h>
21
22#include <mach/hardware.h>
23
24#include <asm/mach/arch.h>
25#include <asm/mach/map.h>
26
27#include <plat/cpu.h>
28#include <plat/devs.h>
29#include <plat/clock.h>
30
31#include <plat/regs-serial.h>
32
33static struct cpu_table *cpu;
34
35static struct cpu_table * __init s3c_lookup_cpu(unsigned long idcode,
36 struct cpu_table *tab,
37 unsigned int count)
38{
39 for (; count != 0; count--, tab++) {
40 if ((idcode & tab->idmask) == tab->idcode)
41 return tab;
42 }
43
44 return NULL;
45}
46
47void __init s3c_init_cpu(unsigned long idcode,
48 struct cpu_table *cputab, unsigned int cputab_size)
49{
50 cpu = s3c_lookup_cpu(idcode, cputab, cputab_size);
51
52 if (cpu == NULL) {
53 printk(KERN_ERR "Unknown CPU type 0x%08lx\n", idcode);
54 panic("Unknown S3C24XX CPU");
55 }
56
57 printk("CPU %s (id 0x%08lx)\n", cpu->name, idcode);
58
59 if (cpu->map_io == NULL || cpu->init == NULL) {
60 printk(KERN_ERR "CPU %s support not enabled\n", cpu->name);
61 panic("Unsupported Samsung CPU");
62 }
63
64 cpu->map_io();
65}
66
67/* s3c24xx_init_clocks
68 *
69 * Initialise the clock subsystem and associated information from the
70 * given master crystal value.
71 *
72 * xtal = 0 -> use default PLL crystal value (normally 12MHz)
73 * != 0 -> PLL crystal value in Hz
74*/
75
76void __init s3c24xx_init_clocks(int xtal)
77{
78 if (xtal == 0)
79 xtal = 12*1000*1000;
80
81 if (cpu == NULL)
82 panic("s3c24xx_init_clocks: no cpu setup?\n");
83
84 if (cpu->init_clocks == NULL)
85 panic("s3c24xx_init_clocks: cpu has no clock init\n");
86 else
87 (cpu->init_clocks)(xtal);
88}
89
90/* uart management */
91
92static int nr_uarts __initdata = 0;
93
94static struct s3c2410_uartcfg uart_cfgs[3];
95
96/* s3c24xx_init_uartdevs
97 *
98 * copy the specified platform data and configuration into our central
99 * set of devices, before the data is thrown away after the init process.
100 *
101 * This also fills in the array passed to the serial driver for the
102 * early initialisation of the console.
103*/
104
105void __init s3c24xx_init_uartdevs(char *name,
106 struct s3c24xx_uart_resources *res,
107 struct s3c2410_uartcfg *cfg, int no)
108{
109 struct platform_device *platdev;
110 struct s3c2410_uartcfg *cfgptr = uart_cfgs;
111 struct s3c24xx_uart_resources *resp;
112 int uart;
113
114 memcpy(cfgptr, cfg, sizeof(struct s3c2410_uartcfg) * no);
115
116 for (uart = 0; uart < no; uart++, cfg++, cfgptr++) {
117 platdev = s3c24xx_uart_src[cfgptr->hwport];
118
119 resp = res + cfgptr->hwport;
120
121 s3c24xx_uart_devs[uart] = platdev;
122
123 platdev->name = name;
124 platdev->resource = resp->resources;
125 platdev->num_resources = resp->nr_resources;
126
127 platdev->dev.platform_data = cfgptr;
128 }
129
130 nr_uarts = no;
131}
132
133void __init s3c24xx_init_uarts(struct s3c2410_uartcfg *cfg, int no)
134{
135 if (cpu == NULL)
136 return;
137
138 if (cpu->init_uarts == NULL) {
139 printk(KERN_ERR "s3c24xx_init_uarts: cpu has no uart init\n");
140 } else
141 (cpu->init_uarts)(cfg, no);
142}
143
144static int __init s3c_arch_init(void)
145{
146 int ret;
147
148 // do the correct init for cpu
149
150 if (cpu == NULL)
151 panic("s3c_arch_init: NULL cpu\n");
152
153 ret = (cpu->init)();
154 if (ret != 0)
155 return ret;
156
157 ret = platform_add_devices(s3c24xx_uart_devs, nr_uarts);
158 return ret;
159}
160
161arch_initcall(s3c_arch_init);