aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/plat-s5p
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/plat-s5p')
-rw-r--r--arch/arm/plat-s5p/Kconfig107
-rw-r--r--arch/arm/plat-s5p/Makefile38
-rw-r--r--arch/arm/plat-s5p/clock.c228
-rw-r--r--arch/arm/plat-s5p/cpu.c126
-rw-r--r--arch/arm/plat-s5p/dev-csis0.c34
-rw-r--r--arch/arm/plat-s5p/dev-csis1.c34
-rw-r--r--arch/arm/plat-s5p/dev-ehci.c57
-rw-r--r--arch/arm/plat-s5p/dev-fimc0.c43
-rw-r--r--arch/arm/plat-s5p/dev-fimc1.c43
-rw-r--r--arch/arm/plat-s5p/dev-fimc2.c43
-rw-r--r--arch/arm/plat-s5p/dev-fimc3.c43
-rw-r--r--arch/arm/plat-s5p/dev-fimd0.c67
-rw-r--r--arch/arm/plat-s5p/dev-mfc.c123
-rw-r--r--arch/arm/plat-s5p/dev-onenand.c45
-rw-r--r--arch/arm/plat-s5p/dev-pmu.c36
-rw-r--r--arch/arm/plat-s5p/dev-uart.c197
-rw-r--r--arch/arm/plat-s5p/include/plat/camport.h28
-rw-r--r--arch/arm/plat-s5p/include/plat/ehci.h21
-rw-r--r--arch/arm/plat-s5p/include/plat/exynos4.h34
-rw-r--r--arch/arm/plat-s5p/include/plat/irqs.h115
-rw-r--r--arch/arm/plat-s5p/include/plat/map-s5p.h61
-rw-r--r--arch/arm/plat-s5p/include/plat/mfc.h27
-rw-r--r--arch/arm/plat-s5p/include/plat/mipi_csis.h43
-rw-r--r--arch/arm/plat-s5p/include/plat/pll.h153
-rw-r--r--arch/arm/plat-s5p/include/plat/regs-srom.h54
-rw-r--r--arch/arm/plat-s5p/include/plat/reset.h16
-rw-r--r--arch/arm/plat-s5p/include/plat/s5p-clock.h55
-rw-r--r--arch/arm/plat-s5p/include/plat/s5p-time.h40
-rw-r--r--arch/arm/plat-s5p/include/plat/s5p6440.h36
-rw-r--r--arch/arm/plat-s5p/include/plat/s5p6450.h36
-rw-r--r--arch/arm/plat-s5p/include/plat/s5pc100.h33
-rw-r--r--arch/arm/plat-s5p/include/plat/s5pv210.h33
-rw-r--r--arch/arm/plat-s5p/include/plat/sysmmu.h95
-rw-r--r--arch/arm/plat-s5p/include/plat/system-reset.h31
-rw-r--r--arch/arm/plat-s5p/include/plat/usb-phy.h22
-rw-r--r--arch/arm/plat-s5p/irq-eint.c219
-rw-r--r--arch/arm/plat-s5p/irq-gpioint.c216
-rw-r--r--arch/arm/plat-s5p/irq-pm.c90
-rw-r--r--arch/arm/plat-s5p/irq.c70
-rw-r--r--arch/arm/plat-s5p/pm.c41
-rw-r--r--arch/arm/plat-s5p/s5p-time.c419
-rw-r--r--arch/arm/plat-s5p/setup-mipiphy.c63
-rw-r--r--arch/arm/plat-s5p/sysmmu.c312
43 files changed, 3627 insertions, 0 deletions
diff --git a/arch/arm/plat-s5p/Kconfig b/arch/arm/plat-s5p/Kconfig
new file mode 100644
index 00000000000..9843c954c04
--- /dev/null
+++ b/arch/arm/plat-s5p/Kconfig
@@ -0,0 +1,107 @@
1# arch/arm/plat-s5p/Kconfig
2#
3# Copyright (c) 2009 Samsung Electronics Co., Ltd.
4# http://www.samsung.com/
5#
6# Licensed under GPLv2
7
8config PLAT_S5P
9 bool
10 depends on (ARCH_S5P64X0 || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_EXYNOS4)
11 default y
12 select ARM_VIC if !ARCH_EXYNOS4
13 select ARM_GIC if ARCH_EXYNOS4
14 select NO_IOPORT
15 select ARCH_REQUIRE_GPIOLIB
16 select S3C_GPIO_TRACK
17 select S5P_GPIO_DRVSTR
18 select SAMSUNG_GPIOLIB_4BIT
19 select S3C_GPIO_CFG_S3C64XX
20 select S3C_GPIO_PULL_UPDOWN
21 select S3C_GPIO_CFG_S3C24XX
22 select PLAT_SAMSUNG
23 select SAMSUNG_CLKSRC
24 select SAMSUNG_IRQ_VIC_TIMER
25 select SAMSUNG_IRQ_UART
26 help
27 Base platform code for Samsung's S5P series SoC.
28
29config S5P_EXT_INT
30 bool
31 help
32 Use the external interrupts (other than GPIO interrupts.)
33 Note: Do not choose this for S5P6440 and S5P6450.
34
35config S5P_GPIO_INT
36 bool
37 help
38 Common code for the GPIO interrupts (other than external interrupts.)
39
40config S5P_HRT
41 bool
42 select SAMSUNG_DEV_PWM
43 help
44 Use the High Resolution timer support
45
46comment "System MMU"
47
48config S5P_SYSTEM_MMU
49 bool "S5P SYSTEM MMU"
50 depends on ARCH_EXYNOS4
51 help
52 Say Y here if you want to enable System MMU
53
54config S5P_DEV_FIMC0
55 bool
56 help
57 Compile in platform device definitions for FIMC controller 0
58
59config S5P_DEV_FIMC1
60 bool
61 help
62 Compile in platform device definitions for FIMC controller 1
63
64config S5P_DEV_FIMC2
65 bool
66 help
67 Compile in platform device definitions for FIMC controller 2
68
69config S5P_DEV_FIMC3
70 bool
71 help
72 Compile in platform device definitions for FIMC controller 3
73
74config S5P_DEV_FIMD0
75 bool
76 help
77 Compile in platform device definitions for FIMD controller 0
78
79config S5P_DEV_MFC
80 bool
81 help
82 Compile in platform device definitions for MFC
83
84config S5P_DEV_ONENAND
85 bool
86 help
87 Compile in platform device definition for OneNAND controller
88
89config S5P_DEV_CSIS0
90 bool
91 help
92 Compile in platform device definitions for MIPI-CSIS channel 0
93
94config S5P_DEV_CSIS1
95 bool
96 help
97 Compile in platform device definitions for MIPI-CSIS channel 1
98
99config S5P_DEV_USB_EHCI
100 bool
101 help
102 Compile in platform device definition for USB EHCI
103
104config S5P_SETUP_MIPIPHY
105 bool
106 help
107 Compile in common setup code for MIPI-CSIS and MIPI-DSIM devices
diff --git a/arch/arm/plat-s5p/Makefile b/arch/arm/plat-s5p/Makefile
new file mode 100644
index 00000000000..4b53e04eeca
--- /dev/null
+++ b/arch/arm/plat-s5p/Makefile
@@ -0,0 +1,38 @@
1# arch/arm/plat-s5p/Makefile
2#
3# Copyright (c) 2009 Samsung Electronics Co., Ltd.
4# http://www.samsung.com/
5#
6# Licensed under GPLv2
7
8obj-y :=
9obj-m :=
10obj-n := dummy.o
11obj- :=
12
13# Core files
14
15obj-y += dev-pmu.o
16obj-y += dev-uart.o
17obj-y += cpu.o
18obj-y += clock.o
19obj-y += irq.o
20obj-$(CONFIG_S5P_EXT_INT) += irq-eint.o
21obj-$(CONFIG_S5P_GPIO_INT) += irq-gpioint.o
22obj-$(CONFIG_S5P_SYSTEM_MMU) += sysmmu.o
23obj-$(CONFIG_PM) += pm.o
24obj-$(CONFIG_PM) += irq-pm.o
25obj-$(CONFIG_S5P_HRT) += s5p-time.o
26
27# devices
28obj-$(CONFIG_S5P_DEV_MFC) += dev-mfc.o
29obj-$(CONFIG_S5P_DEV_FIMC0) += dev-fimc0.o
30obj-$(CONFIG_S5P_DEV_FIMC1) += dev-fimc1.o
31obj-$(CONFIG_S5P_DEV_FIMC2) += dev-fimc2.o
32obj-$(CONFIG_S5P_DEV_FIMC3) += dev-fimc3.o
33obj-$(CONFIG_S5P_DEV_FIMD0) += dev-fimd0.o
34obj-$(CONFIG_S5P_DEV_ONENAND) += dev-onenand.o
35obj-$(CONFIG_S5P_DEV_CSIS0) += dev-csis0.o
36obj-$(CONFIG_S5P_DEV_CSIS1) += dev-csis1.o
37obj-$(CONFIG_S5P_DEV_USB_EHCI) += dev-ehci.o
38obj-$(CONFIG_S5P_SETUP_MIPIPHY) += setup-mipiphy.o
diff --git a/arch/arm/plat-s5p/clock.c b/arch/arm/plat-s5p/clock.c
new file mode 100644
index 00000000000..5f84a3f13ef
--- /dev/null
+++ b/arch/arm/plat-s5p/clock.c
@@ -0,0 +1,228 @@
1/* linux/arch/arm/plat-s5p/clock.c
2 *
3 * Copyright 2009 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * S5P - Common clock 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/module.h>
15#include <linux/kernel.h>
16#include <linux/list.h>
17#include <linux/errno.h>
18#include <linux/err.h>
19#include <linux/clk.h>
20#include <linux/sysdev.h>
21#include <linux/io.h>
22#include <asm/div64.h>
23
24#include <mach/regs-clock.h>
25
26#include <plat/clock.h>
27#include <plat/clock-clksrc.h>
28#include <plat/s5p-clock.h>
29
30/* fin_apll, fin_mpll and fin_epll are all the same clock, which we call
31 * clk_ext_xtal_mux.
32*/
33struct clk clk_ext_xtal_mux = {
34 .name = "ext_xtal",
35 .id = -1,
36};
37
38struct clk clk_xusbxti = {
39 .name = "xusbxti",
40 .id = -1,
41};
42
43struct clk s5p_clk_27m = {
44 .name = "clk_27m",
45 .id = -1,
46 .rate = 27000000,
47};
48
49/* 48MHz USB Phy clock output */
50struct clk clk_48m = {
51 .name = "clk_48m",
52 .id = -1,
53 .rate = 48000000,
54};
55
56/* APLL clock output
57 * No need .ctrlbit, this is always on
58*/
59struct clk clk_fout_apll = {
60 .name = "fout_apll",
61 .id = -1,
62};
63
64/* MPLL clock output
65 * No need .ctrlbit, this is always on
66*/
67struct clk clk_fout_mpll = {
68 .name = "fout_mpll",
69 .id = -1,
70};
71
72/* EPLL clock output */
73struct clk clk_fout_epll = {
74 .name = "fout_epll",
75 .id = -1,
76 .ctrlbit = (1 << 31),
77};
78
79/* DPLL clock output */
80struct clk clk_fout_dpll = {
81 .name = "fout_dpll",
82 .id = -1,
83 .ctrlbit = (1 << 31),
84};
85
86/* VPLL clock output */
87struct clk clk_fout_vpll = {
88 .name = "fout_vpll",
89 .id = -1,
90 .ctrlbit = (1 << 31),
91};
92
93/* Possible clock sources for APLL Mux */
94static struct clk *clk_src_apll_list[] = {
95 [0] = &clk_fin_apll,
96 [1] = &clk_fout_apll,
97};
98
99struct clksrc_sources clk_src_apll = {
100 .sources = clk_src_apll_list,
101 .nr_sources = ARRAY_SIZE(clk_src_apll_list),
102};
103
104/* Possible clock sources for MPLL Mux */
105static struct clk *clk_src_mpll_list[] = {
106 [0] = &clk_fin_mpll,
107 [1] = &clk_fout_mpll,
108};
109
110struct clksrc_sources clk_src_mpll = {
111 .sources = clk_src_mpll_list,
112 .nr_sources = ARRAY_SIZE(clk_src_mpll_list),
113};
114
115/* Possible clock sources for EPLL Mux */
116static struct clk *clk_src_epll_list[] = {
117 [0] = &clk_fin_epll,
118 [1] = &clk_fout_epll,
119};
120
121struct clksrc_sources clk_src_epll = {
122 .sources = clk_src_epll_list,
123 .nr_sources = ARRAY_SIZE(clk_src_epll_list),
124};
125
126/* Possible clock sources for DPLL Mux */
127static struct clk *clk_src_dpll_list[] = {
128 [0] = &clk_fin_dpll,
129 [1] = &clk_fout_dpll,
130};
131
132struct clksrc_sources clk_src_dpll = {
133 .sources = clk_src_dpll_list,
134 .nr_sources = ARRAY_SIZE(clk_src_dpll_list),
135};
136
137struct clk clk_vpll = {
138 .name = "vpll",
139 .id = -1,
140};
141
142int s5p_gatectrl(void __iomem *reg, struct clk *clk, int enable)
143{
144 unsigned int ctrlbit = clk->ctrlbit;
145 u32 con;
146
147 con = __raw_readl(reg);
148 con = enable ? (con | ctrlbit) : (con & ~ctrlbit);
149 __raw_writel(con, reg);
150 return 0;
151}
152
153int s5p_epll_enable(struct clk *clk, int enable)
154{
155 unsigned int ctrlbit = clk->ctrlbit;
156 unsigned int epll_con = __raw_readl(S5P_EPLL_CON) & ~ctrlbit;
157
158 if (enable)
159 __raw_writel(epll_con | ctrlbit, S5P_EPLL_CON);
160 else
161 __raw_writel(epll_con, S5P_EPLL_CON);
162
163 return 0;
164}
165
166unsigned long s5p_epll_get_rate(struct clk *clk)
167{
168 return clk->rate;
169}
170
171int s5p_spdif_set_rate(struct clk *clk, unsigned long rate)
172{
173 struct clk *pclk;
174 int ret;
175
176 pclk = clk_get_parent(clk);
177 if (IS_ERR(pclk))
178 return -EINVAL;
179
180 ret = pclk->ops->set_rate(pclk, rate);
181 clk_put(pclk);
182
183 return ret;
184}
185
186unsigned long s5p_spdif_get_rate(struct clk *clk)
187{
188 struct clk *pclk;
189 int rate;
190
191 pclk = clk_get_parent(clk);
192 if (IS_ERR(pclk))
193 return -EINVAL;
194
195 rate = pclk->ops->get_rate(pclk);
196 clk_put(pclk);
197
198 return rate;
199}
200
201struct clk_ops s5p_sclk_spdif_ops = {
202 .set_rate = s5p_spdif_set_rate,
203 .get_rate = s5p_spdif_get_rate,
204};
205
206static struct clk *s5p_clks[] __initdata = {
207 &clk_ext_xtal_mux,
208 &clk_48m,
209 &s5p_clk_27m,
210 &clk_fout_apll,
211 &clk_fout_mpll,
212 &clk_fout_epll,
213 &clk_fout_dpll,
214 &clk_fout_vpll,
215 &clk_vpll,
216 &clk_xusbxti,
217};
218
219void __init s5p_register_clocks(unsigned long xtal_freq)
220{
221 int ret;
222
223 clk_ext_xtal_mux.rate = xtal_freq;
224
225 ret = s3c24xx_register_clocks(s5p_clks, ARRAY_SIZE(s5p_clks));
226 if (ret > 0)
227 printk(KERN_ERR "Failed to register s5p clocks\n");
228}
diff --git a/arch/arm/plat-s5p/cpu.c b/arch/arm/plat-s5p/cpu.c
new file mode 100644
index 00000000000..bbc2aa7449c
--- /dev/null
+++ b/arch/arm/plat-s5p/cpu.c
@@ -0,0 +1,126 @@
1/* linux/arch/arm/plat-s5p/cpu.c
2 *
3 * Copyright (c) 2009-2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * S5P CPU 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/module.h>
15
16#include <asm/mach/arch.h>
17#include <asm/mach/map.h>
18
19#include <mach/map.h>
20#include <mach/regs-clock.h>
21
22#include <plat/cpu.h>
23#include <plat/s5p6440.h>
24#include <plat/s5p6450.h>
25#include <plat/s5pc100.h>
26#include <plat/s5pv210.h>
27#include <plat/exynos4.h>
28
29/* table of supported CPUs */
30
31static const char name_s5p6440[] = "S5P6440";
32static const char name_s5p6450[] = "S5P6450";
33static const char name_s5pc100[] = "S5PC100";
34static const char name_s5pv210[] = "S5PV210/S5PC110";
35static const char name_exynos4210[] = "EXYNOS4210";
36
37static struct cpu_table cpu_ids[] __initdata = {
38 {
39 .idcode = 0x56440100,
40 .idmask = 0xfffff000,
41 .map_io = s5p6440_map_io,
42 .init_clocks = s5p6440_init_clocks,
43 .init_uarts = s5p6440_init_uarts,
44 .init = s5p64x0_init,
45 .name = name_s5p6440,
46 }, {
47 .idcode = 0x36450000,
48 .idmask = 0xfffff000,
49 .map_io = s5p6450_map_io,
50 .init_clocks = s5p6450_init_clocks,
51 .init_uarts = s5p6450_init_uarts,
52 .init = s5p64x0_init,
53 .name = name_s5p6450,
54 }, {
55 .idcode = 0x43100000,
56 .idmask = 0xfffff000,
57 .map_io = s5pc100_map_io,
58 .init_clocks = s5pc100_init_clocks,
59 .init_uarts = s5pc100_init_uarts,
60 .init = s5pc100_init,
61 .name = name_s5pc100,
62 }, {
63 .idcode = 0x43110000,
64 .idmask = 0xfffff000,
65 .map_io = s5pv210_map_io,
66 .init_clocks = s5pv210_init_clocks,
67 .init_uarts = s5pv210_init_uarts,
68 .init = s5pv210_init,
69 .name = name_s5pv210,
70 }, {
71 .idcode = 0x43210000,
72 .idmask = 0xfffe0000,
73 .map_io = exynos4_map_io,
74 .init_clocks = exynos4_init_clocks,
75 .init_uarts = exynos4_init_uarts,
76 .init = exynos4_init,
77 .name = name_exynos4210,
78 },
79};
80
81/* minimal IO mapping */
82
83static struct map_desc s5p_iodesc[] __initdata = {
84 {
85 .virtual = (unsigned long)S5P_VA_CHIPID,
86 .pfn = __phys_to_pfn(S5P_PA_CHIPID),
87 .length = SZ_4K,
88 .type = MT_DEVICE,
89 }, {
90 .virtual = (unsigned long)S3C_VA_SYS,
91 .pfn = __phys_to_pfn(S5P_PA_SYSCON),
92 .length = SZ_64K,
93 .type = MT_DEVICE,
94 }, {
95 .virtual = (unsigned long)S3C_VA_TIMER,
96 .pfn = __phys_to_pfn(S5P_PA_TIMER),
97 .length = SZ_16K,
98 .type = MT_DEVICE,
99 }, {
100 .virtual = (unsigned long)S3C_VA_WATCHDOG,
101 .pfn = __phys_to_pfn(S3C_PA_WDT),
102 .length = SZ_4K,
103 .type = MT_DEVICE,
104 }, {
105 .virtual = (unsigned long)S5P_VA_SROMC,
106 .pfn = __phys_to_pfn(S5P_PA_SROMC),
107 .length = SZ_4K,
108 .type = MT_DEVICE,
109 },
110};
111
112/* read cpu identification code */
113
114void __init s5p_init_io(struct map_desc *mach_desc,
115 int size, void __iomem *cpuid_addr)
116{
117 unsigned long idcode;
118
119 /* initialize the io descriptors we need for initialization */
120 iotable_init(s5p_iodesc, ARRAY_SIZE(s5p_iodesc));
121 if (mach_desc)
122 iotable_init(mach_desc, size);
123
124 idcode = __raw_readl(cpuid_addr);
125 s3c_init_cpu(idcode, cpu_ids, ARRAY_SIZE(cpu_ids));
126}
diff --git a/arch/arm/plat-s5p/dev-csis0.c b/arch/arm/plat-s5p/dev-csis0.c
new file mode 100644
index 00000000000..e3aabef5e34
--- /dev/null
+++ b/arch/arm/plat-s5p/dev-csis0.c
@@ -0,0 +1,34 @@
1/*
2 * Copyright (C) 2010-2011 Samsung Electronics Co., Ltd.
3 *
4 * S5P series device definition for MIPI-CSIS channel 0
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9*/
10
11#include <linux/kernel.h>
12#include <linux/interrupt.h>
13#include <linux/platform_device.h>
14#include <mach/map.h>
15
16static struct resource s5p_mipi_csis0_resource[] = {
17 [0] = {
18 .start = S5P_PA_MIPI_CSIS0,
19 .end = S5P_PA_MIPI_CSIS0 + SZ_4K - 1,
20 .flags = IORESOURCE_MEM,
21 },
22 [1] = {
23 .start = IRQ_MIPI_CSIS0,
24 .end = IRQ_MIPI_CSIS0,
25 .flags = IORESOURCE_IRQ,
26 }
27};
28
29struct platform_device s5p_device_mipi_csis0 = {
30 .name = "s5p-mipi-csis",
31 .id = 0,
32 .num_resources = ARRAY_SIZE(s5p_mipi_csis0_resource),
33 .resource = s5p_mipi_csis0_resource,
34};
diff --git a/arch/arm/plat-s5p/dev-csis1.c b/arch/arm/plat-s5p/dev-csis1.c
new file mode 100644
index 00000000000..08b91b58020
--- /dev/null
+++ b/arch/arm/plat-s5p/dev-csis1.c
@@ -0,0 +1,34 @@
1/*
2 * Copyright (C) 2010-2011 Samsung Electronics Co., Ltd.
3 *
4 * S5P series device definition for MIPI-CSIS channel 1
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9*/
10
11#include <linux/kernel.h>
12#include <linux/interrupt.h>
13#include <linux/platform_device.h>
14#include <mach/map.h>
15
16static struct resource s5p_mipi_csis1_resource[] = {
17 [0] = {
18 .start = S5P_PA_MIPI_CSIS1,
19 .end = S5P_PA_MIPI_CSIS1 + SZ_4K - 1,
20 .flags = IORESOURCE_MEM,
21 },
22 [1] = {
23 .start = IRQ_MIPI_CSIS1,
24 .end = IRQ_MIPI_CSIS1,
25 .flags = IORESOURCE_IRQ,
26 },
27};
28
29struct platform_device s5p_device_mipi_csis1 = {
30 .name = "s5p-mipi-csis",
31 .id = 1,
32 .num_resources = ARRAY_SIZE(s5p_mipi_csis1_resource),
33 .resource = s5p_mipi_csis1_resource,
34};
diff --git a/arch/arm/plat-s5p/dev-ehci.c b/arch/arm/plat-s5p/dev-ehci.c
new file mode 100644
index 00000000000..94080fff9e9
--- /dev/null
+++ b/arch/arm/plat-s5p/dev-ehci.c
@@ -0,0 +1,57 @@
1/*
2 * Copyright (C) 2011 Samsung Electronics Co.Ltd
3 * Author: Joonyoung Shim <jy0922.shim@samsung.com>
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 *
10 */
11
12#include <linux/platform_device.h>
13#include <mach/irqs.h>
14#include <mach/map.h>
15#include <plat/devs.h>
16#include <plat/ehci.h>
17#include <plat/usb-phy.h>
18
19/* USB EHCI Host Controller registration */
20static struct resource s5p_ehci_resource[] = {
21 [0] = {
22 .start = S5P_PA_EHCI,
23 .end = S5P_PA_EHCI + SZ_256 - 1,
24 .flags = IORESOURCE_MEM,
25 },
26 [1] = {
27 .start = IRQ_USB_HOST,
28 .end = IRQ_USB_HOST,
29 .flags = IORESOURCE_IRQ,
30 }
31};
32
33static u64 s5p_device_ehci_dmamask = 0xffffffffUL;
34
35struct platform_device s5p_device_ehci = {
36 .name = "s5p-ehci",
37 .id = -1,
38 .num_resources = ARRAY_SIZE(s5p_ehci_resource),
39 .resource = s5p_ehci_resource,
40 .dev = {
41 .dma_mask = &s5p_device_ehci_dmamask,
42 .coherent_dma_mask = 0xffffffffUL
43 }
44};
45
46void __init s5p_ehci_set_platdata(struct s5p_ehci_platdata *pd)
47{
48 struct s5p_ehci_platdata *npd;
49
50 npd = s3c_set_platdata(pd, sizeof(struct s5p_ehci_platdata),
51 &s5p_device_ehci);
52
53 if (!npd->phy_init)
54 npd->phy_init = s5p_usb_phy_init;
55 if (!npd->phy_exit)
56 npd->phy_exit = s5p_usb_phy_exit;
57}
diff --git a/arch/arm/plat-s5p/dev-fimc0.c b/arch/arm/plat-s5p/dev-fimc0.c
new file mode 100644
index 00000000000..608770fc153
--- /dev/null
+++ b/arch/arm/plat-s5p/dev-fimc0.c
@@ -0,0 +1,43 @@
1/* linux/arch/arm/plat-s5p/dev-fimc0.c
2 *
3 * Copyright (c) 2010 Samsung Electronics
4 *
5 * Base S5P FIMC0 resource and device definitions
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>
13#include <linux/dma-mapping.h>
14#include <linux/platform_device.h>
15#include <linux/interrupt.h>
16#include <linux/ioport.h>
17#include <mach/map.h>
18
19static struct resource s5p_fimc0_resource[] = {
20 [0] = {
21 .start = S5P_PA_FIMC0,
22 .end = S5P_PA_FIMC0 + SZ_4K - 1,
23 .flags = IORESOURCE_MEM,
24 },
25 [1] = {
26 .start = IRQ_FIMC0,
27 .end = IRQ_FIMC0,
28 .flags = IORESOURCE_IRQ,
29 },
30};
31
32static u64 s5p_fimc0_dma_mask = DMA_BIT_MASK(32);
33
34struct platform_device s5p_device_fimc0 = {
35 .name = "s5p-fimc",
36 .id = 0,
37 .num_resources = ARRAY_SIZE(s5p_fimc0_resource),
38 .resource = s5p_fimc0_resource,
39 .dev = {
40 .dma_mask = &s5p_fimc0_dma_mask,
41 .coherent_dma_mask = DMA_BIT_MASK(32),
42 },
43};
diff --git a/arch/arm/plat-s5p/dev-fimc1.c b/arch/arm/plat-s5p/dev-fimc1.c
new file mode 100644
index 00000000000..76e3a97a87d
--- /dev/null
+++ b/arch/arm/plat-s5p/dev-fimc1.c
@@ -0,0 +1,43 @@
1/* linux/arch/arm/plat-s5p/dev-fimc1.c
2 *
3 * Copyright (c) 2010 Samsung Electronics
4 *
5 * Base S5P FIMC1 resource and device definitions
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>
13#include <linux/dma-mapping.h>
14#include <linux/platform_device.h>
15#include <linux/interrupt.h>
16#include <linux/ioport.h>
17#include <mach/map.h>
18
19static struct resource s5p_fimc1_resource[] = {
20 [0] = {
21 .start = S5P_PA_FIMC1,
22 .end = S5P_PA_FIMC1 + SZ_4K - 1,
23 .flags = IORESOURCE_MEM,
24 },
25 [1] = {
26 .start = IRQ_FIMC1,
27 .end = IRQ_FIMC1,
28 .flags = IORESOURCE_IRQ,
29 },
30};
31
32static u64 s5p_fimc1_dma_mask = DMA_BIT_MASK(32);
33
34struct platform_device s5p_device_fimc1 = {
35 .name = "s5p-fimc",
36 .id = 1,
37 .num_resources = ARRAY_SIZE(s5p_fimc1_resource),
38 .resource = s5p_fimc1_resource,
39 .dev = {
40 .dma_mask = &s5p_fimc1_dma_mask,
41 .coherent_dma_mask = DMA_BIT_MASK(32),
42 },
43};
diff --git a/arch/arm/plat-s5p/dev-fimc2.c b/arch/arm/plat-s5p/dev-fimc2.c
new file mode 100644
index 00000000000..24d29816fa2
--- /dev/null
+++ b/arch/arm/plat-s5p/dev-fimc2.c
@@ -0,0 +1,43 @@
1/* linux/arch/arm/plat-s5p/dev-fimc2.c
2 *
3 * Copyright (c) 2010 Samsung Electronics
4 *
5 * Base S5P FIMC2 resource and device definitions
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>
13#include <linux/dma-mapping.h>
14#include <linux/platform_device.h>
15#include <linux/interrupt.h>
16#include <linux/ioport.h>
17#include <mach/map.h>
18
19static struct resource s5p_fimc2_resource[] = {
20 [0] = {
21 .start = S5P_PA_FIMC2,
22 .end = S5P_PA_FIMC2 + SZ_4K - 1,
23 .flags = IORESOURCE_MEM,
24 },
25 [1] = {
26 .start = IRQ_FIMC2,
27 .end = IRQ_FIMC2,
28 .flags = IORESOURCE_IRQ,
29 },
30};
31
32static u64 s5p_fimc2_dma_mask = DMA_BIT_MASK(32);
33
34struct platform_device s5p_device_fimc2 = {
35 .name = "s5p-fimc",
36 .id = 2,
37 .num_resources = ARRAY_SIZE(s5p_fimc2_resource),
38 .resource = s5p_fimc2_resource,
39 .dev = {
40 .dma_mask = &s5p_fimc2_dma_mask,
41 .coherent_dma_mask = DMA_BIT_MASK(32),
42 },
43};
diff --git a/arch/arm/plat-s5p/dev-fimc3.c b/arch/arm/plat-s5p/dev-fimc3.c
new file mode 100644
index 00000000000..ef31beca386
--- /dev/null
+++ b/arch/arm/plat-s5p/dev-fimc3.c
@@ -0,0 +1,43 @@
1/* linux/arch/arm/plat-s5p/dev-fimc3.c
2 *
3 * Copyright (c) 2010 Samsung Electronics
4 *
5 * Base S5P FIMC3 resource and device definitions
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>
13#include <linux/dma-mapping.h>
14#include <linux/platform_device.h>
15#include <linux/interrupt.h>
16#include <linux/ioport.h>
17#include <mach/map.h>
18
19static struct resource s5p_fimc3_resource[] = {
20 [0] = {
21 .start = S5P_PA_FIMC3,
22 .end = S5P_PA_FIMC3 + SZ_4K - 1,
23 .flags = IORESOURCE_MEM,
24 },
25 [1] = {
26 .start = IRQ_FIMC3,
27 .end = IRQ_FIMC3,
28 .flags = IORESOURCE_IRQ,
29 },
30};
31
32static u64 s5p_fimc3_dma_mask = DMA_BIT_MASK(32);
33
34struct platform_device s5p_device_fimc3 = {
35 .name = "s5p-fimc",
36 .id = 3,
37 .num_resources = ARRAY_SIZE(s5p_fimc3_resource),
38 .resource = s5p_fimc3_resource,
39 .dev = {
40 .dma_mask = &s5p_fimc3_dma_mask,
41 .coherent_dma_mask = DMA_BIT_MASK(32),
42 },
43};
diff --git a/arch/arm/plat-s5p/dev-fimd0.c b/arch/arm/plat-s5p/dev-fimd0.c
new file mode 100644
index 00000000000..f728bb5abce
--- /dev/null
+++ b/arch/arm/plat-s5p/dev-fimd0.c
@@ -0,0 +1,67 @@
1/* linux/arch/arm/plat-s5p/dev-fimd0.c
2 *
3 * Copyright (c) 2009-2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * Core file for Samsung Display Controller (FIMD) driver
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/kernel.h>
14#include <linux/string.h>
15#include <linux/platform_device.h>
16#include <linux/fb.h>
17#include <linux/gfp.h>
18#include <linux/dma-mapping.h>
19
20#include <mach/irqs.h>
21#include <mach/map.h>
22
23#include <plat/fb.h>
24#include <plat/devs.h>
25#include <plat/cpu.h>
26
27static struct resource s5p_fimd0_resource[] = {
28 [0] = {
29 .start = S5P_PA_FIMD0,
30 .end = S5P_PA_FIMD0 + SZ_32K - 1,
31 .flags = IORESOURCE_MEM,
32 },
33 [1] = {
34 .start = IRQ_FIMD0_VSYNC,
35 .end = IRQ_FIMD0_VSYNC,
36 .flags = IORESOURCE_IRQ,
37 },
38 [2] = {
39 .start = IRQ_FIMD0_FIFO,
40 .end = IRQ_FIMD0_FIFO,
41 .flags = IORESOURCE_IRQ,
42 },
43 [3] = {
44 .start = IRQ_FIMD0_SYSTEM,
45 .end = IRQ_FIMD0_SYSTEM,
46 .flags = IORESOURCE_IRQ,
47 },
48};
49
50static u64 fimd0_dmamask = DMA_BIT_MASK(32);
51
52struct platform_device s5p_device_fimd0 = {
53 .name = "s5p-fb",
54 .id = 0,
55 .num_resources = ARRAY_SIZE(s5p_fimd0_resource),
56 .resource = s5p_fimd0_resource,
57 .dev = {
58 .dma_mask = &fimd0_dmamask,
59 .coherent_dma_mask = DMA_BIT_MASK(32),
60 },
61};
62
63void __init s5p_fimd0_set_platdata(struct s3c_fb_platdata *pd)
64{
65 s3c_set_platdata(pd, sizeof(struct s3c_fb_platdata),
66 &s5p_device_fimd0);
67}
diff --git a/arch/arm/plat-s5p/dev-mfc.c b/arch/arm/plat-s5p/dev-mfc.c
new file mode 100644
index 00000000000..94226a0010f
--- /dev/null
+++ b/arch/arm/plat-s5p/dev-mfc.c
@@ -0,0 +1,123 @@
1/* linux/arch/arm/plat-s5p/dev-mfc.c
2 *
3 * Copyright (C) 2010-2011 Samsung Electronics Co.Ltd
4 *
5 * Base S5P MFC resource and device definitions
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
13#include <linux/kernel.h>
14#include <linux/interrupt.h>
15#include <linux/platform_device.h>
16#include <linux/dma-mapping.h>
17#include <linux/memblock.h>
18#include <linux/ioport.h>
19
20#include <mach/map.h>
21#include <plat/devs.h>
22#include <plat/irqs.h>
23#include <plat/mfc.h>
24
25static struct resource s5p_mfc_resource[] = {
26 [0] = {
27 .start = S5P_PA_MFC,
28 .end = S5P_PA_MFC + SZ_64K - 1,
29 .flags = IORESOURCE_MEM,
30 },
31 [1] = {
32 .start = IRQ_MFC,
33 .end = IRQ_MFC,
34 .flags = IORESOURCE_IRQ,
35 }
36};
37
38struct platform_device s5p_device_mfc = {
39 .name = "s5p-mfc",
40 .id = -1,
41 .num_resources = ARRAY_SIZE(s5p_mfc_resource),
42 .resource = s5p_mfc_resource,
43};
44
45/*
46 * MFC hardware has 2 memory interfaces which are modelled as two separate
47 * platform devices to let dma-mapping distinguish between them.
48 *
49 * MFC parent device (s5p_device_mfc) must be registered before memory
50 * interface specific devices (s5p_device_mfc_l and s5p_device_mfc_r).
51 */
52
53static u64 s5p_mfc_dma_mask = DMA_BIT_MASK(32);
54
55struct platform_device s5p_device_mfc_l = {
56 .name = "s5p-mfc-l",
57 .id = -1,
58 .dev = {
59 .parent = &s5p_device_mfc.dev,
60 .dma_mask = &s5p_mfc_dma_mask,
61 .coherent_dma_mask = DMA_BIT_MASK(32),
62 },
63};
64
65struct platform_device s5p_device_mfc_r = {
66 .name = "s5p-mfc-r",
67 .id = -1,
68 .dev = {
69 .parent = &s5p_device_mfc.dev,
70 .dma_mask = &s5p_mfc_dma_mask,
71 .coherent_dma_mask = DMA_BIT_MASK(32),
72 },
73};
74
75struct s5p_mfc_reserved_mem {
76 phys_addr_t base;
77 unsigned long size;
78 struct device *dev;
79};
80
81static struct s5p_mfc_reserved_mem s5p_mfc_mem[2] __initdata;
82
83void __init s5p_mfc_reserve_mem(phys_addr_t rbase, unsigned int rsize,
84 phys_addr_t lbase, unsigned int lsize)
85{
86 int i;
87
88 s5p_mfc_mem[0].dev = &s5p_device_mfc_r.dev;
89 s5p_mfc_mem[0].base = rbase;
90 s5p_mfc_mem[0].size = rsize;
91
92 s5p_mfc_mem[1].dev = &s5p_device_mfc_l.dev;
93 s5p_mfc_mem[1].base = lbase;
94 s5p_mfc_mem[1].size = lsize;
95
96 for (i = 0; i < ARRAY_SIZE(s5p_mfc_mem); i++) {
97 struct s5p_mfc_reserved_mem *area = &s5p_mfc_mem[i];
98 if (memblock_remove(area->base, area->size)) {
99 printk(KERN_ERR "Failed to reserve memory for MFC device (%ld bytes at 0x%08lx)\n",
100 area->size, (unsigned long) area->base);
101 area->base = 0;
102 }
103 }
104}
105
106static int __init s5p_mfc_memory_init(void)
107{
108 int i;
109
110 for (i = 0; i < ARRAY_SIZE(s5p_mfc_mem); i++) {
111 struct s5p_mfc_reserved_mem *area = &s5p_mfc_mem[i];
112 if (!area->base)
113 continue;
114
115 if (dma_declare_coherent_memory(area->dev, area->base,
116 area->base, area->size,
117 DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE) == 0)
118 printk(KERN_ERR "Failed to declare coherent memory for MFC device (%ld bytes at 0x%08lx)\n",
119 area->size, (unsigned long) area->base);
120 }
121 return 0;
122}
123device_initcall(s5p_mfc_memory_init);
diff --git a/arch/arm/plat-s5p/dev-onenand.c b/arch/arm/plat-s5p/dev-onenand.c
new file mode 100644
index 00000000000..20336c8f247
--- /dev/null
+++ b/arch/arm/plat-s5p/dev-onenand.c
@@ -0,0 +1,45 @@
1/* linux/arch/arm/plat-s5p/dev-onenand.c
2 *
3 * Copyright 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * Copyright (c) 2008-2010 Samsung Electronics
7 * Kyungmin Park <kyungmin.park@samsung.com>
8 *
9 * S5P series device definition for OneNAND devices
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 */
15
16#include <linux/kernel.h>
17#include <linux/platform_device.h>
18
19#include <mach/irqs.h>
20#include <mach/map.h>
21
22static struct resource s5p_onenand_resources[] = {
23 [0] = {
24 .start = S5P_PA_ONENAND,
25 .end = S5P_PA_ONENAND + SZ_128K - 1,
26 .flags = IORESOURCE_MEM,
27 },
28 [1] = {
29 .start = S5P_PA_ONENAND_DMA,
30 .end = S5P_PA_ONENAND_DMA + SZ_8K - 1,
31 .flags = IORESOURCE_MEM,
32 },
33 [2] = {
34 .start = IRQ_ONENAND_AUDI,
35 .end = IRQ_ONENAND_AUDI,
36 .flags = IORESOURCE_IRQ,
37 },
38};
39
40struct platform_device s5p_device_onenand = {
41 .name = "s5pc110-onenand",
42 .id = -1,
43 .num_resources = ARRAY_SIZE(s5p_onenand_resources),
44 .resource = s5p_onenand_resources,
45};
diff --git a/arch/arm/plat-s5p/dev-pmu.c b/arch/arm/plat-s5p/dev-pmu.c
new file mode 100644
index 00000000000..a08576da72b
--- /dev/null
+++ b/arch/arm/plat-s5p/dev-pmu.c
@@ -0,0 +1,36 @@
1/*
2 * linux/arch/arm/plat-s5p/dev-pmu.c
3 *
4 * Copyright (C) 2010 Samsung Electronics Co.Ltd
5 * Author: Joonyoung Shim <jy0922.shim@samsung.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 *
12 */
13
14#include <linux/platform_device.h>
15#include <asm/pmu.h>
16#include <mach/irqs.h>
17
18static struct resource s5p_pmu_resource = {
19 .start = IRQ_PMU,
20 .end = IRQ_PMU,
21 .flags = IORESOURCE_IRQ,
22};
23
24struct platform_device s5p_device_pmu = {
25 .name = "arm-pmu",
26 .id = ARM_PMU_DEVICE_CPU,
27 .num_resources = 1,
28 .resource = &s5p_pmu_resource,
29};
30
31static int __init s5p_pmu_init(void)
32{
33 platform_device_register(&s5p_device_pmu);
34 return 0;
35}
36arch_initcall(s5p_pmu_init);
diff --git a/arch/arm/plat-s5p/dev-uart.c b/arch/arm/plat-s5p/dev-uart.c
new file mode 100644
index 00000000000..afaf87fdb93
--- /dev/null
+++ b/arch/arm/plat-s5p/dev-uart.c
@@ -0,0 +1,197 @@
1/* linux/arch/arm/plat-s5p/dev-uart.c
2 *
3 * Copyright (c) 2009 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * Base S5P UART resource and device definitions
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/kernel.h>
14#include <linux/types.h>
15#include <linux/interrupt.h>
16#include <linux/list.h>
17#include <linux/platform_device.h>
18
19#include <asm/mach/arch.h>
20#include <asm/mach/irq.h>
21#include <mach/hardware.h>
22#include <mach/map.h>
23
24#include <plat/devs.h>
25
26 /* Serial port registrations */
27
28static struct resource s5p_uart0_resource[] = {
29 [0] = {
30 .start = S5P_PA_UART0,
31 .end = S5P_PA_UART0 + S5P_SZ_UART - 1,
32 .flags = IORESOURCE_MEM,
33 },
34 [1] = {
35 .start = IRQ_S5P_UART_RX0,
36 .end = IRQ_S5P_UART_RX0,
37 .flags = IORESOURCE_IRQ,
38 },
39 [2] = {
40 .start = IRQ_S5P_UART_TX0,
41 .end = IRQ_S5P_UART_TX0,
42 .flags = IORESOURCE_IRQ,
43 },
44 [3] = {
45 .start = IRQ_S5P_UART_ERR0,
46 .end = IRQ_S5P_UART_ERR0,
47 .flags = IORESOURCE_IRQ,
48 }
49};
50
51static struct resource s5p_uart1_resource[] = {
52 [0] = {
53 .start = S5P_PA_UART1,
54 .end = S5P_PA_UART1 + S5P_SZ_UART - 1,
55 .flags = IORESOURCE_MEM,
56 },
57 [1] = {
58 .start = IRQ_S5P_UART_RX1,
59 .end = IRQ_S5P_UART_RX1,
60 .flags = IORESOURCE_IRQ,
61 },
62 [2] = {
63 .start = IRQ_S5P_UART_TX1,
64 .end = IRQ_S5P_UART_TX1,
65 .flags = IORESOURCE_IRQ,
66 },
67 [3] = {
68 .start = IRQ_S5P_UART_ERR1,
69 .end = IRQ_S5P_UART_ERR1,
70 .flags = IORESOURCE_IRQ,
71 },
72};
73
74static struct resource s5p_uart2_resource[] = {
75 [0] = {
76 .start = S5P_PA_UART2,
77 .end = S5P_PA_UART2 + S5P_SZ_UART - 1,
78 .flags = IORESOURCE_MEM,
79 },
80 [1] = {
81 .start = IRQ_S5P_UART_RX2,
82 .end = IRQ_S5P_UART_RX2,
83 .flags = IORESOURCE_IRQ,
84 },
85 [2] = {
86 .start = IRQ_S5P_UART_TX2,
87 .end = IRQ_S5P_UART_TX2,
88 .flags = IORESOURCE_IRQ,
89 },
90 [3] = {
91 .start = IRQ_S5P_UART_ERR2,
92 .end = IRQ_S5P_UART_ERR2,
93 .flags = IORESOURCE_IRQ,
94 },
95};
96
97static struct resource s5p_uart3_resource[] = {
98#if CONFIG_SERIAL_SAMSUNG_UARTS > 3
99 [0] = {
100 .start = S5P_PA_UART3,
101 .end = S5P_PA_UART3 + S5P_SZ_UART - 1,
102 .flags = IORESOURCE_MEM,
103 },
104 [1] = {
105 .start = IRQ_S5P_UART_RX3,
106 .end = IRQ_S5P_UART_RX3,
107 .flags = IORESOURCE_IRQ,
108 },
109 [2] = {
110 .start = IRQ_S5P_UART_TX3,
111 .end = IRQ_S5P_UART_TX3,
112 .flags = IORESOURCE_IRQ,
113 },
114 [3] = {
115 .start = IRQ_S5P_UART_ERR3,
116 .end = IRQ_S5P_UART_ERR3,
117 .flags = IORESOURCE_IRQ,
118 },
119#endif
120};
121
122static struct resource s5p_uart4_resource[] = {
123#if CONFIG_SERIAL_SAMSUNG_UARTS > 4
124 [0] = {
125 .start = S5P_PA_UART4,
126 .end = S5P_PA_UART4 + S5P_SZ_UART - 1,
127 .flags = IORESOURCE_MEM,
128 },
129 [1] = {
130 .start = IRQ_S5P_UART_RX4,
131 .end = IRQ_S5P_UART_RX4,
132 .flags = IORESOURCE_IRQ,
133 },
134 [2] = {
135 .start = IRQ_S5P_UART_TX4,
136 .end = IRQ_S5P_UART_TX4,
137 .flags = IORESOURCE_IRQ,
138 },
139 [3] = {
140 .start = IRQ_S5P_UART_ERR4,
141 .end = IRQ_S5P_UART_ERR4,
142 .flags = IORESOURCE_IRQ,
143 },
144#endif
145};
146
147static struct resource s5p_uart5_resource[] = {
148#if CONFIG_SERIAL_SAMSUNG_UARTS > 5
149 [0] = {
150 .start = S5P_PA_UART5,
151 .end = S5P_PA_UART5 + S5P_SZ_UART - 1,
152 .flags = IORESOURCE_MEM,
153 },
154 [1] = {
155 .start = IRQ_S5P_UART_RX5,
156 .end = IRQ_S5P_UART_RX5,
157 .flags = IORESOURCE_IRQ,
158 },
159 [2] = {
160 .start = IRQ_S5P_UART_TX5,
161 .end = IRQ_S5P_UART_TX5,
162 .flags = IORESOURCE_IRQ,
163 },
164 [3] = {
165 .start = IRQ_S5P_UART_ERR5,
166 .end = IRQ_S5P_UART_ERR5,
167 .flags = IORESOURCE_IRQ,
168 },
169#endif
170};
171
172struct s3c24xx_uart_resources s5p_uart_resources[] __initdata = {
173 [0] = {
174 .resources = s5p_uart0_resource,
175 .nr_resources = ARRAY_SIZE(s5p_uart0_resource),
176 },
177 [1] = {
178 .resources = s5p_uart1_resource,
179 .nr_resources = ARRAY_SIZE(s5p_uart1_resource),
180 },
181 [2] = {
182 .resources = s5p_uart2_resource,
183 .nr_resources = ARRAY_SIZE(s5p_uart2_resource),
184 },
185 [3] = {
186 .resources = s5p_uart3_resource,
187 .nr_resources = ARRAY_SIZE(s5p_uart3_resource),
188 },
189 [4] = {
190 .resources = s5p_uart4_resource,
191 .nr_resources = ARRAY_SIZE(s5p_uart4_resource),
192 },
193 [5] = {
194 .resources = s5p_uart5_resource,
195 .nr_resources = ARRAY_SIZE(s5p_uart5_resource),
196 },
197};
diff --git a/arch/arm/plat-s5p/include/plat/camport.h b/arch/arm/plat-s5p/include/plat/camport.h
new file mode 100644
index 00000000000..71688c8ba28
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/camport.h
@@ -0,0 +1,28 @@
1/*
2 * Copyright (C) 2011 Samsung Electronics Co., Ltd.
3 *
4 * S5P series camera interface helper functions
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#ifndef PLAT_S5P_CAMPORT_H_
12#define PLAT_S5P_CAMPORT_H_ __FILE__
13
14enum s5p_camport_id {
15 S5P_CAMPORT_A,
16 S5P_CAMPORT_B,
17};
18
19/*
20 * The helper functions to configure GPIO for the camera parallel bus.
21 * The camera port can be multiplexed with any FIMC entity, even multiple
22 * FIMC entities are allowed to be attached to a single port simultaneously.
23 * These functions are to be used in the board setup code.
24 */
25int s5pv210_fimc_setup_gpio(enum s5p_camport_id id);
26int exynos4_fimc_setup_gpio(enum s5p_camport_id id);
27
28#endif
diff --git a/arch/arm/plat-s5p/include/plat/ehci.h b/arch/arm/plat-s5p/include/plat/ehci.h
new file mode 100644
index 00000000000..6ae6810c756
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/ehci.h
@@ -0,0 +1,21 @@
1/*
2 * Copyright (C) 2011 Samsung Electronics Co.Ltd
3 * Author: Joonyoung Shim <jy0922.shim@samsung.com>
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 */
10
11#ifndef __PLAT_S5P_EHCI_H
12#define __PLAT_S5P_EHCI_H
13
14struct s5p_ehci_platdata {
15 int (*phy_init)(struct platform_device *pdev, int type);
16 int (*phy_exit)(struct platform_device *pdev, int type);
17};
18
19extern void s5p_ehci_set_platdata(struct s5p_ehci_platdata *pd);
20
21#endif /* __PLAT_S5P_EHCI_H */
diff --git a/arch/arm/plat-s5p/include/plat/exynos4.h b/arch/arm/plat-s5p/include/plat/exynos4.h
new file mode 100644
index 00000000000..907caab53dc
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/exynos4.h
@@ -0,0 +1,34 @@
1/* linux/arch/arm/plat-s5p/include/plat/exynos4.h
2 *
3 * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * Header file for exynos4 cpu 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/* Common init code for EXYNOS4 related SoCs */
14
15extern void exynos4_common_init_uarts(struct s3c2410_uartcfg *cfg, int no);
16extern void exynos4_register_clocks(void);
17extern void exynos4_setup_clocks(void);
18
19#ifdef CONFIG_CPU_EXYNOS4210
20
21extern int exynos4_init(void);
22extern void exynos4_init_irq(void);
23extern void exynos4_map_io(void);
24extern void exynos4_init_clocks(int xtal);
25extern struct sys_timer exynos4_timer;
26
27#define exynos4_init_uarts exynos4_common_init_uarts
28
29#else
30#define exynos4_init_clocks NULL
31#define exynos4_init_uarts NULL
32#define exynos4_map_io NULL
33#define exynos4_init NULL
34#endif
diff --git a/arch/arm/plat-s5p/include/plat/irqs.h b/arch/arm/plat-s5p/include/plat/irqs.h
new file mode 100644
index 00000000000..ba9121c60a2
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/irqs.h
@@ -0,0 +1,115 @@
1/* linux/arch/arm/plat-s5p/include/plat/irqs.h
2 *
3 * Copyright (c) 2009 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * S5P Common IRQ 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#ifndef __ASM_PLAT_S5P_IRQS_H
14#define __ASM_PLAT_S5P_IRQS_H __FILE__
15
16/* we keep the first set of CPU IRQs out of the range of
17 * the ISA space, so that the PC104 has them to itself
18 * and we don't end up having to do horrible things to the
19 * standard ISA drivers....
20 *
21 * note, since we're using the VICs, our start must be a
22 * mulitple of 32 to allow the common code to work
23 */
24
25#define S5P_IRQ_OFFSET (32)
26
27#define S5P_IRQ(x) ((x) + S5P_IRQ_OFFSET)
28
29#define S5P_VIC0_BASE S5P_IRQ(0)
30#define S5P_VIC1_BASE S5P_IRQ(32)
31#define S5P_VIC2_BASE S5P_IRQ(64)
32#define S5P_VIC3_BASE S5P_IRQ(96)
33
34#define VIC_BASE(x) (S5P_VIC0_BASE + ((x)*32))
35
36#define IRQ_VIC0_BASE S5P_VIC0_BASE
37#define IRQ_VIC1_BASE S5P_VIC1_BASE
38#define IRQ_VIC2_BASE S5P_VIC2_BASE
39
40/* UART interrupts, each UART has 4 intterupts per channel so
41 * use the space between the ISA and S3C main interrupts. Note, these
42 * are not in the same order as the S3C24XX series! */
43
44#define IRQ_S5P_UART_BASE0 (16)
45#define IRQ_S5P_UART_BASE1 (20)
46#define IRQ_S5P_UART_BASE2 (24)
47#define IRQ_S5P_UART_BASE3 (28)
48
49#define UART_IRQ_RXD (0)
50#define UART_IRQ_ERR (1)
51#define UART_IRQ_TXD (2)
52
53#define IRQ_S5P_UART_RX0 (IRQ_S5P_UART_BASE0 + UART_IRQ_RXD)
54#define IRQ_S5P_UART_TX0 (IRQ_S5P_UART_BASE0 + UART_IRQ_TXD)
55#define IRQ_S5P_UART_ERR0 (IRQ_S5P_UART_BASE0 + UART_IRQ_ERR)
56
57#define IRQ_S5P_UART_RX1 (IRQ_S5P_UART_BASE1 + UART_IRQ_RXD)
58#define IRQ_S5P_UART_TX1 (IRQ_S5P_UART_BASE1 + UART_IRQ_TXD)
59#define IRQ_S5P_UART_ERR1 (IRQ_S5P_UART_BASE1 + UART_IRQ_ERR)
60
61#define IRQ_S5P_UART_RX2 (IRQ_S5P_UART_BASE2 + UART_IRQ_RXD)
62#define IRQ_S5P_UART_TX2 (IRQ_S5P_UART_BASE2 + UART_IRQ_TXD)
63#define IRQ_S5P_UART_ERR2 (IRQ_S5P_UART_BASE2 + UART_IRQ_ERR)
64
65#define IRQ_S5P_UART_RX3 (IRQ_S5P_UART_BASE3 + UART_IRQ_RXD)
66#define IRQ_S5P_UART_TX3 (IRQ_S5P_UART_BASE3 + UART_IRQ_TXD)
67#define IRQ_S5P_UART_ERR3 (IRQ_S5P_UART_BASE3 + UART_IRQ_ERR)
68
69/* S3C compatibilty defines */
70#define IRQ_S3CUART_RX0 IRQ_S5P_UART_RX0
71#define IRQ_S3CUART_RX1 IRQ_S5P_UART_RX1
72#define IRQ_S3CUART_RX2 IRQ_S5P_UART_RX2
73#define IRQ_S3CUART_RX3 IRQ_S5P_UART_RX3
74
75/* VIC based IRQs */
76
77#define S5P_IRQ_VIC0(x) (S5P_VIC0_BASE + (x))
78#define S5P_IRQ_VIC1(x) (S5P_VIC1_BASE + (x))
79#define S5P_IRQ_VIC2(x) (S5P_VIC2_BASE + (x))
80#define S5P_IRQ_VIC3(x) (S5P_VIC3_BASE + (x))
81
82#define S5P_TIMER_IRQ(x) (11 + (x))
83
84#define IRQ_TIMER0 S5P_TIMER_IRQ(0)
85#define IRQ_TIMER1 S5P_TIMER_IRQ(1)
86#define IRQ_TIMER2 S5P_TIMER_IRQ(2)
87#define IRQ_TIMER3 S5P_TIMER_IRQ(3)
88#define IRQ_TIMER4 S5P_TIMER_IRQ(4)
89
90#define IRQ_EINT(x) ((x) < 16 ? ((x) + S5P_EINT_BASE1) \
91 : ((x) - 16 + S5P_EINT_BASE2))
92
93#define EINT_OFFSET(irq) ((irq) < S5P_EINT_BASE2 ? \
94 ((irq) - S5P_EINT_BASE1) : \
95 ((irq) + 16 - S5P_EINT_BASE2))
96
97#define IRQ_EINT_BIT(x) EINT_OFFSET(x)
98
99/* Typically only a few gpio chips require gpio interrupt support.
100 To avoid memory waste irq descriptors are allocated only for
101 S5P_GPIOINT_GROUP_COUNT chips, each with total number of
102 S5P_GPIOINT_GROUP_SIZE pins/irqs. Each GPIOINT group can be assiged
103 to any gpio chip with the s5p_register_gpio_interrupt() function */
104#define S5P_GPIOINT_GROUP_COUNT 4
105#define S5P_GPIOINT_GROUP_SIZE 8
106#define S5P_GPIOINT_COUNT (S5P_GPIOINT_GROUP_COUNT * S5P_GPIOINT_GROUP_SIZE)
107
108/* IRQ types common for all s5p platforms */
109#define S5P_IRQ_TYPE_LEVEL_LOW (0x00)
110#define S5P_IRQ_TYPE_LEVEL_HIGH (0x01)
111#define S5P_IRQ_TYPE_EDGE_FALLING (0x02)
112#define S5P_IRQ_TYPE_EDGE_RISING (0x03)
113#define S5P_IRQ_TYPE_EDGE_BOTH (0x04)
114
115#endif /* __ASM_PLAT_S5P_IRQS_H */
diff --git a/arch/arm/plat-s5p/include/plat/map-s5p.h b/arch/arm/plat-s5p/include/plat/map-s5p.h
new file mode 100644
index 00000000000..36d3551173b
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/map-s5p.h
@@ -0,0 +1,61 @@
1/* linux/arch/arm/plat-s5p/include/plat/map-s5p.h
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * S5P - Memory map definitions
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#ifndef __ASM_PLAT_MAP_S5P_H
14#define __ASM_PLAT_MAP_S5P_H __FILE__
15
16#define S5P_VA_CHIPID S3C_ADDR(0x02000000)
17#define S5P_VA_CMU S3C_ADDR(0x02100000)
18#define S5P_VA_PMU S3C_ADDR(0x02180000)
19#define S5P_VA_GPIO S3C_ADDR(0x02200000)
20#define S5P_VA_GPIO1 S5P_VA_GPIO
21#define S5P_VA_GPIO2 S3C_ADDR(0x02240000)
22#define S5P_VA_GPIO3 S3C_ADDR(0x02280000)
23
24#define S5P_VA_SYSRAM S3C_ADDR(0x02400000)
25#define S5P_VA_DMC0 S3C_ADDR(0x02440000)
26#define S5P_VA_DMC1 S3C_ADDR(0x02480000)
27#define S5P_VA_SROMC S3C_ADDR(0x024C0000)
28
29#define S5P_VA_SYSTIMER S3C_ADDR(0x02500000)
30#define S5P_VA_L2CC S3C_ADDR(0x02600000)
31
32#define S5P_VA_COMBINER_BASE S3C_ADDR(0x02700000)
33#define S5P_VA_COMBINER(x) (S5P_VA_COMBINER_BASE + ((x) >> 2) * 0x10)
34
35#define S5P_VA_COREPERI_BASE S3C_ADDR(0x02800000)
36#define S5P_VA_COREPERI(x) (S5P_VA_COREPERI_BASE + (x))
37#define S5P_VA_SCU S5P_VA_COREPERI(0x0)
38#define S5P_VA_TWD S5P_VA_COREPERI(0x600)
39
40#define S5P_VA_GIC_CPU S3C_ADDR(0x02810000)
41#define S5P_VA_GIC_DIST S3C_ADDR(0x02820000)
42
43#define S3C_VA_USB_HSPHY S3C_ADDR(0x02900000)
44
45#define VA_VIC(x) (S3C_VA_IRQ + ((x) * 0x10000))
46#define VA_VIC0 VA_VIC(0)
47#define VA_VIC1 VA_VIC(1)
48#define VA_VIC2 VA_VIC(2)
49#define VA_VIC3 VA_VIC(3)
50
51#define S5P_VA_UART(x) (S3C_VA_UART + ((x) * S3C_UART_OFFSET))
52#define S5P_VA_UART0 S5P_VA_UART(0)
53#define S5P_VA_UART1 S5P_VA_UART(1)
54#define S5P_VA_UART2 S5P_VA_UART(2)
55#define S5P_VA_UART3 S5P_VA_UART(3)
56
57#ifndef S3C_UART_OFFSET
58#define S3C_UART_OFFSET (0x400)
59#endif
60
61#endif /* __ASM_PLAT_MAP_S5P_H */
diff --git a/arch/arm/plat-s5p/include/plat/mfc.h b/arch/arm/plat-s5p/include/plat/mfc.h
new file mode 100644
index 00000000000..6697f8cb294
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/mfc.h
@@ -0,0 +1,27 @@
1/*
2 * Copyright (C) 2011 Samsung Electronics Co.Ltd
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 */
9
10#ifndef __PLAT_S5P_MFC_H
11#define __PLAT_S5P_MFC_H
12
13/**
14 * s5p_mfc_reserve_mem - function to early reserve memory for MFC driver
15 * @rbase: base address for MFC 'right' memory interface
16 * @rsize: size of the memory reserved for MFC 'right' interface
17 * @lbase: base address for MFC 'left' memory interface
18 * @lsize: size of the memory reserved for MFC 'left' interface
19 *
20 * This function reserves system memory for both MFC device memory
21 * interfaces and registers it to respective struct device entries as
22 * coherent memory.
23 */
24void __init s5p_mfc_reserve_mem(phys_addr_t rbase, unsigned int rsize,
25 phys_addr_t lbase, unsigned int lsize);
26
27#endif /* __PLAT_S5P_MFC_H */
diff --git a/arch/arm/plat-s5p/include/plat/mipi_csis.h b/arch/arm/plat-s5p/include/plat/mipi_csis.h
new file mode 100644
index 00000000000..9bd254c5ed2
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/mipi_csis.h
@@ -0,0 +1,43 @@
1/*
2 * Copyright (C) 2010-2011 Samsung Electronics Co., Ltd.
3 *
4 * S5P series MIPI CSI slave device support
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#ifndef PLAT_S5P_MIPI_CSIS_H_
12#define PLAT_S5P_MIPI_CSIS_H_ __FILE__
13
14struct platform_device;
15
16/**
17 * struct s5p_platform_mipi_csis - platform data for S5P MIPI-CSIS driver
18 * @clk_rate: bus clock frequency
19 * @lanes: number of data lanes used
20 * @alignment: data alignment in bits
21 * @hs_settle: HS-RX settle time
22 * @fixed_phy_vdd: false to enable external D-PHY regulator management in the
23 * driver or true in case this regulator has no enable function
24 * @phy_enable: pointer to a callback controlling D-PHY enable/reset
25 */
26struct s5p_platform_mipi_csis {
27 unsigned long clk_rate;
28 u8 lanes;
29 u8 alignment;
30 u8 hs_settle;
31 bool fixed_phy_vdd;
32 int (*phy_enable)(struct platform_device *pdev, bool on);
33};
34
35/**
36 * s5p_csis_phy_enable - global MIPI-CSI receiver D-PHY control
37 * @pdev: MIPI-CSIS platform device
38 * @on: true to enable D-PHY and deassert its reset
39 * false to disable D-PHY
40 */
41int s5p_csis_phy_enable(struct platform_device *pdev, bool on);
42
43#endif /* PLAT_S5P_MIPI_CSIS_H_ */
diff --git a/arch/arm/plat-s5p/include/plat/pll.h b/arch/arm/plat-s5p/include/plat/pll.h
new file mode 100644
index 00000000000..bf28fadee7a
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/pll.h
@@ -0,0 +1,153 @@
1/* arch/arm/plat-s5p/include/plat/pll.h
2 *
3 * Copyright (c) 2009 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * S5P PLL code
7 *
8 * Based on arch/arm/plat-s3c64xx/include/plat/pll.h
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13*/
14
15#define PLL45XX_MDIV_MASK (0x3FF)
16#define PLL45XX_PDIV_MASK (0x3F)
17#define PLL45XX_SDIV_MASK (0x7)
18#define PLL45XX_MDIV_SHIFT (16)
19#define PLL45XX_PDIV_SHIFT (8)
20#define PLL45XX_SDIV_SHIFT (0)
21
22#include <asm/div64.h>
23
24enum pll45xx_type_t {
25 pll_4500,
26 pll_4502,
27 pll_4508
28};
29
30static inline unsigned long s5p_get_pll45xx(unsigned long baseclk, u32 pll_con,
31 enum pll45xx_type_t pll_type)
32{
33 u32 mdiv, pdiv, sdiv;
34 u64 fvco = baseclk;
35
36 mdiv = (pll_con >> PLL45XX_MDIV_SHIFT) & PLL45XX_MDIV_MASK;
37 pdiv = (pll_con >> PLL45XX_PDIV_SHIFT) & PLL45XX_PDIV_MASK;
38 sdiv = (pll_con >> PLL45XX_SDIV_SHIFT) & PLL45XX_SDIV_MASK;
39
40 if (pll_type == pll_4508)
41 sdiv = sdiv - 1;
42
43 fvco *= mdiv;
44 do_div(fvco, (pdiv << sdiv));
45
46 return (unsigned long)fvco;
47}
48
49#define PLL46XX_KDIV_MASK (0xFFFF)
50#define PLL4650C_KDIV_MASK (0xFFF)
51#define PLL46XX_MDIV_MASK (0x1FF)
52#define PLL46XX_PDIV_MASK (0x3F)
53#define PLL46XX_SDIV_MASK (0x7)
54#define PLL46XX_MDIV_SHIFT (16)
55#define PLL46XX_PDIV_SHIFT (8)
56#define PLL46XX_SDIV_SHIFT (0)
57
58enum pll46xx_type_t {
59 pll_4600,
60 pll_4650,
61 pll_4650c,
62};
63
64static inline unsigned long s5p_get_pll46xx(unsigned long baseclk,
65 u32 pll_con0, u32 pll_con1,
66 enum pll46xx_type_t pll_type)
67{
68 unsigned long result;
69 u32 mdiv, pdiv, sdiv, kdiv;
70 u64 tmp;
71
72 mdiv = (pll_con0 >> PLL46XX_MDIV_SHIFT) & PLL46XX_MDIV_MASK;
73 pdiv = (pll_con0 >> PLL46XX_PDIV_SHIFT) & PLL46XX_PDIV_MASK;
74 sdiv = (pll_con0 >> PLL46XX_SDIV_SHIFT) & PLL46XX_SDIV_MASK;
75 kdiv = pll_con1 & PLL46XX_KDIV_MASK;
76
77 if (pll_type == pll_4650c)
78 kdiv = pll_con1 & PLL4650C_KDIV_MASK;
79 else
80 kdiv = pll_con1 & PLL46XX_KDIV_MASK;
81
82 tmp = baseclk;
83
84 if (pll_type == pll_4600) {
85 tmp *= (mdiv << 16) + kdiv;
86 do_div(tmp, (pdiv << sdiv));
87 result = tmp >> 16;
88 } else {
89 tmp *= (mdiv << 10) + kdiv;
90 do_div(tmp, (pdiv << sdiv));
91 result = tmp >> 10;
92 }
93
94 return result;
95}
96
97#define PLL90XX_MDIV_MASK (0xFF)
98#define PLL90XX_PDIV_MASK (0x3F)
99#define PLL90XX_SDIV_MASK (0x7)
100#define PLL90XX_KDIV_MASK (0xffff)
101#define PLL90XX_MDIV_SHIFT (16)
102#define PLL90XX_PDIV_SHIFT (8)
103#define PLL90XX_SDIV_SHIFT (0)
104#define PLL90XX_KDIV_SHIFT (0)
105
106static inline unsigned long s5p_get_pll90xx(unsigned long baseclk,
107 u32 pll_con, u32 pll_conk)
108{
109 unsigned long result;
110 u32 mdiv, pdiv, sdiv, kdiv;
111 u64 tmp;
112
113 mdiv = (pll_con >> PLL90XX_MDIV_SHIFT) & PLL90XX_MDIV_MASK;
114 pdiv = (pll_con >> PLL90XX_PDIV_SHIFT) & PLL90XX_PDIV_MASK;
115 sdiv = (pll_con >> PLL90XX_SDIV_SHIFT) & PLL90XX_SDIV_MASK;
116 kdiv = pll_conk & PLL90XX_KDIV_MASK;
117
118 /* We need to multiple baseclk by mdiv (the integer part) and kdiv
119 * which is in 2^16ths, so shift mdiv up (does not overflow) and
120 * add kdiv before multiplying. The use of tmp is to avoid any
121 * overflows before shifting bac down into result when multipling
122 * by the mdiv and kdiv pair.
123 */
124
125 tmp = baseclk;
126 tmp *= (mdiv << 16) + kdiv;
127 do_div(tmp, (pdiv << sdiv));
128 result = tmp >> 16;
129
130 return result;
131}
132
133#define PLL65XX_MDIV_MASK (0x3FF)
134#define PLL65XX_PDIV_MASK (0x3F)
135#define PLL65XX_SDIV_MASK (0x7)
136#define PLL65XX_MDIV_SHIFT (16)
137#define PLL65XX_PDIV_SHIFT (8)
138#define PLL65XX_SDIV_SHIFT (0)
139
140static inline unsigned long s5p_get_pll65xx(unsigned long baseclk, u32 pll_con)
141{
142 u32 mdiv, pdiv, sdiv;
143 u64 fvco = baseclk;
144
145 mdiv = (pll_con >> PLL65XX_MDIV_SHIFT) & PLL65XX_MDIV_MASK;
146 pdiv = (pll_con >> PLL65XX_PDIV_SHIFT) & PLL65XX_PDIV_MASK;
147 sdiv = (pll_con >> PLL65XX_SDIV_SHIFT) & PLL65XX_SDIV_MASK;
148
149 fvco *= mdiv;
150 do_div(fvco, (pdiv << sdiv));
151
152 return (unsigned long)fvco;
153}
diff --git a/arch/arm/plat-s5p/include/plat/regs-srom.h b/arch/arm/plat-s5p/include/plat/regs-srom.h
new file mode 100644
index 00000000000..f121ab5e76c
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/regs-srom.h
@@ -0,0 +1,54 @@
1/* linux/arch/arm/plat-s5p/include/plat/regs-srom.h
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * S5P SROMC register definitions
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#ifndef __ASM_PLAT_S5P_REGS_SROM_H
14#define __ASM_PLAT_S5P_REGS_SROM_H __FILE__
15
16#include <mach/map.h>
17
18#define S5P_SROMREG(x) (S5P_VA_SROMC + (x))
19
20#define S5P_SROM_BW S5P_SROMREG(0x0)
21#define S5P_SROM_BC0 S5P_SROMREG(0x4)
22#define S5P_SROM_BC1 S5P_SROMREG(0x8)
23#define S5P_SROM_BC2 S5P_SROMREG(0xc)
24#define S5P_SROM_BC3 S5P_SROMREG(0x10)
25#define S5P_SROM_BC4 S5P_SROMREG(0x14)
26#define S5P_SROM_BC5 S5P_SROMREG(0x18)
27
28/* one register BW holds 4 x 4-bit packed settings for NCS0 - NCS3 */
29
30#define S5P_SROM_BW__DATAWIDTH__SHIFT 0
31#define S5P_SROM_BW__ADDRMODE__SHIFT 1
32#define S5P_SROM_BW__WAITENABLE__SHIFT 2
33#define S5P_SROM_BW__BYTEENABLE__SHIFT 3
34
35#define S5P_SROM_BW__CS_MASK 0xf
36
37#define S5P_SROM_BW__NCS0__SHIFT 0
38#define S5P_SROM_BW__NCS1__SHIFT 4
39#define S5P_SROM_BW__NCS2__SHIFT 8
40#define S5P_SROM_BW__NCS3__SHIFT 12
41#define S5P_SROM_BW__NCS4__SHIFT 16
42#define S5P_SROM_BW__NCS5__SHIFT 20
43
44/* applies to same to BCS0 - BCS3 */
45
46#define S5P_SROM_BCX__PMC__SHIFT 0
47#define S5P_SROM_BCX__TACP__SHIFT 4
48#define S5P_SROM_BCX__TCAH__SHIFT 8
49#define S5P_SROM_BCX__TCOH__SHIFT 12
50#define S5P_SROM_BCX__TACC__SHIFT 16
51#define S5P_SROM_BCX__TCOS__SHIFT 24
52#define S5P_SROM_BCX__TACS__SHIFT 28
53
54#endif /* __ASM_PLAT_S5P_REGS_SROM_H */
diff --git a/arch/arm/plat-s5p/include/plat/reset.h b/arch/arm/plat-s5p/include/plat/reset.h
new file mode 100644
index 00000000000..335e97812ee
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/reset.h
@@ -0,0 +1,16 @@
1/* linux/arch/arm/plat-s5p/include/plat/reset.h
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9*/
10
11#ifndef __ASM_PLAT_S5P_RESET_H
12#define __ASM_PLAT_S5P_RESET_H __FILE__
13
14extern void (*s5p_reset_hook)(void);
15
16#endif /* __ASM_PLAT_S5P_RESET_H */
diff --git a/arch/arm/plat-s5p/include/plat/s5p-clock.h b/arch/arm/plat-s5p/include/plat/s5p-clock.h
new file mode 100644
index 00000000000..769b5bdfb04
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/s5p-clock.h
@@ -0,0 +1,55 @@
1/* linux/arch/arm/plat-s5p/include/plat/s5p-clock.h
2 *
3 * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * Header file for s5p clock 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#ifndef __ASM_PLAT_S5P_CLOCK_H
14#define __ASM_PLAT_S5P_CLOCK_H __FILE__
15
16#include <linux/clk.h>
17
18#define GET_DIV(clk, field) ((((clk) & field##_MASK) >> field##_SHIFT) + 1)
19
20#define clk_fin_apll clk_ext_xtal_mux
21#define clk_fin_mpll clk_ext_xtal_mux
22#define clk_fin_epll clk_ext_xtal_mux
23#define clk_fin_dpll clk_ext_xtal_mux
24#define clk_fin_vpll clk_ext_xtal_mux
25#define clk_fin_hpll clk_ext_xtal_mux
26
27extern struct clk clk_ext_xtal_mux;
28extern struct clk clk_xusbxti;
29extern struct clk clk_48m;
30extern struct clk s5p_clk_27m;
31extern struct clk clk_fout_apll;
32extern struct clk clk_fout_mpll;
33extern struct clk clk_fout_epll;
34extern struct clk clk_fout_dpll;
35extern struct clk clk_fout_vpll;
36extern struct clk clk_arm;
37extern struct clk clk_vpll;
38
39extern struct clksrc_sources clk_src_apll;
40extern struct clksrc_sources clk_src_mpll;
41extern struct clksrc_sources clk_src_epll;
42extern struct clksrc_sources clk_src_dpll;
43
44extern int s5p_gatectrl(void __iomem *reg, struct clk *clk, int enable);
45
46/* Common EPLL operations for S5P platform */
47extern int s5p_epll_enable(struct clk *clk, int enable);
48extern unsigned long s5p_epll_get_rate(struct clk *clk);
49
50/* SPDIF clk operations common for S5PC100/V210/C110 and Exynos4 */
51extern int s5p_spdif_set_rate(struct clk *clk, unsigned long rate);
52extern unsigned long s5p_spdif_get_rate(struct clk *clk);
53
54extern struct clk_ops s5p_sclk_spdif_ops;
55#endif /* __ASM_PLAT_S5P_CLOCK_H */
diff --git a/arch/arm/plat-s5p/include/plat/s5p-time.h b/arch/arm/plat-s5p/include/plat/s5p-time.h
new file mode 100644
index 00000000000..575e88109db
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/s5p-time.h
@@ -0,0 +1,40 @@
1/* linux/arch/arm/plat-s5p/include/plat/s5p-time.h
2 *
3 * Copyright 2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * Header file for s5p time 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#ifndef __ASM_PLAT_S5P_TIME_H
14#define __ASM_PLAT_S5P_TIME_H __FILE__
15
16/* S5P HR-Timer Clock mode */
17enum s5p_timer_mode {
18 S5P_PWM0,
19 S5P_PWM1,
20 S5P_PWM2,
21 S5P_PWM3,
22 S5P_PWM4,
23};
24
25struct s5p_timer_source {
26 unsigned int event_id;
27 unsigned int source_id;
28};
29
30/* Be able to sleep for atleast 4 seconds (usually more) */
31#define S5PTIMER_MIN_RANGE 4
32
33#define TCNT_MAX 0xffffffff
34#define NON_PERIODIC 0
35#define PERIODIC 1
36
37extern void __init s5p_set_timer_source(enum s5p_timer_mode event,
38 enum s5p_timer_mode source);
39extern struct sys_timer s5p_timer;
40#endif /* __ASM_PLAT_S5P_TIME_H */
diff --git a/arch/arm/plat-s5p/include/plat/s5p6440.h b/arch/arm/plat-s5p/include/plat/s5p6440.h
new file mode 100644
index 00000000000..528585d2caf
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/s5p6440.h
@@ -0,0 +1,36 @@
1/* arch/arm/plat-s5p/include/plat/s5p6440.h
2 *
3 * Copyright (c) 2009 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * Header file for s5p6440 cpu 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 /* Common init code for S5P6440 related SoCs */
14
15extern void s5p6440_register_clocks(void);
16extern void s5p6440_setup_clocks(void);
17
18#ifdef CONFIG_CPU_S5P6440
19
20extern int s5p64x0_init(void);
21extern void s5p6440_init_irq(void);
22extern void s5p6440_map_io(void);
23extern void s5p6440_init_clocks(int xtal);
24
25extern void s5p6440_init_uarts(struct s3c2410_uartcfg *cfg, int no);
26
27#else
28#define s5p6440_init_clocks NULL
29#define s5p6440_init_uarts NULL
30#define s5p6440_map_io NULL
31#define s5p64x0_init NULL
32#endif
33
34/* S5P6440 timer */
35
36extern struct sys_timer s5p6440_timer;
diff --git a/arch/arm/plat-s5p/include/plat/s5p6450.h b/arch/arm/plat-s5p/include/plat/s5p6450.h
new file mode 100644
index 00000000000..640a41c26be
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/s5p6450.h
@@ -0,0 +1,36 @@
1/* arch/arm/plat-s5p/include/plat/s5p6450.h
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * Header file for s5p6450 cpu 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/* Common init code for S5P6450 related SoCs */
14
15extern void s5p6450_register_clocks(void);
16extern void s5p6450_setup_clocks(void);
17
18#ifdef CONFIG_CPU_S5P6450
19
20extern int s5p64x0_init(void);
21extern void s5p6450_init_irq(void);
22extern void s5p6450_map_io(void);
23extern void s5p6450_init_clocks(int xtal);
24
25extern void s5p6450_init_uarts(struct s3c2410_uartcfg *cfg, int no);
26
27#else
28#define s5p6450_init_clocks NULL
29#define s5p6450_init_uarts NULL
30#define s5p6450_map_io NULL
31#define s5p64x0_init NULL
32#endif
33
34/* S5P6450 timer */
35
36extern struct sys_timer s5p6450_timer;
diff --git a/arch/arm/plat-s5p/include/plat/s5pc100.h b/arch/arm/plat-s5p/include/plat/s5pc100.h
new file mode 100644
index 00000000000..5f6099dd7ca
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/s5pc100.h
@@ -0,0 +1,33 @@
1/* arch/arm/plat-s5p/include/plat/s5pc100.h
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * Header file for s5pc100 cpu 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/* Common init code for S5PC100 related SoCs */
14
15extern void s5pc100_common_init_uarts(struct s3c2410_uartcfg *cfg, int no);
16extern void s5pc100_register_clocks(void);
17extern void s5pc100_setup_clocks(void);
18
19#ifdef CONFIG_CPU_S5PC100
20
21extern int s5pc100_init(void);
22extern void s5pc100_init_irq(void);
23extern void s5pc100_map_io(void);
24extern void s5pc100_init_clocks(int xtal);
25
26#define s5pc100_init_uarts s5pc100_common_init_uarts
27
28#else
29#define s5pc100_init_clocks NULL
30#define s5pc100_init_uarts NULL
31#define s5pc100_map_io NULL
32#define s5pc100_init NULL
33#endif
diff --git a/arch/arm/plat-s5p/include/plat/s5pv210.h b/arch/arm/plat-s5p/include/plat/s5pv210.h
new file mode 100644
index 00000000000..6c93a0c7810
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/s5pv210.h
@@ -0,0 +1,33 @@
1/* linux/arch/arm/plat-s5p/include/plat/s5pv210.h
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * Header file for s5pv210 cpu 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/* Common init code for S5PV210 related SoCs */
14
15extern void s5pv210_common_init_uarts(struct s3c2410_uartcfg *cfg, int no);
16extern void s5pv210_register_clocks(void);
17extern void s5pv210_setup_clocks(void);
18
19#ifdef CONFIG_CPU_S5PV210
20
21extern int s5pv210_init(void);
22extern void s5pv210_init_irq(void);
23extern void s5pv210_map_io(void);
24extern void s5pv210_init_clocks(int xtal);
25
26#define s5pv210_init_uarts s5pv210_common_init_uarts
27
28#else
29#define s5pv210_init_clocks NULL
30#define s5pv210_init_uarts NULL
31#define s5pv210_map_io NULL
32#define s5pv210_init NULL
33#endif
diff --git a/arch/arm/plat-s5p/include/plat/sysmmu.h b/arch/arm/plat-s5p/include/plat/sysmmu.h
new file mode 100644
index 00000000000..bf5283c2a19
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/sysmmu.h
@@ -0,0 +1,95 @@
1/* linux/arch/arm/plat-s5p/include/plat/sysmmu.h
2 *
3 * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * Samsung System MMU driver for S5P platform
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#ifndef __ASM__PLAT_SYSMMU_H
14#define __ASM__PLAT_SYSMMU_H __FILE__
15
16enum S5P_SYSMMU_INTERRUPT_TYPE {
17 SYSMMU_PAGEFAULT,
18 SYSMMU_AR_MULTIHIT,
19 SYSMMU_AW_MULTIHIT,
20 SYSMMU_BUSERROR,
21 SYSMMU_AR_SECURITY,
22 SYSMMU_AR_ACCESS,
23 SYSMMU_AW_SECURITY,
24 SYSMMU_AW_PROTECTION, /* 7 */
25 SYSMMU_FAULTS_NUM
26};
27
28#ifdef CONFIG_S5P_SYSTEM_MMU
29
30#include <mach/sysmmu.h>
31
32/**
33 * s5p_sysmmu_enable() - enable system mmu of ip
34 * @ips: The ip connected system mmu.
35 * #pgd: Base physical address of the 1st level page table
36 *
37 * This function enable system mmu to transfer address
38 * from virtual address to physical address
39 */
40void s5p_sysmmu_enable(sysmmu_ips ips, unsigned long pgd);
41
42/**
43 * s5p_sysmmu_disable() - disable sysmmu mmu of ip
44 * @ips: The ip connected system mmu.
45 *
46 * This function disable system mmu to transfer address
47 * from virtual address to physical address
48 */
49void s5p_sysmmu_disable(sysmmu_ips ips);
50
51/**
52 * s5p_sysmmu_set_tablebase_pgd() - set page table base address to refer page table
53 * @ips: The ip connected system mmu.
54 * @pgd: The page table base address.
55 *
56 * This function set page table base address
57 * When system mmu transfer address from virtaul address to physical address,
58 * system mmu refer address information from page table
59 */
60void s5p_sysmmu_set_tablebase_pgd(sysmmu_ips ips, unsigned long pgd);
61
62/**
63 * s5p_sysmmu_tlb_invalidate() - flush all TLB entry in system mmu
64 * @ips: The ip connected system mmu.
65 *
66 * This function flush all TLB entry in system mmu
67 */
68void s5p_sysmmu_tlb_invalidate(sysmmu_ips ips);
69
70/** s5p_sysmmu_set_fault_handler() - Fault handler for System MMUs
71 * @itype: type of fault.
72 * @pgtable_base: the physical address of page table base. This is 0 if @ips is
73 * SYSMMU_BUSERROR.
74 * @fault_addr: the device (virtual) address that the System MMU tried to
75 * translated. This is 0 if @ips is SYSMMU_BUSERROR.
76 * Called when interrupt occurred by the System MMUs
77 * The device drivers of peripheral devices that has a System MMU can implement
78 * a fault handler to resolve address translation fault by System MMU.
79 * The meanings of return value and parameters are described below.
80
81 * return value: non-zero if the fault is correctly resolved.
82 * zero if the fault is not handled.
83 */
84void s5p_sysmmu_set_fault_handler(sysmmu_ips ips,
85 int (*handler)(enum S5P_SYSMMU_INTERRUPT_TYPE itype,
86 unsigned long pgtable_base,
87 unsigned long fault_addr));
88#else
89#define s5p_sysmmu_enable(ips, pgd) do { } while (0)
90#define s5p_sysmmu_disable(ips) do { } while (0)
91#define s5p_sysmmu_set_tablebase_pgd(ips, pgd) do { } while (0)
92#define s5p_sysmmu_tlb_invalidate(ips) do { } while (0)
93#define s5p_sysmmu_set_fault_handler(ips, handler) do { } while (0)
94#endif
95#endif /* __ASM_PLAT_SYSMMU_H */
diff --git a/arch/arm/plat-s5p/include/plat/system-reset.h b/arch/arm/plat-s5p/include/plat/system-reset.h
new file mode 100644
index 00000000000..f307f34e642
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/system-reset.h
@@ -0,0 +1,31 @@
1/* linux/arch/arm/plat-s5p/include/plat/system-reset.h
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * Based on arch/arm/mach-s3c2410/include/mach/system-reset.h
7 *
8 * S5P - System define for arch_reset()
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13*/
14
15#include <plat/watchdog-reset.h>
16
17void (*s5p_reset_hook)(void);
18
19static void arch_reset(char mode, const char *cmd)
20{
21 /* SWRESET support in s5p_reset_hook() */
22
23 if (s5p_reset_hook)
24 s5p_reset_hook();
25
26 /* Perform reset using Watchdog reset
27 * if there is no s5p_reset_hook()
28 */
29
30 arch_wdt_reset();
31}
diff --git a/arch/arm/plat-s5p/include/plat/usb-phy.h b/arch/arm/plat-s5p/include/plat/usb-phy.h
new file mode 100644
index 00000000000..6dd6bcfca3c
--- /dev/null
+++ b/arch/arm/plat-s5p/include/plat/usb-phy.h
@@ -0,0 +1,22 @@
1/*
2 * Copyright (C) 2011 Samsung Electronics Co.Ltd
3 * Author: Joonyoung Shim <jy0922.shim@samsung.com>
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 */
10
11#ifndef __PLAT_S5P_USB_PHY_H
12#define __PLAT_S5P_USB_PHY_H
13
14enum s5p_usb_phy_type {
15 S5P_USB_PHY_DEVICE,
16 S5P_USB_PHY_HOST,
17};
18
19extern int s5p_usb_phy_init(struct platform_device *pdev, int type);
20extern int s5p_usb_phy_exit(struct platform_device *pdev, int type);
21
22#endif /* __PLAT_S5P_REGS_USB_PHY_H */
diff --git a/arch/arm/plat-s5p/irq-eint.c b/arch/arm/plat-s5p/irq-eint.c
new file mode 100644
index 00000000000..b5bb774985b
--- /dev/null
+++ b/arch/arm/plat-s5p/irq-eint.c
@@ -0,0 +1,219 @@
1/* linux/arch/arm/plat-s5p/irq-eint.c
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * S5P - IRQ EINT 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/kernel.h>
14#include <linux/interrupt.h>
15#include <linux/irq.h>
16#include <linux/io.h>
17#include <linux/sysdev.h>
18#include <linux/gpio.h>
19
20#include <asm/hardware/vic.h>
21
22#include <plat/regs-irqtype.h>
23
24#include <mach/map.h>
25#include <plat/cpu.h>
26#include <plat/pm.h>
27
28#include <plat/gpio-cfg.h>
29#include <mach/regs-gpio.h>
30
31static inline void s5p_irq_eint_mask(struct irq_data *data)
32{
33 u32 mask;
34
35 mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(data->irq)));
36 mask |= eint_irq_to_bit(data->irq);
37 __raw_writel(mask, S5P_EINT_MASK(EINT_REG_NR(data->irq)));
38}
39
40static void s5p_irq_eint_unmask(struct irq_data *data)
41{
42 u32 mask;
43
44 mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(data->irq)));
45 mask &= ~(eint_irq_to_bit(data->irq));
46 __raw_writel(mask, S5P_EINT_MASK(EINT_REG_NR(data->irq)));
47}
48
49static inline void s5p_irq_eint_ack(struct irq_data *data)
50{
51 __raw_writel(eint_irq_to_bit(data->irq),
52 S5P_EINT_PEND(EINT_REG_NR(data->irq)));
53}
54
55static void s5p_irq_eint_maskack(struct irq_data *data)
56{
57 /* compiler should in-line these */
58 s5p_irq_eint_mask(data);
59 s5p_irq_eint_ack(data);
60}
61
62static int s5p_irq_eint_set_type(struct irq_data *data, unsigned int type)
63{
64 int offs = EINT_OFFSET(data->irq);
65 int shift;
66 u32 ctrl, mask;
67 u32 newvalue = 0;
68
69 switch (type) {
70 case IRQ_TYPE_EDGE_RISING:
71 newvalue = S5P_IRQ_TYPE_EDGE_RISING;
72 break;
73
74 case IRQ_TYPE_EDGE_FALLING:
75 newvalue = S5P_IRQ_TYPE_EDGE_FALLING;
76 break;
77
78 case IRQ_TYPE_EDGE_BOTH:
79 newvalue = S5P_IRQ_TYPE_EDGE_BOTH;
80 break;
81
82 case IRQ_TYPE_LEVEL_LOW:
83 newvalue = S5P_IRQ_TYPE_LEVEL_LOW;
84 break;
85
86 case IRQ_TYPE_LEVEL_HIGH:
87 newvalue = S5P_IRQ_TYPE_LEVEL_HIGH;
88 break;
89
90 default:
91 printk(KERN_ERR "No such irq type %d", type);
92 return -EINVAL;
93 }
94
95 shift = (offs & 0x7) * 4;
96 mask = 0x7 << shift;
97
98 ctrl = __raw_readl(S5P_EINT_CON(EINT_REG_NR(data->irq)));
99 ctrl &= ~mask;
100 ctrl |= newvalue << shift;
101 __raw_writel(ctrl, S5P_EINT_CON(EINT_REG_NR(data->irq)));
102
103 if ((0 <= offs) && (offs < 8))
104 s3c_gpio_cfgpin(EINT_GPIO_0(offs & 0x7), EINT_MODE);
105
106 else if ((8 <= offs) && (offs < 16))
107 s3c_gpio_cfgpin(EINT_GPIO_1(offs & 0x7), EINT_MODE);
108
109 else if ((16 <= offs) && (offs < 24))
110 s3c_gpio_cfgpin(EINT_GPIO_2(offs & 0x7), EINT_MODE);
111
112 else if ((24 <= offs) && (offs < 32))
113 s3c_gpio_cfgpin(EINT_GPIO_3(offs & 0x7), EINT_MODE);
114
115 else
116 printk(KERN_ERR "No such irq number %d", offs);
117
118 return 0;
119}
120
121static struct irq_chip s5p_irq_eint = {
122 .name = "s5p-eint",
123 .irq_mask = s5p_irq_eint_mask,
124 .irq_unmask = s5p_irq_eint_unmask,
125 .irq_mask_ack = s5p_irq_eint_maskack,
126 .irq_ack = s5p_irq_eint_ack,
127 .irq_set_type = s5p_irq_eint_set_type,
128#ifdef CONFIG_PM
129 .irq_set_wake = s3c_irqext_wake,
130#endif
131};
132
133/* s5p_irq_demux_eint
134 *
135 * This function demuxes the IRQ from the group0 external interrupts,
136 * from EINTs 16 to 31. It is designed to be inlined into the specific
137 * handler s5p_irq_demux_eintX_Y.
138 *
139 * Each EINT pend/mask registers handle eight of them.
140 */
141static inline void s5p_irq_demux_eint(unsigned int start)
142{
143 u32 status = __raw_readl(S5P_EINT_PEND(EINT_REG_NR(start)));
144 u32 mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(start)));
145 unsigned int irq;
146
147 status &= ~mask;
148 status &= 0xff;
149
150 while (status) {
151 irq = fls(status) - 1;
152 generic_handle_irq(irq + start);
153 status &= ~(1 << irq);
154 }
155}
156
157static void s5p_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc)
158{
159 s5p_irq_demux_eint(IRQ_EINT(16));
160 s5p_irq_demux_eint(IRQ_EINT(24));
161}
162
163static inline void s5p_irq_vic_eint_mask(struct irq_data *data)
164{
165 void __iomem *base = irq_data_get_irq_chip_data(data);
166
167 s5p_irq_eint_mask(data);
168 writel(1 << EINT_OFFSET(data->irq), base + VIC_INT_ENABLE_CLEAR);
169}
170
171static void s5p_irq_vic_eint_unmask(struct irq_data *data)
172{
173 void __iomem *base = irq_data_get_irq_chip_data(data);
174
175 s5p_irq_eint_unmask(data);
176 writel(1 << EINT_OFFSET(data->irq), base + VIC_INT_ENABLE);
177}
178
179static inline void s5p_irq_vic_eint_ack(struct irq_data *data)
180{
181 __raw_writel(eint_irq_to_bit(data->irq),
182 S5P_EINT_PEND(EINT_REG_NR(data->irq)));
183}
184
185static void s5p_irq_vic_eint_maskack(struct irq_data *data)
186{
187 s5p_irq_vic_eint_mask(data);
188 s5p_irq_vic_eint_ack(data);
189}
190
191static struct irq_chip s5p_irq_vic_eint = {
192 .name = "s5p_vic_eint",
193 .irq_mask = s5p_irq_vic_eint_mask,
194 .irq_unmask = s5p_irq_vic_eint_unmask,
195 .irq_mask_ack = s5p_irq_vic_eint_maskack,
196 .irq_ack = s5p_irq_vic_eint_ack,
197 .irq_set_type = s5p_irq_eint_set_type,
198#ifdef CONFIG_PM
199 .irq_set_wake = s3c_irqext_wake,
200#endif
201};
202
203int __init s5p_init_irq_eint(void)
204{
205 int irq;
206
207 for (irq = IRQ_EINT(0); irq <= IRQ_EINT(15); irq++)
208 irq_set_chip(irq, &s5p_irq_vic_eint);
209
210 for (irq = IRQ_EINT(16); irq <= IRQ_EINT(31); irq++) {
211 irq_set_chip_and_handler(irq, &s5p_irq_eint, handle_level_irq);
212 set_irq_flags(irq, IRQF_VALID);
213 }
214
215 irq_set_chained_handler(IRQ_EINT16_31, s5p_irq_demux_eint16_31);
216 return 0;
217}
218
219arch_initcall(s5p_init_irq_eint);
diff --git a/arch/arm/plat-s5p/irq-gpioint.c b/arch/arm/plat-s5p/irq-gpioint.c
new file mode 100644
index 00000000000..c65eb791d1b
--- /dev/null
+++ b/arch/arm/plat-s5p/irq-gpioint.c
@@ -0,0 +1,216 @@
1/* linux/arch/arm/plat-s5p/irq-gpioint.c
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * Author: Kyungmin Park <kyungmin.park@samsung.com>
5 * Author: Joonyoung Shim <jy0922.shim@samsung.com>
6 * Author: Marek Szyprowski <m.szyprowski@samsung.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 *
13 */
14
15#include <linux/kernel.h>
16#include <linux/interrupt.h>
17#include <linux/irq.h>
18#include <linux/io.h>
19#include <linux/gpio.h>
20#include <linux/slab.h>
21
22#include <mach/map.h>
23#include <plat/gpio-core.h>
24#include <plat/gpio-cfg.h>
25
26#include <asm/mach/irq.h>
27
28#define GPIO_BASE(chip) (((unsigned long)(chip)->base) & 0xFFFFF000u)
29
30#define CON_OFFSET 0x700
31#define MASK_OFFSET 0x900
32#define PEND_OFFSET 0xA00
33#define REG_OFFSET(x) ((x) << 2)
34
35struct s5p_gpioint_bank {
36 struct list_head list;
37 int start;
38 int nr_groups;
39 int irq;
40 struct s3c_gpio_chip **chips;
41 void (*handler)(unsigned int, struct irq_desc *);
42};
43
44LIST_HEAD(banks);
45
46static int s5p_gpioint_set_type(struct irq_data *d, unsigned int type)
47{
48 struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
49 struct irq_chip_type *ct = gc->chip_types;
50 unsigned int shift = (d->irq - gc->irq_base) << 2;
51
52 switch (type) {
53 case IRQ_TYPE_EDGE_RISING:
54 type = S5P_IRQ_TYPE_EDGE_RISING;
55 break;
56 case IRQ_TYPE_EDGE_FALLING:
57 type = S5P_IRQ_TYPE_EDGE_FALLING;
58 break;
59 case IRQ_TYPE_EDGE_BOTH:
60 type = S5P_IRQ_TYPE_EDGE_BOTH;
61 break;
62 case IRQ_TYPE_LEVEL_HIGH:
63 type = S5P_IRQ_TYPE_LEVEL_HIGH;
64 break;
65 case IRQ_TYPE_LEVEL_LOW:
66 type = S5P_IRQ_TYPE_LEVEL_LOW;
67 break;
68 case IRQ_TYPE_NONE:
69 default:
70 printk(KERN_WARNING "No irq type\n");
71 return -EINVAL;
72 }
73
74 gc->type_cache &= ~(0x7 << shift);
75 gc->type_cache |= type << shift;
76 writel(gc->type_cache, gc->reg_base + ct->regs.type);
77 return 0;
78}
79
80static void s5p_gpioint_handler(unsigned int irq, struct irq_desc *desc)
81{
82 struct s5p_gpioint_bank *bank = irq_get_handler_data(irq);
83 int group, pend_offset, mask_offset;
84 unsigned int pend, mask;
85
86 struct irq_chip *chip = irq_get_chip(irq);
87 chained_irq_enter(chip, desc);
88
89 for (group = 0; group < bank->nr_groups; group++) {
90 struct s3c_gpio_chip *chip = bank->chips[group];
91 if (!chip)
92 continue;
93
94 pend_offset = REG_OFFSET(group);
95 pend = __raw_readl(GPIO_BASE(chip) + PEND_OFFSET + pend_offset);
96 if (!pend)
97 continue;
98
99 mask_offset = REG_OFFSET(group);
100 mask = __raw_readl(GPIO_BASE(chip) + MASK_OFFSET + mask_offset);
101 pend &= ~mask;
102
103 while (pend) {
104 int offset = fls(pend) - 1;
105 int real_irq = chip->irq_base + offset;
106 generic_handle_irq(real_irq);
107 pend &= ~BIT(offset);
108 }
109 }
110 chained_irq_exit(chip, desc);
111}
112
113static __init int s5p_gpioint_add(struct s3c_gpio_chip *chip)
114{
115 static int used_gpioint_groups = 0;
116 int group = chip->group;
117 struct s5p_gpioint_bank *b, *bank = NULL;
118 struct irq_chip_generic *gc;
119 struct irq_chip_type *ct;
120
121 if (used_gpioint_groups >= S5P_GPIOINT_GROUP_COUNT)
122 return -ENOMEM;
123
124 list_for_each_entry(b, &banks, list) {
125 if (group >= b->start && group < b->start + b->nr_groups) {
126 bank = b;
127 break;
128 }
129 }
130 if (!bank)
131 return -EINVAL;
132
133 if (!bank->handler) {
134 bank->chips = kzalloc(sizeof(struct s3c_gpio_chip *) *
135 bank->nr_groups, GFP_KERNEL);
136 if (!bank->chips)
137 return -ENOMEM;
138
139 irq_set_chained_handler(bank->irq, s5p_gpioint_handler);
140 irq_set_handler_data(bank->irq, bank);
141 bank->handler = s5p_gpioint_handler;
142 printk(KERN_INFO "Registered chained gpio int handler for interrupt %d.\n",
143 bank->irq);
144 }
145
146 /*
147 * chained GPIO irq has been successfully registered, allocate new gpio
148 * int group and assign irq nubmers
149 */
150 chip->irq_base = S5P_GPIOINT_BASE +
151 used_gpioint_groups * S5P_GPIOINT_GROUP_SIZE;
152 used_gpioint_groups++;
153
154 bank->chips[group - bank->start] = chip;
155
156 gc = irq_alloc_generic_chip("s5p_gpioint", 1, chip->irq_base,
157 (void __iomem *)GPIO_BASE(chip),
158 handle_level_irq);
159 if (!gc)
160 return -ENOMEM;
161 ct = gc->chip_types;
162 ct->chip.irq_ack = irq_gc_ack_set_bit;
163 ct->chip.irq_mask = irq_gc_mask_set_bit;
164 ct->chip.irq_unmask = irq_gc_mask_clr_bit;
165 ct->chip.irq_set_type = s5p_gpioint_set_type,
166 ct->regs.ack = PEND_OFFSET + REG_OFFSET(group - bank->start);
167 ct->regs.mask = MASK_OFFSET + REG_OFFSET(group - bank->start);
168 ct->regs.type = CON_OFFSET + REG_OFFSET(group - bank->start);
169 irq_setup_generic_chip(gc, IRQ_MSK(chip->chip.ngpio),
170 IRQ_GC_INIT_MASK_CACHE,
171 IRQ_NOREQUEST | IRQ_NOPROBE, 0);
172 return 0;
173}
174
175int __init s5p_register_gpio_interrupt(int pin)
176{
177 struct s3c_gpio_chip *my_chip = s3c_gpiolib_getchip(pin);
178 int offset, group;
179 int ret;
180
181 if (!my_chip)
182 return -EINVAL;
183
184 offset = pin - my_chip->chip.base;
185 group = my_chip->group;
186
187 /* check if the group has been already registered */
188 if (my_chip->irq_base)
189 return my_chip->irq_base + offset;
190
191 /* register gpio group */
192 ret = s5p_gpioint_add(my_chip);
193 if (ret == 0) {
194 my_chip->chip.to_irq = samsung_gpiolib_to_irq;
195 printk(KERN_INFO "Registered interrupt support for gpio group %d.\n",
196 group);
197 return my_chip->irq_base + offset;
198 }
199 return ret;
200}
201
202int __init s5p_register_gpioint_bank(int chain_irq, int start, int nr_groups)
203{
204 struct s5p_gpioint_bank *bank;
205
206 bank = kzalloc(sizeof(*bank), GFP_KERNEL);
207 if (!bank)
208 return -ENOMEM;
209
210 bank->start = start;
211 bank->nr_groups = nr_groups;
212 bank->irq = chain_irq;
213
214 list_add_tail(&bank->list, &banks);
215 return 0;
216}
diff --git a/arch/arm/plat-s5p/irq-pm.c b/arch/arm/plat-s5p/irq-pm.c
new file mode 100644
index 00000000000..327acb3a446
--- /dev/null
+++ b/arch/arm/plat-s5p/irq-pm.c
@@ -0,0 +1,90 @@
1/* linux/arch/arm/plat-s5p/irq-pm.c
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * Based on arch/arm/plat-s3c24xx/irq-pm.c,
7 * Copyright (c) 2003,2004 Simtec Electronics
8 * Ben Dooks <ben@simtec.co.uk>
9 * http://armlinux.simtec.co.uk/
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14*/
15
16#include <linux/init.h>
17#include <linux/module.h>
18#include <linux/interrupt.h>
19
20#include <plat/cpu.h>
21#include <plat/irqs.h>
22#include <plat/pm.h>
23#include <mach/map.h>
24
25#include <mach/regs-gpio.h>
26#include <mach/regs-irq.h>
27
28/* state for IRQs over sleep */
29
30/* default is to allow for EINT0..EINT31, and IRQ_RTC_TIC, IRQ_RTC_ALARM,
31 * as wakeup sources
32 *
33 * set bit to 1 in allow bitfield to enable the wakeup settings on it
34*/
35
36unsigned long s3c_irqwake_intallow = 0x00000006L;
37unsigned long s3c_irqwake_eintallow = 0xffffffffL;
38
39int s3c_irq_wake(struct irq_data *data, unsigned int state)
40{
41 unsigned long irqbit;
42
43 switch (data->irq) {
44 case IRQ_RTC_TIC:
45 case IRQ_RTC_ALARM:
46 irqbit = 1 << (data->irq + 1 - IRQ_RTC_ALARM);
47 if (!state)
48 s3c_irqwake_intmask |= irqbit;
49 else
50 s3c_irqwake_intmask &= ~irqbit;
51 break;
52 default:
53 return -ENOENT;
54 }
55 return 0;
56}
57
58static struct sleep_save eint_save[] = {
59 SAVE_ITEM(S5P_EINT_CON(0)),
60 SAVE_ITEM(S5P_EINT_CON(1)),
61 SAVE_ITEM(S5P_EINT_CON(2)),
62 SAVE_ITEM(S5P_EINT_CON(3)),
63
64 SAVE_ITEM(S5P_EINT_FLTCON(0)),
65 SAVE_ITEM(S5P_EINT_FLTCON(1)),
66 SAVE_ITEM(S5P_EINT_FLTCON(2)),
67 SAVE_ITEM(S5P_EINT_FLTCON(3)),
68 SAVE_ITEM(S5P_EINT_FLTCON(4)),
69 SAVE_ITEM(S5P_EINT_FLTCON(5)),
70 SAVE_ITEM(S5P_EINT_FLTCON(6)),
71 SAVE_ITEM(S5P_EINT_FLTCON(7)),
72
73 SAVE_ITEM(S5P_EINT_MASK(0)),
74 SAVE_ITEM(S5P_EINT_MASK(1)),
75 SAVE_ITEM(S5P_EINT_MASK(2)),
76 SAVE_ITEM(S5P_EINT_MASK(3)),
77};
78
79int s3c24xx_irq_suspend(void)
80{
81 s3c_pm_do_save(eint_save, ARRAY_SIZE(eint_save));
82
83 return 0;
84}
85
86void s3c24xx_irq_resume(void)
87{
88 s3c_pm_do_restore(eint_save, ARRAY_SIZE(eint_save));
89}
90
diff --git a/arch/arm/plat-s5p/irq.c b/arch/arm/plat-s5p/irq.c
new file mode 100644
index 00000000000..a97c08957f4
--- /dev/null
+++ b/arch/arm/plat-s5p/irq.c
@@ -0,0 +1,70 @@
1/* arch/arm/plat-s5p/irq.c
2 *
3 * Copyright (c) 2009 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * S5P - Interrupt handling
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/kernel.h>
14#include <linux/interrupt.h>
15#include <linux/irq.h>
16#include <linux/io.h>
17
18#include <asm/hardware/vic.h>
19
20#include <linux/serial_core.h>
21#include <mach/map.h>
22#include <plat/regs-timer.h>
23#include <plat/regs-serial.h>
24#include <plat/cpu.h>
25#include <plat/irq-vic-timer.h>
26#include <plat/irq-uart.h>
27
28/*
29 * Note, we make use of the fact that the parent IRQs, IRQ_UART[0..3]
30 * are consecutive when looking up the interrupt in the demux routines.
31 */
32static struct s3c_uart_irq uart_irqs[] = {
33 [0] = {
34 .regs = S5P_VA_UART0,
35 .base_irq = IRQ_S5P_UART_BASE0,
36 .parent_irq = IRQ_UART0,
37 },
38 [1] = {
39 .regs = S5P_VA_UART1,
40 .base_irq = IRQ_S5P_UART_BASE1,
41 .parent_irq = IRQ_UART1,
42 },
43 [2] = {
44 .regs = S5P_VA_UART2,
45 .base_irq = IRQ_S5P_UART_BASE2,
46 .parent_irq = IRQ_UART2,
47 },
48#if CONFIG_SERIAL_SAMSUNG_UARTS > 3
49 [3] = {
50 .regs = S5P_VA_UART3,
51 .base_irq = IRQ_S5P_UART_BASE3,
52 .parent_irq = IRQ_UART3,
53 },
54#endif
55};
56
57void __init s5p_init_irq(u32 *vic, u32 num_vic)
58{
59#ifdef CONFIG_ARM_VIC
60 int irq;
61
62 /* initialize the VICs */
63 for (irq = 0; irq < num_vic; irq++)
64 vic_init(VA_VIC(irq), VIC_BASE(irq), vic[irq], 0);
65#endif
66
67 s3c_init_vic_timer_irq(5, IRQ_TIMER0);
68
69 s3c_init_uart_irqs(uart_irqs, ARRAY_SIZE(uart_irqs));
70}
diff --git a/arch/arm/plat-s5p/pm.c b/arch/arm/plat-s5p/pm.c
new file mode 100644
index 00000000000..d15dc47b0e3
--- /dev/null
+++ b/arch/arm/plat-s5p/pm.c
@@ -0,0 +1,41 @@
1/* linux/arch/arm/plat-s5p/pm.c
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * S5P Power Manager (Suspend-To-RAM) support
7 *
8 * Based on arch/arm/plat-s3c24xx/pm.c
9 * Copyright (c) 2004,2006 Simtec Electronics
10 * Ben Dooks <ben@simtec.co.uk>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15*/
16
17#include <linux/suspend.h>
18#include <plat/pm.h>
19
20#define PFX "s5p pm: "
21
22/* s3c_pm_configure_extint
23 *
24 * configure all external interrupt pins
25*/
26
27void s3c_pm_configure_extint(void)
28{
29 /* nothing here yet */
30}
31
32void s3c_pm_restore_core(void)
33{
34 /* nothing here yet */
35}
36
37void s3c_pm_save_core(void)
38{
39 /* nothing here yet */
40}
41
diff --git a/arch/arm/plat-s5p/s5p-time.c b/arch/arm/plat-s5p/s5p-time.c
new file mode 100644
index 00000000000..c833e7b5759
--- /dev/null
+++ b/arch/arm/plat-s5p/s5p-time.c
@@ -0,0 +1,419 @@
1/* linux/arch/arm/plat-s5p/s5p-time.c
2 *
3 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 *
6 * S5P - Common hr-timer 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/sched.h>
14#include <linux/interrupt.h>
15#include <linux/irq.h>
16#include <linux/err.h>
17#include <linux/clk.h>
18#include <linux/clockchips.h>
19#include <linux/platform_device.h>
20
21#include <asm/smp_twd.h>
22#include <asm/mach/time.h>
23#include <asm/mach/arch.h>
24#include <asm/mach/map.h>
25#include <asm/sched_clock.h>
26
27#include <mach/map.h>
28#include <plat/devs.h>
29#include <plat/regs-timer.h>
30#include <plat/s5p-time.h>
31
32static struct clk *tin_event;
33static struct clk *tin_source;
34static struct clk *tdiv_event;
35static struct clk *tdiv_source;
36static struct clk *timerclk;
37static struct s5p_timer_source timer_source;
38static unsigned long clock_count_per_tick;
39static void s5p_timer_resume(void);
40
41static void s5p_time_stop(enum s5p_timer_mode mode)
42{
43 unsigned long tcon;
44
45 tcon = __raw_readl(S3C2410_TCON);
46
47 switch (mode) {
48 case S5P_PWM0:
49 tcon &= ~S3C2410_TCON_T0START;
50 break;
51
52 case S5P_PWM1:
53 tcon &= ~S3C2410_TCON_T1START;
54 break;
55
56 case S5P_PWM2:
57 tcon &= ~S3C2410_TCON_T2START;
58 break;
59
60 case S5P_PWM3:
61 tcon &= ~S3C2410_TCON_T3START;
62 break;
63
64 case S5P_PWM4:
65 tcon &= ~S3C2410_TCON_T4START;
66 break;
67
68 default:
69 printk(KERN_ERR "Invalid Timer %d\n", mode);
70 break;
71 }
72 __raw_writel(tcon, S3C2410_TCON);
73}
74
75static void s5p_time_setup(enum s5p_timer_mode mode, unsigned long tcnt)
76{
77 unsigned long tcon;
78
79 tcon = __raw_readl(S3C2410_TCON);
80
81 tcnt--;
82
83 switch (mode) {
84 case S5P_PWM0:
85 tcon &= ~(0x0f << 0);
86 tcon |= S3C2410_TCON_T0MANUALUPD;
87 break;
88
89 case S5P_PWM1:
90 tcon &= ~(0x0f << 8);
91 tcon |= S3C2410_TCON_T1MANUALUPD;
92 break;
93
94 case S5P_PWM2:
95 tcon &= ~(0x0f << 12);
96 tcon |= S3C2410_TCON_T2MANUALUPD;
97 break;
98
99 case S5P_PWM3:
100 tcon &= ~(0x0f << 16);
101 tcon |= S3C2410_TCON_T3MANUALUPD;
102 break;
103
104 case S5P_PWM4:
105 tcon &= ~(0x07 << 20);
106 tcon |= S3C2410_TCON_T4MANUALUPD;
107 break;
108
109 default:
110 printk(KERN_ERR "Invalid Timer %d\n", mode);
111 break;
112 }
113
114 __raw_writel(tcnt, S3C2410_TCNTB(mode));
115 __raw_writel(tcnt, S3C2410_TCMPB(mode));
116 __raw_writel(tcon, S3C2410_TCON);
117}
118
119static void s5p_time_start(enum s5p_timer_mode mode, bool periodic)
120{
121 unsigned long tcon;
122
123 tcon = __raw_readl(S3C2410_TCON);
124
125 switch (mode) {
126 case S5P_PWM0:
127 tcon |= S3C2410_TCON_T0START;
128 tcon &= ~S3C2410_TCON_T0MANUALUPD;
129
130 if (periodic)
131 tcon |= S3C2410_TCON_T0RELOAD;
132 else
133 tcon &= ~S3C2410_TCON_T0RELOAD;
134 break;
135
136 case S5P_PWM1:
137 tcon |= S3C2410_TCON_T1START;
138 tcon &= ~S3C2410_TCON_T1MANUALUPD;
139
140 if (periodic)
141 tcon |= S3C2410_TCON_T1RELOAD;
142 else
143 tcon &= ~S3C2410_TCON_T1RELOAD;
144 break;
145
146 case S5P_PWM2:
147 tcon |= S3C2410_TCON_T2START;
148 tcon &= ~S3C2410_TCON_T2MANUALUPD;
149
150 if (periodic)
151 tcon |= S3C2410_TCON_T2RELOAD;
152 else
153 tcon &= ~S3C2410_TCON_T2RELOAD;
154 break;
155
156 case S5P_PWM3:
157 tcon |= S3C2410_TCON_T3START;
158 tcon &= ~S3C2410_TCON_T3MANUALUPD;
159
160 if (periodic)
161 tcon |= S3C2410_TCON_T3RELOAD;
162 else
163 tcon &= ~S3C2410_TCON_T3RELOAD;
164 break;
165
166 case S5P_PWM4:
167 tcon |= S3C2410_TCON_T4START;
168 tcon &= ~S3C2410_TCON_T4MANUALUPD;
169
170 if (periodic)
171 tcon |= S3C2410_TCON_T4RELOAD;
172 else
173 tcon &= ~S3C2410_TCON_T4RELOAD;
174 break;
175
176 default:
177 printk(KERN_ERR "Invalid Timer %d\n", mode);
178 break;
179 }
180 __raw_writel(tcon, S3C2410_TCON);
181}
182
183static int s5p_set_next_event(unsigned long cycles,
184 struct clock_event_device *evt)
185{
186 s5p_time_setup(timer_source.event_id, cycles);
187 s5p_time_start(timer_source.event_id, NON_PERIODIC);
188
189 return 0;
190}
191
192static void s5p_set_mode(enum clock_event_mode mode,
193 struct clock_event_device *evt)
194{
195 s5p_time_stop(timer_source.event_id);
196
197 switch (mode) {
198 case CLOCK_EVT_MODE_PERIODIC:
199 s5p_time_setup(timer_source.event_id, clock_count_per_tick);
200 s5p_time_start(timer_source.event_id, PERIODIC);
201 break;
202
203 case CLOCK_EVT_MODE_ONESHOT:
204 break;
205
206 case CLOCK_EVT_MODE_UNUSED:
207 case CLOCK_EVT_MODE_SHUTDOWN:
208 break;
209
210 case CLOCK_EVT_MODE_RESUME:
211 s5p_timer_resume();
212 break;
213 }
214}
215
216static void s5p_timer_resume(void)
217{
218 /* event timer restart */
219 s5p_time_setup(timer_source.event_id, clock_count_per_tick);
220 s5p_time_start(timer_source.event_id, PERIODIC);
221
222 /* source timer restart */
223 s5p_time_setup(timer_source.source_id, TCNT_MAX);
224 s5p_time_start(timer_source.source_id, PERIODIC);
225}
226
227void __init s5p_set_timer_source(enum s5p_timer_mode event,
228 enum s5p_timer_mode source)
229{
230 s3c_device_timer[event].dev.bus = &platform_bus_type;
231 s3c_device_timer[source].dev.bus = &platform_bus_type;
232
233 timer_source.event_id = event;
234 timer_source.source_id = source;
235}
236
237static struct clock_event_device time_event_device = {
238 .name = "s5p_event_timer",
239 .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
240 .rating = 200,
241 .set_next_event = s5p_set_next_event,
242 .set_mode = s5p_set_mode,
243};
244
245static irqreturn_t s5p_clock_event_isr(int irq, void *dev_id)
246{
247 struct clock_event_device *evt = dev_id;
248
249 evt->event_handler(evt);
250
251 return IRQ_HANDLED;
252}
253
254static struct irqaction s5p_clock_event_irq = {
255 .name = "s5p_time_irq",
256 .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
257 .handler = s5p_clock_event_isr,
258 .dev_id = &time_event_device,
259};
260
261static void __init s5p_clockevent_init(void)
262{
263 unsigned long pclk;
264 unsigned long clock_rate;
265 unsigned int irq_number;
266 struct clk *tscaler;
267
268 pclk = clk_get_rate(timerclk);
269
270 tscaler = clk_get_parent(tdiv_event);
271
272 clk_set_rate(tscaler, pclk / 2);
273 clk_set_rate(tdiv_event, pclk / 2);
274 clk_set_parent(tin_event, tdiv_event);
275
276 clock_rate = clk_get_rate(tin_event);
277 clock_count_per_tick = clock_rate / HZ;
278
279 clockevents_calc_mult_shift(&time_event_device,
280 clock_rate, S5PTIMER_MIN_RANGE);
281 time_event_device.max_delta_ns =
282 clockevent_delta2ns(-1, &time_event_device);
283 time_event_device.min_delta_ns =
284 clockevent_delta2ns(1, &time_event_device);
285
286 time_event_device.cpumask = cpumask_of(0);
287 clockevents_register_device(&time_event_device);
288
289 irq_number = timer_source.event_id + IRQ_TIMER0;
290 setup_irq(irq_number, &s5p_clock_event_irq);
291}
292
293static void __iomem *s5p_timer_reg(void)
294{
295 unsigned long offset = 0;
296
297 switch (timer_source.source_id) {
298 case S5P_PWM0:
299 case S5P_PWM1:
300 case S5P_PWM2:
301 case S5P_PWM3:
302 offset = (timer_source.source_id * 0x0c) + 0x14;
303 break;
304
305 case S5P_PWM4:
306 offset = 0x40;
307 break;
308
309 default:
310 printk(KERN_ERR "Invalid Timer %d\n", timer_source.source_id);
311 return NULL;
312 }
313
314 return S3C_TIMERREG(offset);
315}
316
317/*
318 * Override the global weak sched_clock symbol with this
319 * local implementation which uses the clocksource to get some
320 * better resolution when scheduling the kernel. We accept that
321 * this wraps around for now, since it is just a relative time
322 * stamp. (Inspired by U300 implementation.)
323 */
324static DEFINE_CLOCK_DATA(cd);
325
326unsigned long long notrace sched_clock(void)
327{
328 void __iomem *reg = s5p_timer_reg();
329
330 if (!reg)
331 return 0;
332
333 return cyc_to_sched_clock(&cd, ~__raw_readl(reg), (u32)~0);
334}
335
336static void notrace s5p_update_sched_clock(void)
337{
338 void __iomem *reg = s5p_timer_reg();
339
340 if (!reg)
341 return;
342
343 update_sched_clock(&cd, ~__raw_readl(reg), (u32)~0);
344}
345
346static void __init s5p_clocksource_init(void)
347{
348 unsigned long pclk;
349 unsigned long clock_rate;
350
351 pclk = clk_get_rate(timerclk);
352
353 clk_set_rate(tdiv_source, pclk / 2);
354 clk_set_parent(tin_source, tdiv_source);
355
356 clock_rate = clk_get_rate(tin_source);
357
358 s5p_time_setup(timer_source.source_id, TCNT_MAX);
359 s5p_time_start(timer_source.source_id, PERIODIC);
360
361 init_sched_clock(&cd, s5p_update_sched_clock, 32, clock_rate);
362
363 if (clocksource_mmio_init(s5p_timer_reg(), "s5p_clocksource_timer",
364 clock_rate, 250, 32, clocksource_mmio_readl_down))
365 panic("s5p_clocksource_timer: can't register clocksource\n");
366}
367
368static void __init s5p_timer_resources(void)
369{
370
371 unsigned long event_id = timer_source.event_id;
372 unsigned long source_id = timer_source.source_id;
373 char devname[15];
374
375 timerclk = clk_get(NULL, "timers");
376 if (IS_ERR(timerclk))
377 panic("failed to get timers clock for timer");
378
379 clk_enable(timerclk);
380
381 sprintf(devname, "s3c24xx-pwm.%lu", event_id);
382 s3c_device_timer[event_id].id = event_id;
383 s3c_device_timer[event_id].dev.init_name = devname;
384
385 tin_event = clk_get(&s3c_device_timer[event_id].dev, "pwm-tin");
386 if (IS_ERR(tin_event))
387 panic("failed to get pwm-tin clock for event timer");
388
389 tdiv_event = clk_get(&s3c_device_timer[event_id].dev, "pwm-tdiv");
390 if (IS_ERR(tdiv_event))
391 panic("failed to get pwm-tdiv clock for event timer");
392
393 clk_enable(tin_event);
394
395 sprintf(devname, "s3c24xx-pwm.%lu", source_id);
396 s3c_device_timer[source_id].id = source_id;
397 s3c_device_timer[source_id].dev.init_name = devname;
398
399 tin_source = clk_get(&s3c_device_timer[source_id].dev, "pwm-tin");
400 if (IS_ERR(tin_source))
401 panic("failed to get pwm-tin clock for source timer");
402
403 tdiv_source = clk_get(&s3c_device_timer[source_id].dev, "pwm-tdiv");
404 if (IS_ERR(tdiv_source))
405 panic("failed to get pwm-tdiv clock for source timer");
406
407 clk_enable(tin_source);
408}
409
410static void __init s5p_timer_init(void)
411{
412 s5p_timer_resources();
413 s5p_clockevent_init();
414 s5p_clocksource_init();
415}
416
417struct sys_timer s5p_timer = {
418 .init = s5p_timer_init,
419};
diff --git a/arch/arm/plat-s5p/setup-mipiphy.c b/arch/arm/plat-s5p/setup-mipiphy.c
new file mode 100644
index 00000000000..683c466c0e6
--- /dev/null
+++ b/arch/arm/plat-s5p/setup-mipiphy.c
@@ -0,0 +1,63 @@
1/*
2 * Copyright (C) 2011 Samsung Electronics Co., Ltd.
3 *
4 * S5P - Helper functions for MIPI-CSIS and MIPI-DSIM D-PHY control
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#include <linux/kernel.h>
12#include <linux/platform_device.h>
13#include <linux/io.h>
14#include <linux/spinlock.h>
15#include <mach/regs-clock.h>
16
17static int __s5p_mipi_phy_control(struct platform_device *pdev,
18 bool on, u32 reset)
19{
20 static DEFINE_SPINLOCK(lock);
21 void __iomem *addr;
22 unsigned long flags;
23 int pid;
24 u32 cfg;
25
26 if (!pdev)
27 return -EINVAL;
28
29 pid = (pdev->id == -1) ? 0 : pdev->id;
30
31 if (pid != 0 && pid != 1)
32 return -EINVAL;
33
34 addr = S5P_MIPI_DPHY_CONTROL(pid);
35
36 spin_lock_irqsave(&lock, flags);
37
38 cfg = __raw_readl(addr);
39 cfg = on ? (cfg | reset) : (cfg & ~reset);
40 __raw_writel(cfg, addr);
41
42 if (on) {
43 cfg |= S5P_MIPI_DPHY_ENABLE;
44 } else if (!(cfg & (S5P_MIPI_DPHY_SRESETN |
45 S5P_MIPI_DPHY_MRESETN) & ~reset)) {
46 cfg &= ~S5P_MIPI_DPHY_ENABLE;
47 }
48
49 __raw_writel(cfg, addr);
50 spin_unlock_irqrestore(&lock, flags);
51
52 return 0;
53}
54
55int s5p_csis_phy_enable(struct platform_device *pdev, bool on)
56{
57 return __s5p_mipi_phy_control(pdev, on, S5P_MIPI_DPHY_SRESETN);
58}
59
60int s5p_dsim_phy_enable(struct platform_device *pdev, bool on)
61{
62 return __s5p_mipi_phy_control(pdev, on, S5P_MIPI_DPHY_MRESETN);
63}
diff --git a/arch/arm/plat-s5p/sysmmu.c b/arch/arm/plat-s5p/sysmmu.c
new file mode 100644
index 00000000000..e1cbc728c77
--- /dev/null
+++ b/arch/arm/plat-s5p/sysmmu.c
@@ -0,0 +1,312 @@
1/* linux/arch/arm/plat-s5p/sysmmu.c
2 *
3 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#include <linux/io.h>
12#include <linux/interrupt.h>
13#include <linux/platform_device.h>
14
15#include <asm/pgtable.h>
16
17#include <mach/map.h>
18#include <mach/regs-sysmmu.h>
19#include <plat/sysmmu.h>
20
21#define CTRL_ENABLE 0x5
22#define CTRL_BLOCK 0x7
23#define CTRL_DISABLE 0x0
24
25static struct device *dev;
26
27static unsigned short fault_reg_offset[SYSMMU_FAULTS_NUM] = {
28 S5P_PAGE_FAULT_ADDR,
29 S5P_AR_FAULT_ADDR,
30 S5P_AW_FAULT_ADDR,
31 S5P_DEFAULT_SLAVE_ADDR,
32 S5P_AR_FAULT_ADDR,
33 S5P_AR_FAULT_ADDR,
34 S5P_AW_FAULT_ADDR,
35 S5P_AW_FAULT_ADDR
36};
37
38static char *sysmmu_fault_name[SYSMMU_FAULTS_NUM] = {
39 "PAGE FAULT",
40 "AR MULTI-HIT FAULT",
41 "AW MULTI-HIT FAULT",
42 "BUS ERROR",
43 "AR SECURITY PROTECTION FAULT",
44 "AR ACCESS PROTECTION FAULT",
45 "AW SECURITY PROTECTION FAULT",
46 "AW ACCESS PROTECTION FAULT"
47};
48
49static int (*fault_handlers[S5P_SYSMMU_TOTAL_IPNUM])(
50 enum S5P_SYSMMU_INTERRUPT_TYPE itype,
51 unsigned long pgtable_base,
52 unsigned long fault_addr);
53
54/*
55 * If adjacent 2 bits are true, the system MMU is enabled.
56 * The system MMU is disabled, otherwise.
57 */
58static unsigned long sysmmu_states;
59
60static inline void set_sysmmu_active(sysmmu_ips ips)
61{
62 sysmmu_states |= 3 << (ips * 2);
63}
64
65static inline void set_sysmmu_inactive(sysmmu_ips ips)
66{
67 sysmmu_states &= ~(3 << (ips * 2));
68}
69
70static inline int is_sysmmu_active(sysmmu_ips ips)
71{
72 return sysmmu_states & (3 << (ips * 2));
73}
74
75static void __iomem *sysmmusfrs[S5P_SYSMMU_TOTAL_IPNUM];
76
77static inline void sysmmu_block(sysmmu_ips ips)
78{
79 __raw_writel(CTRL_BLOCK, sysmmusfrs[ips] + S5P_MMU_CTRL);
80 dev_dbg(dev, "%s is blocked.\n", sysmmu_ips_name[ips]);
81}
82
83static inline void sysmmu_unblock(sysmmu_ips ips)
84{
85 __raw_writel(CTRL_ENABLE, sysmmusfrs[ips] + S5P_MMU_CTRL);
86 dev_dbg(dev, "%s is unblocked.\n", sysmmu_ips_name[ips]);
87}
88
89static inline void __sysmmu_tlb_invalidate(sysmmu_ips ips)
90{
91 __raw_writel(0x1, sysmmusfrs[ips] + S5P_MMU_FLUSH);
92 dev_dbg(dev, "TLB of %s is invalidated.\n", sysmmu_ips_name[ips]);
93}
94
95static inline void __sysmmu_set_ptbase(sysmmu_ips ips, unsigned long pgd)
96{
97 if (unlikely(pgd == 0)) {
98 pgd = (unsigned long)ZERO_PAGE(0);
99 __raw_writel(0x20, sysmmusfrs[ips] + S5P_MMU_CFG); /* 4KB LV1 */
100 } else {
101 __raw_writel(0x0, sysmmusfrs[ips] + S5P_MMU_CFG); /* 16KB LV1 */
102 }
103
104 __raw_writel(pgd, sysmmusfrs[ips] + S5P_PT_BASE_ADDR);
105
106 dev_dbg(dev, "Page table base of %s is initialized with 0x%08lX.\n",
107 sysmmu_ips_name[ips], pgd);
108 __sysmmu_tlb_invalidate(ips);
109}
110
111void sysmmu_set_fault_handler(sysmmu_ips ips,
112 int (*handler)(enum S5P_SYSMMU_INTERRUPT_TYPE itype,
113 unsigned long pgtable_base,
114 unsigned long fault_addr))
115{
116 BUG_ON(!((ips >= SYSMMU_MDMA) && (ips < S5P_SYSMMU_TOTAL_IPNUM)));
117 fault_handlers[ips] = handler;
118}
119
120static irqreturn_t s5p_sysmmu_irq(int irq, void *dev_id)
121{
122 /* SYSMMU is in blocked when interrupt occurred. */
123 unsigned long base = 0;
124 sysmmu_ips ips = (sysmmu_ips)dev_id;
125 enum S5P_SYSMMU_INTERRUPT_TYPE itype;
126
127 itype = (enum S5P_SYSMMU_INTERRUPT_TYPE)
128 __ffs(__raw_readl(sysmmusfrs[ips] + S5P_INT_STATUS));
129
130 BUG_ON(!((itype >= 0) && (itype < 8)));
131
132 dev_alert(dev, "%s occurred by %s.\n", sysmmu_fault_name[itype],
133 sysmmu_ips_name[ips]);
134
135 if (fault_handlers[ips]) {
136 unsigned long addr;
137
138 base = __raw_readl(sysmmusfrs[ips] + S5P_PT_BASE_ADDR);
139 addr = __raw_readl(sysmmusfrs[ips] + fault_reg_offset[itype]);
140
141 if (fault_handlers[ips](itype, base, addr)) {
142 __raw_writel(1 << itype,
143 sysmmusfrs[ips] + S5P_INT_CLEAR);
144 dev_notice(dev, "%s from %s is resolved."
145 " Retrying translation.\n",
146 sysmmu_fault_name[itype], sysmmu_ips_name[ips]);
147 } else {
148 base = 0;
149 }
150 }
151
152 sysmmu_unblock(ips);
153
154 if (!base)
155 dev_notice(dev, "%s from %s is not handled.\n",
156 sysmmu_fault_name[itype], sysmmu_ips_name[ips]);
157
158 return IRQ_HANDLED;
159}
160
161void s5p_sysmmu_set_tablebase_pgd(sysmmu_ips ips, unsigned long pgd)
162{
163 if (is_sysmmu_active(ips)) {
164 sysmmu_block(ips);
165 __sysmmu_set_ptbase(ips, pgd);
166 sysmmu_unblock(ips);
167 } else {
168 dev_dbg(dev, "%s is disabled. "
169 "Skipping initializing page table base.\n",
170 sysmmu_ips_name[ips]);
171 }
172}
173
174void s5p_sysmmu_enable(sysmmu_ips ips, unsigned long pgd)
175{
176 if (!is_sysmmu_active(ips)) {
177 sysmmu_clk_enable(ips);
178
179 __sysmmu_set_ptbase(ips, pgd);
180
181 __raw_writel(CTRL_ENABLE, sysmmusfrs[ips] + S5P_MMU_CTRL);
182
183 set_sysmmu_active(ips);
184 dev_dbg(dev, "%s is enabled.\n", sysmmu_ips_name[ips]);
185 } else {
186 dev_dbg(dev, "%s is already enabled.\n", sysmmu_ips_name[ips]);
187 }
188}
189
190void s5p_sysmmu_disable(sysmmu_ips ips)
191{
192 if (is_sysmmu_active(ips)) {
193 __raw_writel(CTRL_DISABLE, sysmmusfrs[ips] + S5P_MMU_CTRL);
194 set_sysmmu_inactive(ips);
195 sysmmu_clk_disable(ips);
196 dev_dbg(dev, "%s is disabled.\n", sysmmu_ips_name[ips]);
197 } else {
198 dev_dbg(dev, "%s is already disabled.\n", sysmmu_ips_name[ips]);
199 }
200}
201
202void s5p_sysmmu_tlb_invalidate(sysmmu_ips ips)
203{
204 if (is_sysmmu_active(ips)) {
205 sysmmu_block(ips);
206 __sysmmu_tlb_invalidate(ips);
207 sysmmu_unblock(ips);
208 } else {
209 dev_dbg(dev, "%s is disabled. "
210 "Skipping invalidating TLB.\n", sysmmu_ips_name[ips]);
211 }
212}
213
214static int s5p_sysmmu_probe(struct platform_device *pdev)
215{
216 int i, ret;
217 struct resource *res, *mem;
218
219 dev = &pdev->dev;
220
221 for (i = 0; i < S5P_SYSMMU_TOTAL_IPNUM; i++) {
222 int irq;
223
224 sysmmu_clk_init(dev, i);
225 sysmmu_clk_disable(i);
226
227 res = platform_get_resource(pdev, IORESOURCE_MEM, i);
228 if (!res) {
229 dev_err(dev, "Failed to get the resource of %s.\n",
230 sysmmu_ips_name[i]);
231 ret = -ENODEV;
232 goto err_res;
233 }
234
235 mem = request_mem_region(res->start, resource_size(res),
236 pdev->name);
237 if (!mem) {
238 dev_err(dev, "Failed to request the memory region of %s.\n",
239 sysmmu_ips_name[i]);
240 ret = -EBUSY;
241 goto err_res;
242 }
243
244 sysmmusfrs[i] = ioremap(res->start, resource_size(res));
245 if (!sysmmusfrs[i]) {
246 dev_err(dev, "Failed to ioremap() for %s.\n",
247 sysmmu_ips_name[i]);
248 ret = -ENXIO;
249 goto err_reg;
250 }
251
252 irq = platform_get_irq(pdev, i);
253 if (irq <= 0) {
254 dev_err(dev, "Failed to get the IRQ resource of %s.\n",
255 sysmmu_ips_name[i]);
256 ret = -ENOENT;
257 goto err_map;
258 }
259
260 if (request_irq(irq, s5p_sysmmu_irq, IRQF_DISABLED,
261 pdev->name, (void *)i)) {
262 dev_err(dev, "Failed to request IRQ for %s.\n",
263 sysmmu_ips_name[i]);
264 ret = -ENOENT;
265 goto err_map;
266 }
267 }
268
269 return 0;
270
271err_map:
272 iounmap(sysmmusfrs[i]);
273err_reg:
274 release_mem_region(mem->start, resource_size(mem));
275err_res:
276 return ret;
277}
278
279static int s5p_sysmmu_remove(struct platform_device *pdev)
280{
281 return 0;
282}
283int s5p_sysmmu_runtime_suspend(struct device *dev)
284{
285 return 0;
286}
287
288int s5p_sysmmu_runtime_resume(struct device *dev)
289{
290 return 0;
291}
292
293const struct dev_pm_ops s5p_sysmmu_pm_ops = {
294 .runtime_suspend = s5p_sysmmu_runtime_suspend,
295 .runtime_resume = s5p_sysmmu_runtime_resume,
296};
297
298static struct platform_driver s5p_sysmmu_driver = {
299 .probe = s5p_sysmmu_probe,
300 .remove = s5p_sysmmu_remove,
301 .driver = {
302 .owner = THIS_MODULE,
303 .name = "s5p-sysmmu",
304 .pm = &s5p_sysmmu_pm_ops,
305 }
306};
307
308static int __init s5p_sysmmu_init(void)
309{
310 return platform_driver_register(&s5p_sysmmu_driver);
311}
312arch_initcall(s5p_sysmmu_init);