blob: 164685bd25c82ec0f01f1eaeb39f36a125fd4738 [file] [log] [blame]
Kukjin Kimcc511b82011-12-27 08:18:36 +01001/*
2 * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
3 * http://www.samsung.com
4 *
5 * Common Codes for EXYNOS
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/kernel.h>
Tomasz Figa68a433f2013-05-25 06:27:29 +090013#include <linux/bitops.h>
Kukjin Kimcc511b82011-12-27 08:18:36 +010014#include <linux/interrupt.h>
15#include <linux/irq.h>
Rob Herringa900e5d2013-02-12 16:04:52 -060016#include <linux/irqchip.h>
Kukjin Kimcc511b82011-12-27 08:18:36 +010017#include <linux/io.h>
Linus Torvalds7affca32012-01-07 12:03:30 -080018#include <linux/device.h>
Kukjin Kimcc511b82011-12-27 08:18:36 +010019#include <linux/gpio.h>
Tomasz Figa68a433f2013-05-25 06:27:29 +090020#include <clocksource/samsung_pwm.h>
Kukjin Kimcc511b82011-12-27 08:18:36 +010021#include <linux/sched.h>
22#include <linux/serial_core.h>
Arnd Bergmann237c78b2012-01-07 12:30:20 +000023#include <linux/of.h>
Doug Anderson5b7897d2012-11-27 11:53:14 -080024#include <linux/of_fdt.h>
Arnd Bergmann237c78b2012-01-07 12:30:20 +000025#include <linux/of_irq.h>
Thomas Abraham1e60bc02012-05-15 16:18:35 +090026#include <linux/export.h>
27#include <linux/irqdomain.h>
Thomas Abrahame873a472012-05-15 16:25:23 +090028#include <linux/of_address.h>
Thomas Abraham6923ae42013-03-09 17:03:29 +090029#include <linux/clocksource.h>
30#include <linux/clk-provider.h>
Rob Herring520f7bd2012-12-27 13:10:24 -060031#include <linux/irqchip/arm-gic.h>
Catalin Marinasde88cbb2013-01-18 15:31:37 +000032#include <linux/irqchip/chained_irq.h>
Kukjin Kimcc511b82011-12-27 08:18:36 +010033
34#include <asm/proc-fns.h>
Arnd Bergmann40ba95f2012-01-07 11:51:28 +000035#include <asm/exception.h>
Kukjin Kimcc511b82011-12-27 08:18:36 +010036#include <asm/hardware/cache-l2x0.h>
Kukjin Kimcc511b82011-12-27 08:18:36 +010037#include <asm/mach/map.h>
38#include <asm/mach/irq.h>
Amit Daniel Kachhapb756a502012-03-08 02:07:41 -080039#include <asm/cacheflush.h>
Kukjin Kimcc511b82011-12-27 08:18:36 +010040
41#include <mach/regs-irq.h>
42#include <mach/regs-pmu.h>
Kukjin Kimcc511b82011-12-27 08:18:36 +010043
44#include <plat/cpu.h>
Kukjin Kimcc511b82011-12-27 08:18:36 +010045#include <plat/pm.h>
Kukjin Kimcc511b82011-12-27 08:18:36 +010046#include <plat/regs-serial.h>
47
48#include "common.h"
Amit Daniel Kachhap6cdeddc2012-03-08 02:09:12 -080049#define L2_AUX_VAL 0x7C470001
50#define L2_AUX_MASK 0xC200ffff
Kukjin Kimcc511b82011-12-27 08:18:36 +010051
Kukjin Kimcc511b82011-12-27 08:18:36 +010052static const char name_exynos4210[] = "EXYNOS4210";
53static const char name_exynos4212[] = "EXYNOS4212";
54static const char name_exynos4412[] = "EXYNOS4412";
Kukjin Kim94c7ca72012-02-11 22:15:45 +090055static const char name_exynos5250[] = "EXYNOS5250";
Chander Kashyap191d7542013-06-19 00:29:34 +090056static const char name_exynos5420[] = "EXYNOS5420";
Kukjin Kim2edb36c2012-11-15 15:48:56 +090057static const char name_exynos5440[] = "EXYNOS5440";
Kukjin Kimcc511b82011-12-27 08:18:36 +010058
Kukjin Kim906c7892012-02-11 21:27:08 +090059static void exynos4_map_io(void);
Kukjin Kim94c7ca72012-02-11 22:15:45 +090060static void exynos5_map_io(void);
Kukjin Kim2edb36c2012-11-15 15:48:56 +090061static void exynos5440_map_io(void);
Kukjin Kim906c7892012-02-11 21:27:08 +090062static int exynos_init(void);
Kukjin Kimcc511b82011-12-27 08:18:36 +010063
64static struct cpu_table cpu_ids[] __initdata = {
65 {
66 .idcode = EXYNOS4210_CPU_ID,
67 .idmask = EXYNOS4_CPU_MASK,
68 .map_io = exynos4_map_io,
Kukjin Kimcc511b82011-12-27 08:18:36 +010069 .init = exynos_init,
70 .name = name_exynos4210,
71 }, {
72 .idcode = EXYNOS4212_CPU_ID,
73 .idmask = EXYNOS4_CPU_MASK,
74 .map_io = exynos4_map_io,
Kukjin Kimcc511b82011-12-27 08:18:36 +010075 .init = exynos_init,
76 .name = name_exynos4212,
77 }, {
78 .idcode = EXYNOS4412_CPU_ID,
79 .idmask = EXYNOS4_CPU_MASK,
80 .map_io = exynos4_map_io,
Kukjin Kimcc511b82011-12-27 08:18:36 +010081 .init = exynos_init,
82 .name = name_exynos4412,
Kukjin Kim94c7ca72012-02-11 22:15:45 +090083 }, {
84 .idcode = EXYNOS5250_SOC_ID,
85 .idmask = EXYNOS5_SOC_MASK,
86 .map_io = exynos5_map_io,
Kukjin Kim94c7ca72012-02-11 22:15:45 +090087 .init = exynos_init,
88 .name = name_exynos5250,
Kukjin Kim2edb36c2012-11-15 15:48:56 +090089 }, {
Chander Kashyap191d7542013-06-19 00:29:34 +090090 .idcode = EXYNOS5420_SOC_ID,
91 .idmask = EXYNOS5_SOC_MASK,
92 .map_io = exynos5_map_io,
93 .init = exynos_init,
94 .name = name_exynos5420,
95 }, {
Kukjin Kim2edb36c2012-11-15 15:48:56 +090096 .idcode = EXYNOS5440_SOC_ID,
97 .idmask = EXYNOS5_SOC_MASK,
98 .map_io = exynos5440_map_io,
99 .init = exynos_init,
100 .name = name_exynos5440,
Kukjin Kimcc511b82011-12-27 08:18:36 +0100101 },
102};
103
104/* Initial IO mappings */
105
Kukjin Kim94c7ca72012-02-11 22:15:45 +0900106static struct map_desc exynos4_iodesc[] __initdata = {
107 {
Kukjin Kimcc511b82011-12-27 08:18:36 +0100108 .virtual = (unsigned long)S3C_VA_SYS,
109 .pfn = __phys_to_pfn(EXYNOS4_PA_SYSCON),
110 .length = SZ_64K,
111 .type = MT_DEVICE,
112 }, {
113 .virtual = (unsigned long)S3C_VA_TIMER,
114 .pfn = __phys_to_pfn(EXYNOS4_PA_TIMER),
115 .length = SZ_16K,
116 .type = MT_DEVICE,
117 }, {
118 .virtual = (unsigned long)S3C_VA_WATCHDOG,
119 .pfn = __phys_to_pfn(EXYNOS4_PA_WATCHDOG),
120 .length = SZ_4K,
121 .type = MT_DEVICE,
122 }, {
123 .virtual = (unsigned long)S5P_VA_SROMC,
124 .pfn = __phys_to_pfn(EXYNOS4_PA_SROMC),
125 .length = SZ_4K,
126 .type = MT_DEVICE,
127 }, {
128 .virtual = (unsigned long)S5P_VA_SYSTIMER,
129 .pfn = __phys_to_pfn(EXYNOS4_PA_SYSTIMER),
130 .length = SZ_4K,
131 .type = MT_DEVICE,
132 }, {
133 .virtual = (unsigned long)S5P_VA_PMU,
134 .pfn = __phys_to_pfn(EXYNOS4_PA_PMU),
135 .length = SZ_64K,
136 .type = MT_DEVICE,
137 }, {
138 .virtual = (unsigned long)S5P_VA_COMBINER_BASE,
139 .pfn = __phys_to_pfn(EXYNOS4_PA_COMBINER),
140 .length = SZ_4K,
141 .type = MT_DEVICE,
142 }, {
143 .virtual = (unsigned long)S5P_VA_GIC_CPU,
144 .pfn = __phys_to_pfn(EXYNOS4_PA_GIC_CPU),
145 .length = SZ_64K,
146 .type = MT_DEVICE,
147 }, {
148 .virtual = (unsigned long)S5P_VA_GIC_DIST,
149 .pfn = __phys_to_pfn(EXYNOS4_PA_GIC_DIST),
150 .length = SZ_64K,
151 .type = MT_DEVICE,
152 }, {
153 .virtual = (unsigned long)S3C_VA_UART,
154 .pfn = __phys_to_pfn(EXYNOS4_PA_UART),
155 .length = SZ_512K,
156 .type = MT_DEVICE,
Kukjin Kim94c7ca72012-02-11 22:15:45 +0900157 }, {
Kukjin Kimcc511b82011-12-27 08:18:36 +0100158 .virtual = (unsigned long)S5P_VA_CMU,
159 .pfn = __phys_to_pfn(EXYNOS4_PA_CMU),
160 .length = SZ_128K,
161 .type = MT_DEVICE,
162 }, {
163 .virtual = (unsigned long)S5P_VA_COREPERI_BASE,
164 .pfn = __phys_to_pfn(EXYNOS4_PA_COREPERI),
165 .length = SZ_8K,
166 .type = MT_DEVICE,
167 }, {
168 .virtual = (unsigned long)S5P_VA_L2CC,
169 .pfn = __phys_to_pfn(EXYNOS4_PA_L2CC),
170 .length = SZ_4K,
171 .type = MT_DEVICE,
172 }, {
Kukjin Kimcc511b82011-12-27 08:18:36 +0100173 .virtual = (unsigned long)S5P_VA_DMC0,
174 .pfn = __phys_to_pfn(EXYNOS4_PA_DMC0),
MyungJoo Ham2bde0b02011-12-01 15:12:30 +0900175 .length = SZ_64K,
176 .type = MT_DEVICE,
177 }, {
178 .virtual = (unsigned long)S5P_VA_DMC1,
179 .pfn = __phys_to_pfn(EXYNOS4_PA_DMC1),
180 .length = SZ_64K,
Kukjin Kimcc511b82011-12-27 08:18:36 +0100181 .type = MT_DEVICE,
182 }, {
Kukjin Kimcc511b82011-12-27 08:18:36 +0100183 .virtual = (unsigned long)S3C_VA_USB_HSPHY,
184 .pfn = __phys_to_pfn(EXYNOS4_PA_HSPHY),
185 .length = SZ_4K,
186 .type = MT_DEVICE,
187 },
188};
189
190static struct map_desc exynos4_iodesc0[] __initdata = {
191 {
192 .virtual = (unsigned long)S5P_VA_SYSRAM,
193 .pfn = __phys_to_pfn(EXYNOS4_PA_SYSRAM0),
194 .length = SZ_4K,
195 .type = MT_DEVICE,
196 },
197};
198
199static struct map_desc exynos4_iodesc1[] __initdata = {
200 {
201 .virtual = (unsigned long)S5P_VA_SYSRAM,
202 .pfn = __phys_to_pfn(EXYNOS4_PA_SYSRAM1),
203 .length = SZ_4K,
204 .type = MT_DEVICE,
205 },
206};
207
Tomasz Figa41de8982012-12-11 13:58:43 +0900208static struct map_desc exynos4210_iodesc[] __initdata = {
209 {
210 .virtual = (unsigned long)S5P_VA_SYSRAM_NS,
211 .pfn = __phys_to_pfn(EXYNOS4210_PA_SYSRAM_NS),
212 .length = SZ_4K,
213 .type = MT_DEVICE,
214 },
215};
216
217static struct map_desc exynos4x12_iodesc[] __initdata = {
218 {
219 .virtual = (unsigned long)S5P_VA_SYSRAM_NS,
220 .pfn = __phys_to_pfn(EXYNOS4x12_PA_SYSRAM_NS),
221 .length = SZ_4K,
222 .type = MT_DEVICE,
223 },
224};
225
226static struct map_desc exynos5250_iodesc[] __initdata = {
227 {
228 .virtual = (unsigned long)S5P_VA_SYSRAM_NS,
229 .pfn = __phys_to_pfn(EXYNOS5250_PA_SYSRAM_NS),
230 .length = SZ_4K,
231 .type = MT_DEVICE,
232 },
233};
234
Kukjin Kim94c7ca72012-02-11 22:15:45 +0900235static struct map_desc exynos5_iodesc[] __initdata = {
236 {
237 .virtual = (unsigned long)S3C_VA_SYS,
238 .pfn = __phys_to_pfn(EXYNOS5_PA_SYSCON),
239 .length = SZ_64K,
240 .type = MT_DEVICE,
241 }, {
242 .virtual = (unsigned long)S3C_VA_TIMER,
243 .pfn = __phys_to_pfn(EXYNOS5_PA_TIMER),
244 .length = SZ_16K,
245 .type = MT_DEVICE,
246 }, {
247 .virtual = (unsigned long)S3C_VA_WATCHDOG,
248 .pfn = __phys_to_pfn(EXYNOS5_PA_WATCHDOG),
249 .length = SZ_4K,
250 .type = MT_DEVICE,
251 }, {
252 .virtual = (unsigned long)S5P_VA_SROMC,
253 .pfn = __phys_to_pfn(EXYNOS5_PA_SROMC),
254 .length = SZ_4K,
255 .type = MT_DEVICE,
256 }, {
Kukjin Kim94c7ca72012-02-11 22:15:45 +0900257 .virtual = (unsigned long)S5P_VA_SYSRAM,
258 .pfn = __phys_to_pfn(EXYNOS5_PA_SYSRAM),
259 .length = SZ_4K,
260 .type = MT_DEVICE,
261 }, {
262 .virtual = (unsigned long)S5P_VA_CMU,
263 .pfn = __phys_to_pfn(EXYNOS5_PA_CMU),
264 .length = 144 * SZ_1K,
265 .type = MT_DEVICE,
266 }, {
267 .virtual = (unsigned long)S5P_VA_PMU,
268 .pfn = __phys_to_pfn(EXYNOS5_PA_PMU),
269 .length = SZ_64K,
270 .type = MT_DEVICE,
271 }, {
Kukjin Kim94c7ca72012-02-11 22:15:45 +0900272 .virtual = (unsigned long)S3C_VA_UART,
273 .pfn = __phys_to_pfn(EXYNOS5_PA_UART),
274 .length = SZ_512K,
275 .type = MT_DEVICE,
Kukjin Kim94c7ca72012-02-11 22:15:45 +0900276 },
277};
278
Kukjin Kim2edb36c2012-11-15 15:48:56 +0900279static struct map_desc exynos5440_iodesc0[] __initdata = {
280 {
281 .virtual = (unsigned long)S3C_VA_UART,
282 .pfn = __phys_to_pfn(EXYNOS5440_PA_UART0),
283 .length = SZ_512K,
284 .type = MT_DEVICE,
285 },
286};
287
Robin Holt7b6d8642013-07-08 16:01:40 -0700288void exynos4_restart(enum reboot_mode mode, const char *cmd)
Kukjin Kimcc511b82011-12-27 08:18:36 +0100289{
290 __raw_writel(0x1, S5P_SWRESET);
291}
292
Robin Holt7b6d8642013-07-08 16:01:40 -0700293void exynos5_restart(enum reboot_mode mode, const char *cmd)
Kukjin Kim94c7ca72012-02-11 22:15:45 +0900294{
Thomas Abraham60db7e52013-01-24 10:09:13 -0800295 struct device_node *np;
Kukjin Kim2edb36c2012-11-15 15:48:56 +0900296 u32 val;
297 void __iomem *addr;
298
Chander Kashyapeff4e7c2013-06-19 00:29:35 +0900299 val = 0x1;
300 addr = EXYNOS_SWRESET;
301
302 if (of_machine_is_compatible("samsung,exynos5440")) {
Jungseok Lee1ba830c2013-05-25 06:33:03 +0900303 u32 status;
Thomas Abraham60db7e52013-01-24 10:09:13 -0800304 np = of_find_compatible_node(NULL, NULL, "samsung,exynos5440-clock");
Jungseok Lee1ba830c2013-05-25 06:33:03 +0900305
306 addr = of_iomap(np, 0) + 0xbc;
307 status = __raw_readl(addr);
308
Thomas Abraham60db7e52013-01-24 10:09:13 -0800309 addr = of_iomap(np, 0) + 0xcc;
Jungseok Lee1ba830c2013-05-25 06:33:03 +0900310 val = __raw_readl(addr);
311
312 val = (val & 0xffff0000) | (status & 0xffff);
Kukjin Kim2edb36c2012-11-15 15:48:56 +0900313 }
314
315 __raw_writel(val, addr);
Kukjin Kim94c7ca72012-02-11 22:15:45 +0900316}
317
Shawn Guobb13fab2012-04-26 10:35:40 +0800318void __init exynos_init_late(void)
319{
Kukjin Kim2edb36c2012-11-15 15:48:56 +0900320 if (of_machine_is_compatible("samsung,exynos5440"))
321 /* to be supported later */
322 return;
323
Shawn Guobb13fab2012-04-26 10:35:40 +0800324 exynos_pm_late_initcall();
325}
326
Arnd Bergmann564d06b2013-06-19 01:36:56 +0900327static int __init exynos_fdt_map_chipid(unsigned long node, const char *uname,
Thomas Abrahamf5f83c72013-04-23 22:46:53 +0900328 int depth, void *data)
329{
330 struct map_desc iodesc;
331 __be32 *reg;
332 unsigned long len;
333
334 if (!of_flat_dt_is_compatible(node, "samsung,exynos4210-chipid") &&
335 !of_flat_dt_is_compatible(node, "samsung,exynos5440-clock"))
336 return 0;
337
338 reg = of_get_flat_dt_prop(node, "reg", &len);
339 if (reg == NULL || len != (sizeof(unsigned long) * 2))
340 return 0;
341
342 iodesc.pfn = __phys_to_pfn(be32_to_cpu(reg[0]));
343 iodesc.length = be32_to_cpu(reg[1]) - 1;
344 iodesc.virtual = (unsigned long)S5P_VA_CHIPID;
345 iodesc.type = MT_DEVICE;
346 iotable_init(&iodesc, 1);
347 return 1;
348}
Thomas Abrahamf5f83c72013-04-23 22:46:53 +0900349
Kukjin Kimcc511b82011-12-27 08:18:36 +0100350/*
351 * exynos_map_io
352 *
353 * register the standard cpu IO areas
354 */
355
Arnd Bergmann0e2238e2013-06-19 01:36:47 +0900356void __init exynos_init_io(void)
Kukjin Kimcc511b82011-12-27 08:18:36 +0100357{
Doug Anderson9c1fcdc2013-06-05 13:56:33 -0700358 debug_ll_io_init();
359
Tomasz Figa04fae592013-06-15 09:13:25 +0900360 of_scan_flat_dt(exynos_fdt_map_chipid, NULL);
Kukjin Kim2edb36c2012-11-15 15:48:56 +0900361
Kukjin Kimcc511b82011-12-27 08:18:36 +0100362 /* detect cpu id and rev. */
363 s5p_init_cpu(S5P_VA_CHIPID);
364
365 s3c_init_cpu(samsung_cpu_id, cpu_ids, ARRAY_SIZE(cpu_ids));
366}
367
Kukjin Kim906c7892012-02-11 21:27:08 +0900368static void __init exynos4_map_io(void)
Kukjin Kimcc511b82011-12-27 08:18:36 +0100369{
370 iotable_init(exynos4_iodesc, ARRAY_SIZE(exynos4_iodesc));
371
372 if (soc_is_exynos4210() && samsung_rev() == EXYNOS4210_REV_0)
373 iotable_init(exynos4_iodesc0, ARRAY_SIZE(exynos4_iodesc0));
374 else
375 iotable_init(exynos4_iodesc1, ARRAY_SIZE(exynos4_iodesc1));
376
Tomasz Figa41de8982012-12-11 13:58:43 +0900377 if (soc_is_exynos4210())
378 iotable_init(exynos4210_iodesc, ARRAY_SIZE(exynos4210_iodesc));
379 if (soc_is_exynos4212() || soc_is_exynos4412())
380 iotable_init(exynos4x12_iodesc, ARRAY_SIZE(exynos4x12_iodesc));
Kukjin Kimcc511b82011-12-27 08:18:36 +0100381}
382
Kukjin Kim94c7ca72012-02-11 22:15:45 +0900383static void __init exynos5_map_io(void)
384{
385 iotable_init(exynos5_iodesc, ARRAY_SIZE(exynos5_iodesc));
Tomasz Figa41de8982012-12-11 13:58:43 +0900386
387 if (soc_is_exynos5250())
388 iotable_init(exynos5250_iodesc, ARRAY_SIZE(exynos5250_iodesc));
Kukjin Kim94c7ca72012-02-11 22:15:45 +0900389}
390
Kukjin Kim2edb36c2012-11-15 15:48:56 +0900391static void __init exynos5440_map_io(void)
392{
393 iotable_init(exynos5440_iodesc0, ARRAY_SIZE(exynos5440_iodesc0));
394}
395
Thomas Abraham6923ae42013-03-09 17:03:29 +0900396void __init exynos_init_time(void)
Kukjin Kim94c7ca72012-02-11 22:15:45 +0900397{
Tomasz Figa3c70348c72013-06-15 09:04:58 +0900398 of_clk_init(NULL);
399 clocksource_of_init();
Kukjin Kim94c7ca72012-02-11 22:15:45 +0900400}
401
Thomas Abraham9ee6af92012-05-15 15:47:40 +0900402struct bus_type exynos_subsys = {
403 .name = "exynos-core",
404 .dev_name = "exynos-core",
Kukjin Kim94c7ca72012-02-11 22:15:45 +0900405};
406
Linus Torvalds7affca32012-01-07 12:03:30 -0800407static struct device exynos4_dev = {
Thomas Abraham9ee6af92012-05-15 15:47:40 +0900408 .bus = &exynos_subsys,
Kukjin Kim94c7ca72012-02-11 22:15:45 +0900409};
410
411static int __init exynos_core_init(void)
Kukjin Kimcc511b82011-12-27 08:18:36 +0100412{
Thomas Abraham9ee6af92012-05-15 15:47:40 +0900413 return subsys_system_register(&exynos_subsys, NULL);
Kukjin Kimcc511b82011-12-27 08:18:36 +0100414}
Kukjin Kim94c7ca72012-02-11 22:15:45 +0900415core_initcall(exynos_core_init);
Kukjin Kimcc511b82011-12-27 08:18:36 +0100416
Kukjin Kimcc511b82011-12-27 08:18:36 +0100417static int __init exynos4_l2x0_cache_init(void)
418{
Il Hane1b19942012-04-05 07:59:36 -0700419 int ret;
420
Amit Daniel Kachhap6cdeddc2012-03-08 02:09:12 -0800421 ret = l2x0_of_init(L2_AUX_VAL, L2_AUX_MASK);
Arnd Bergmann87107d82013-06-19 01:36:52 +0900422 if (ret)
423 return ret;
Kukjin Kimcc511b82011-12-27 08:18:36 +0100424
Arnd Bergmann87107d82013-06-19 01:36:52 +0900425 l2x0_regs_phys = virt_to_phys(&l2x0_saved_regs);
426 clean_dcache_area(&l2x0_regs_phys, sizeof(unsigned long));
Kukjin Kimcc511b82011-12-27 08:18:36 +0100427 return 0;
428}
Kukjin Kimcc511b82011-12-27 08:18:36 +0100429early_initcall(exynos4_l2x0_cache_init);
Kukjin Kimcc511b82011-12-27 08:18:36 +0100430
Kukjin Kim906c7892012-02-11 21:27:08 +0900431static int __init exynos_init(void)
Kukjin Kimcc511b82011-12-27 08:18:36 +0100432{
433 printk(KERN_INFO "EXYNOS: Initializing architecture\n");
Kukjin Kim94c7ca72012-02-11 22:15:45 +0900434
Thomas Abraham9ee6af92012-05-15 15:47:40 +0900435 return device_register(&exynos4_dev);
Kukjin Kimcc511b82011-12-27 08:18:36 +0100436}