aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2011-12-27 18:15:53 -0500
committerArnd Bergmann <arnd@arndb.de>2011-12-27 18:15:53 -0500
commit4eb821999086417ab42a15174b51497122fc406e (patch)
tree3ef7a628f82286f018df7d9d5f48da475d09c349
parent384703b8e6cd4c8ef08512e596024e028c91c339 (diff)
parent0561ceabd0f13871900d116278fe9268aeb714d1 (diff)
Merge branch 'next-samsung-devel-dt1' of git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung into samsung/dt
-rw-r--r--Documentation/devicetree/bindings/arm/insignal-boards.txt8
-rw-r--r--Documentation/devicetree/bindings/arm/samsung-boards.txt8
-rw-r--r--Documentation/devicetree/bindings/dma/arm-pl330.txt30
-rw-r--r--Documentation/devicetree/bindings/gpio/gpio-samsung.txt40
-rw-r--r--Documentation/devicetree/bindings/input/samsung-keypad.txt88
-rw-r--r--Documentation/devicetree/bindings/rtc/s3c-rtc.txt20
-rw-r--r--Documentation/devicetree/bindings/serial/samsung_uart.txt14
-rw-r--r--arch/arm/boot/dts/exynos4210-origen.dts137
-rw-r--r--arch/arm/boot/dts/exynos4210-smdkv310.dts182
-rw-r--r--arch/arm/boot/dts/exynos4210.dtsi397
-rw-r--r--arch/arm/mach-exynos/Kconfig24
-rw-r--r--arch/arm/mach-exynos/Makefile5
-rw-r--r--arch/arm/mach-exynos/clock.c141
-rw-r--r--arch/arm/mach-exynos/cpu.c17
-rw-r--r--arch/arm/mach-exynos/dma.c229
-rw-r--r--arch/arm/mach-exynos/include/mach/entry-macro.S1
-rw-r--r--arch/arm/mach-exynos/include/mach/irqs.h8
-rw-r--r--arch/arm/mach-exynos/init.c21
-rw-r--r--arch/arm/mach-exynos/mach-exynos4-dt.c85
-rw-r--r--arch/arm/mach-s3c2410/mach-bast.c22
-rw-r--r--arch/arm/mach-s3c2410/mach-vr1000.c24
-rw-r--r--arch/arm/mach-s3c2410/s3c2410.c6
-rw-r--r--arch/arm/mach-s3c2412/clock.c7
-rw-r--r--arch/arm/mach-s3c2440/clock.c44
-rw-r--r--arch/arm/mach-s3c2440/mach-anubis.c22
-rw-r--r--arch/arm/mach-s3c2440/mach-at2440evb.c22
-rw-r--r--arch/arm/mach-s3c2440/mach-osiris.c24
-rw-r--r--arch/arm/mach-s3c2440/mach-rx1950.c18
-rw-r--r--arch/arm/mach-s3c2440/mach-rx3715.c19
-rw-r--r--arch/arm/mach-s3c64xx/clock.c37
-rw-r--r--arch/arm/mach-s5p64x0/clock-s5p6440.c32
-rw-r--r--arch/arm/mach-s5p64x0/clock-s5p6450.c32
-rw-r--r--arch/arm/mach-s5p64x0/dma.c227
-rw-r--r--arch/arm/mach-s5p64x0/include/mach/irqs.h2
-rw-r--r--arch/arm/mach-s5p64x0/init.c31
-rw-r--r--arch/arm/mach-s5pc100/clock.c33
-rw-r--r--arch/arm/mach-s5pc100/dma.c247
-rw-r--r--arch/arm/mach-s5pc100/include/mach/irqs.h2
-rw-r--r--arch/arm/mach-s5pv210/clock.c107
-rw-r--r--arch/arm/mach-s5pv210/dma.c241
-rw-r--r--arch/arm/mach-s5pv210/include/mach/irqs.h2
-rw-r--r--arch/arm/mach-s5pv210/init.c19
-rw-r--r--arch/arm/plat-s3c24xx/s3c2443-clock.c23
-rw-r--r--arch/arm/plat-samsung/dma-ops.c15
-rw-r--r--arch/arm/plat-samsung/include/plat/dma-ops.h1
-rw-r--r--arch/arm/plat-samsung/include/plat/dma-pl330.h3
-rw-r--r--arch/arm/plat-samsung/include/plat/irqs.h3
-rw-r--r--arch/arm/plat-samsung/include/plat/regs-serial.h45
-rw-r--r--drivers/dma/pl330.c99
-rw-r--r--drivers/gpio/gpio-samsung.c72
-rw-r--r--drivers/input/keyboard/samsung-keypad.c174
-rw-r--r--drivers/rtc/rtc-s3c.c21
-rw-r--r--drivers/tty/serial/Kconfig45
-rw-r--r--drivers/tty/serial/Makefile5
-rw-r--r--drivers/tty/serial/s3c2410.c115
-rw-r--r--drivers/tty/serial/s3c2412.c149
-rw-r--r--drivers/tty/serial/s3c2440.c178
-rw-r--r--drivers/tty/serial/s3c6400.c149
-rw-r--r--drivers/tty/serial/s5pv210.c158
-rw-r--r--drivers/tty/serial/samsung.c639
-rw-r--r--drivers/tty/serial/samsung.h32
-rw-r--r--include/linux/amba/pl330.h15
62 files changed, 2423 insertions, 2193 deletions
diff --git a/Documentation/devicetree/bindings/arm/insignal-boards.txt b/Documentation/devicetree/bindings/arm/insignal-boards.txt
new file mode 100644
index 000000000000..524c3dc5d808
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/insignal-boards.txt
@@ -0,0 +1,8 @@
1* Insignal's Exynos4210 based Origen evaluation board
2
3Origen low-cost evaluation board is based on Samsung's Exynos4210 SoC.
4
5Required root node properties:
6 - compatible = should be one or more of the following.
7 (a) "samsung,smdkv310" - for Samsung's SMDKV310 eval board.
8 (b) "samsung,exynos4210" - for boards based on Exynos4210 SoC.
diff --git a/Documentation/devicetree/bindings/arm/samsung-boards.txt b/Documentation/devicetree/bindings/arm/samsung-boards.txt
new file mode 100644
index 000000000000..0bf68be56fd1
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/samsung-boards.txt
@@ -0,0 +1,8 @@
1* Samsung's Exynos4210 based SMDKV310 evaluation board
2
3SMDKV310 evaluation board is based on Samsung's Exynos4210 SoC.
4
5Required root node properties:
6 - compatible = should be one or more of the following.
7 (a) "samsung,smdkv310" - for Samsung's SMDKV310 eval board.
8 (b) "samsung,exynos4210" - for boards based on Exynos4210 SoC.
diff --git a/Documentation/devicetree/bindings/dma/arm-pl330.txt b/Documentation/devicetree/bindings/dma/arm-pl330.txt
new file mode 100644
index 000000000000..a4cd273b2a67
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/arm-pl330.txt
@@ -0,0 +1,30 @@
1* ARM PrimeCell PL330 DMA Controller
2
3The ARM PrimeCell PL330 DMA controller can move blocks of memory contents
4between memory and peripherals or memory to memory.
5
6Required properties:
7 - compatible: should include both "arm,pl330" and "arm,primecell".
8 - reg: physical base address of the controller and length of memory mapped
9 region.
10 - interrupts: interrupt number to the cpu.
11
12Example:
13
14 pdma0: pdma@12680000 {
15 compatible = "arm,pl330", "arm,primecell";
16 reg = <0x12680000 0x1000>;
17 interrupts = <99>;
18 };
19
20Client drivers (device nodes requiring dma transfers from dev-to-mem or
21mem-to-dev) should specify the DMA channel numbers using a two-value pair
22as shown below.
23
24 [property name] = <[phandle of the dma controller] [dma request id]>;
25
26 where 'dma request id' is the dma request number which is connected
27 to the client controller. The 'property name' is recommended to be
28 of the form <name>-dma-channel.
29
30 Example: tx-dma-channel = <&pdma0 12>;
diff --git a/Documentation/devicetree/bindings/gpio/gpio-samsung.txt b/Documentation/devicetree/bindings/gpio/gpio-samsung.txt
new file mode 100644
index 000000000000..8f50fe5e6c42
--- /dev/null
+++ b/Documentation/devicetree/bindings/gpio/gpio-samsung.txt
@@ -0,0 +1,40 @@
1Samsung Exynos4 GPIO Controller
2
3Required properties:
4- compatible: Compatible property value should be "samsung,exynos4-gpio>".
5
6- reg: Physical base address of the controller and length of memory mapped
7 region.
8
9- #gpio-cells: Should be 4. The syntax of the gpio specifier used by client nodes
10 should be the following with values derived from the SoC user manual.
11 <[phandle of the gpio controller node]
12 [pin number within the gpio controller]
13 [mux function]
14 [pull up/down]
15 [drive strength]>
16
17 Values for gpio specifier:
18 - Pin number: is a value between 0 to 7.
19 - Pull Up/Down: 0 - Pull Up/Down Disabled.
20 1 - Pull Down Enabled.
21 3 - Pull Up Enabled.
22 - Drive Strength: 0 - 1x,
23 1 - 3x,
24 2 - 2x,
25 3 - 4x
26
27- gpio-controller: Specifies that the node is a gpio controller.
28- #address-cells: should be 1.
29- #size-cells: should be 1.
30
31Example:
32
33 gpa0: gpio-controller@11400000 {
34 #address-cells = <1>;
35 #size-cells = <1>;
36 compatible = "samsung,exynos4-gpio";
37 reg = <0x11400000 0x20>;
38 #gpio-cells = <4>;
39 gpio-controller;
40 };
diff --git a/Documentation/devicetree/bindings/input/samsung-keypad.txt b/Documentation/devicetree/bindings/input/samsung-keypad.txt
new file mode 100644
index 000000000000..ce3e394c0e64
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/samsung-keypad.txt
@@ -0,0 +1,88 @@
1* Samsung's Keypad Controller device tree bindings
2
3Samsung's Keypad controller is used to interface a SoC with a matrix-type
4keypad device. The keypad controller supports multiple row and column lines.
5A key can be placed at each intersection of a unique row and a unique column.
6The keypad controller can sense a key-press and key-release and report the
7event using a interrupt to the cpu.
8
9Required SoC Specific Properties:
10- compatible: should be one of the following
11 - "samsung,s3c6410-keypad": For controllers compatible with s3c6410 keypad
12 controller.
13 - "samsung,s5pv210-keypad": For controllers compatible with s5pv210 keypad
14 controller.
15
16- reg: physical base address of the controller and length of memory mapped
17 region.
18
19- interrupts: The interrupt number to the cpu.
20
21Required Board Specific Properties:
22- samsung,keypad-num-rows: Number of row lines connected to the keypad
23 controller.
24
25- samsung,keypad-num-columns: Number of column lines connected to the
26 keypad controller.
27
28- row-gpios: List of gpios used as row lines. The gpio specifier for
29 this property depends on the gpio controller to which these row lines
30 are connected.
31
32- col-gpios: List of gpios used as column lines. The gpio specifier for
33 this property depends on the gpio controller to which these column
34 lines are connected.
35
36- Keys represented as child nodes: Each key connected to the keypad
37 controller is represented as a child node to the keypad controller
38 device node and should include the following properties.
39 - keypad,row: the row number to which the key is connected.
40 - keypad,column: the column number to which the key is connected.
41 - linux,code: the key-code to be reported when the key is pressed
42 and released.
43
44Optional Properties specific to linux:
45- linux,keypad-no-autorepeat: do no enable autorepeat feature.
46- linux,keypad-wakeup: use any event on keypad as wakeup event.
47
48
49Example:
50 keypad@100A0000 {
51 compatible = "samsung,s5pv210-keypad";
52 reg = <0x100A0000 0x100>;
53 interrupts = <173>;
54 samsung,keypad-num-rows = <2>;
55 samsung,keypad-num-columns = <8>;
56 linux,input-no-autorepeat;
57 linux,input-wakeup;
58
59 row-gpios = <&gpx2 0 3 3 0
60 &gpx2 1 3 3 0>;
61
62 col-gpios = <&gpx1 0 3 0 0
63 &gpx1 1 3 0 0
64 &gpx1 2 3 0 0
65 &gpx1 3 3 0 0
66 &gpx1 4 3 0 0
67 &gpx1 5 3 0 0
68 &gpx1 6 3 0 0
69 &gpx1 7 3 0 0>;
70
71 key_1 {
72 keypad,row = <0>;
73 keypad,column = <3>;
74 linux,code = <2>;
75 };
76
77 key_2 {
78 keypad,row = <0>;
79 keypad,column = <4>;
80 linux,code = <3>;
81 };
82
83 key_3 {
84 keypad,row = <0>;
85 keypad,column = <5>;
86 linux,code = <4>;
87 };
88 };
diff --git a/Documentation/devicetree/bindings/rtc/s3c-rtc.txt b/Documentation/devicetree/bindings/rtc/s3c-rtc.txt
new file mode 100644
index 000000000000..90ec45fd33ec
--- /dev/null
+++ b/Documentation/devicetree/bindings/rtc/s3c-rtc.txt
@@ -0,0 +1,20 @@
1* Samsung's S3C Real Time Clock controller
2
3Required properties:
4- compatible: should be one of the following.
5 * "samsung,s3c2410-rtc" - for controllers compatible with s3c2410 rtc.
6 * "samsung,s3c6410-rtc" - for controllers compatible with s3c6410 rtc.
7- reg: physical base address of the controller and length of memory mapped
8 region.
9- interrupts: Two interrupt numbers to the cpu should be specified. First
10 interrupt number is the rtc alarm interupt and second interrupt number
11 is the rtc tick interrupt. The number of cells representing a interrupt
12 depends on the parent interrupt controller.
13
14Example:
15
16 rtc@10070000 {
17 compatible = "samsung,s3c6410-rtc";
18 reg = <0x10070000 0x100>;
19 interrupts = <44 0 45 0>;
20 };
diff --git a/Documentation/devicetree/bindings/serial/samsung_uart.txt b/Documentation/devicetree/bindings/serial/samsung_uart.txt
new file mode 100644
index 000000000000..2c8a17cf5cb5
--- /dev/null
+++ b/Documentation/devicetree/bindings/serial/samsung_uart.txt
@@ -0,0 +1,14 @@
1* Samsung's UART Controller
2
3The Samsung's UART controller is used for interfacing SoC with serial communicaion
4devices.
5
6Required properties:
7- compatible: should be
8 - "samsung,exynos4210-uart", for UART's compatible with Exynos4210 uart ports.
9
10- reg: base physical address of the controller and length of memory mapped
11 region.
12
13- interrupts: interrupt number to the cpu. The interrupt specifier format depends
14 on the interrupt controller parent.
diff --git a/arch/arm/boot/dts/exynos4210-origen.dts b/arch/arm/boot/dts/exynos4210-origen.dts
new file mode 100644
index 000000000000..b8c476384eef
--- /dev/null
+++ b/arch/arm/boot/dts/exynos4210-origen.dts
@@ -0,0 +1,137 @@
1/*
2 * Samsung's Exynos4210 based Origen board device tree source
3 *
4 * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
5 * http://www.samsung.com
6 * Copyright (c) 2010-2011 Linaro Ltd.
7 * www.linaro.org
8 *
9 * Device tree source file for Insignal's Origen board which is based on
10 * Samsung's Exynos4210 SoC.
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/dts-v1/;
18/include/ "exynos4210.dtsi"
19
20/ {
21 model = "Insignal Origen evaluation board based on Exynos4210";
22 compatible = "insignal,origen", "samsung,exynos4210";
23
24 memory {
25 reg = <0x40000000 0x40000000>;
26 };
27
28 chosen {
29 bootargs ="root=/dev/ram0 rw ramdisk=8192 initrd=0x41000000,8M console=ttySAC2,115200 init=/linuxrc";
30 };
31
32 sdhci@12530000 {
33 samsung,sdhci-bus-width = <4>;
34 linux,mmc_cap_4_bit_data;
35 samsung,sdhci-cd-internal;
36 gpio-cd = <&gpk2 2 2 3 3>;
37 gpios = <&gpk2 0 2 0 3>,
38 <&gpk2 1 2 0 3>,
39 <&gpk2 3 2 3 3>,
40 <&gpk2 4 2 3 3>,
41 <&gpk2 5 2 3 3>,
42 <&gpk2 6 2 3 3>;
43 };
44
45 sdhci@12510000 {
46 samsung,sdhci-bus-width = <4>;
47 linux,mmc_cap_4_bit_data;
48 samsung,sdhci-cd-internal;
49 gpio-cd = <&gpk0 2 2 3 3>;
50 gpios = <&gpk0 0 2 0 3>,
51 <&gpk0 1 2 0 3>,
52 <&gpk0 3 2 3 3>,
53 <&gpk0 4 2 3 3>,
54 <&gpk0 5 2 3 3>,
55 <&gpk0 6 2 3 3>;
56 };
57
58 gpio_keys {
59 compatible = "gpio-keys";
60 #address-cells = <1>;
61 #size-cells = <0>;
62
63 up {
64 label = "Up";
65 gpios = <&gpx2 0 0 0 2>;
66 linux,code = <103>;
67 };
68
69 down {
70 label = "Down";
71 gpios = <&gpx2 1 0 0 2>;
72 linux,code = <108>;
73 };
74
75 back {
76 label = "Back";
77 gpios = <&gpx1 7 0 0 2>;
78 linux,code = <158>;
79 };
80
81 home {
82 label = "Home";
83 gpios = <&gpx1 6 0 0 2>;
84 linux,code = <102>;
85 };
86
87 menu {
88 label = "Menu";
89 gpios = <&gpx1 5 0 0 2>;
90 linux,code = <139>;
91 };
92 };
93
94 keypad@100A0000 {
95 status = "disabled";
96 };
97
98 sdhci@12520000 {
99 status = "disabled";
100 };
101
102 sdhci@12540000 {
103 status = "disabled";
104 };
105
106 i2c@13860000 {
107 status = "disabled";
108 };
109
110 i2c@13870000 {
111 status = "disabled";
112 };
113
114 i2c@13880000 {
115 status = "disabled";
116 };
117
118 i2c@13890000 {
119 status = "disabled";
120 };
121
122 i2c@138A0000 {
123 status = "disabled";
124 };
125
126 i2c@138B0000 {
127 status = "disabled";
128 };
129
130 i2c@138C0000 {
131 status = "disabled";
132 };
133
134 i2c@138D0000 {
135 status = "disabled";
136 };
137};
diff --git a/arch/arm/boot/dts/exynos4210-smdkv310.dts b/arch/arm/boot/dts/exynos4210-smdkv310.dts
new file mode 100644
index 000000000000..27afc8e535ca
--- /dev/null
+++ b/arch/arm/boot/dts/exynos4210-smdkv310.dts
@@ -0,0 +1,182 @@
1/*
2 * Samsung's Exynos4210 based SMDKV310 board device tree source
3 *
4 * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
5 * http://www.samsung.com
6 * Copyright (c) 2010-2011 Linaro Ltd.
7 * www.linaro.org
8 *
9 * Device tree source file for Samsung's SMDKV310 board which is based on
10 * Samsung's Exynos4210 SoC.
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/dts-v1/;
18/include/ "exynos4210.dtsi"
19
20/ {
21 model = "Samsung smdkv310 evaluation board based on Exynos4210";
22 compatible = "samsung,smdkv310", "samsung,exynos4210";
23
24 memory {
25 reg = <0x40000000 0x80000000>;
26 };
27
28 chosen {
29 bootargs = "root=/dev/ram0 rw ramdisk=8192 initrd=0x41000000,8M console=ttySAC1,115200 init=/linuxrc";
30 };
31
32 sdhci@12530000 {
33 samsung,sdhci-bus-width = <4>;
34 linux,mmc_cap_4_bit_data;
35 samsung,sdhci-cd-internal;
36 gpio-cd = <&gpk2 2 2 3 3>;
37 gpios = <&gpk2 0 2 0 3>,
38 <&gpk2 1 2 0 3>,
39 <&gpk2 3 2 3 3>,
40 <&gpk2 4 2 3 3>,
41 <&gpk2 5 2 3 3>,
42 <&gpk2 6 2 3 3>;
43 };
44
45 keypad@100A0000 {
46 samsung,keypad-num-rows = <2>;
47 samsung,keypad-num-columns = <8>;
48 linux,keypad-no-autorepeat;
49 linux,keypad-wakeup;
50
51 row-gpios = <&gpx2 0 3 3 0>,
52 <&gpx2 1 3 3 0>;
53
54 col-gpios = <&gpx1 0 3 0 0>,
55 <&gpx1 1 3 0 0>,
56 <&gpx1 2 3 0 0>,
57 <&gpx1 3 3 0 0>,
58 <&gpx1 4 3 0 0>,
59 <&gpx1 5 3 0 0>,
60 <&gpx1 6 3 0 0>,
61 <&gpx1 7 3 0 0>;
62
63 key_1 {
64 keypad,row = <0>;
65 keypad,column = <3>;
66 linux,code = <2>;
67 };
68
69 key_2 {
70 keypad,row = <0>;
71 keypad,column = <4>;
72 linux,code = <3>;
73 };
74
75 key_3 {
76 keypad,row = <0>;
77 keypad,column = <5>;
78 linux,code = <4>;
79 };
80
81 key_4 {
82 keypad,row = <0>;
83 keypad,column = <6>;
84 linux,code = <5>;
85 };
86
87 key_5 {
88 keypad,row = <0>;
89 keypad,column = <7>;
90 linux,code = <6>;
91 };
92
93 key_a {
94 keypad,row = <1>;
95 keypad,column = <3>;
96 linux,code = <30>;
97 };
98
99 key_b {
100 keypad,row = <1>;
101 keypad,column = <4>;
102 linux,code = <48>;
103 };
104
105 key_c {
106 keypad,row = <1>;
107 keypad,column = <5>;
108 linux,code = <46>;
109 };
110
111 key_d {
112 keypad,row = <1>;
113 keypad,column = <6>;
114 linux,code = <32>;
115 };
116
117 key_e {
118 keypad,row = <1>;
119 keypad,column = <7>;
120 linux,code = <18>;
121 };
122 };
123
124 i2c@13860000 {
125 #address-cells = <1>;
126 #size-cells = <0>;
127 samsung,i2c-sda-delay = <100>;
128 samsung,i2c-max-bus-freq = <20000>;
129 gpios = <&gpd1 0 2 3 0>,
130 <&gpd1 1 2 3 0>;
131
132 eeprom@50 {
133 compatible = "samsung,24ad0xd1";
134 reg = <0x50>;
135 };
136
137 eeprom@52 {
138 compatible = "samsung,24ad0xd1";
139 reg = <0x52>;
140 };
141 };
142
143 sdhci@12510000 {
144 status = "disabled";
145 };
146
147 sdhci@12520000 {
148 status = "disabled";
149 };
150
151 sdhci@12540000 {
152 status = "disabled";
153 };
154
155 i2c@13870000 {
156 status = "disabled";
157 };
158
159 i2c@13880000 {
160 status = "disabled";
161 };
162
163 i2c@13890000 {
164 status = "disabled";
165 };
166
167 i2c@138A0000 {
168 status = "disabled";
169 };
170
171 i2c@138B0000 {
172 status = "disabled";
173 };
174
175 i2c@138C0000 {
176 status = "disabled";
177 };
178
179 i2c@138D0000 {
180 status = "disabled";
181 };
182};
diff --git a/arch/arm/boot/dts/exynos4210.dtsi b/arch/arm/boot/dts/exynos4210.dtsi
new file mode 100644
index 000000000000..63d7578856c1
--- /dev/null
+++ b/arch/arm/boot/dts/exynos4210.dtsi
@@ -0,0 +1,397 @@
1/*
2 * Samsung's Exynos4210 SoC device tree source
3 *
4 * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
5 * http://www.samsung.com
6 * Copyright (c) 2010-2011 Linaro Ltd.
7 * www.linaro.org
8 *
9 * Samsung's Exynos4210 SoC device nodes are listed in this file. Exynos4210
10 * based board files can include this file and provide values for board specfic
11 * bindings.
12 *
13 * Note: This file does not include device nodes for all the controllers in
14 * Exynos4210 SoC. As device tree coverage for Exynos4210 increases, additional
15 * nodes can be added to this file.
16 *
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License version 2 as
19 * published by the Free Software Foundation.
20*/
21
22/include/ "skeleton.dtsi"
23
24/ {
25 compatible = "samsung,exynos4210";
26 interrupt-parent = <&gic>;
27
28 gic:interrupt-controller@10490000 {
29 compatible = "arm,cortex-a9-gic";
30 #interrupt-cells = <3>;
31 interrupt-controller;
32 reg = <0x10490000 0x1000>, <0x10480000 0x100>;
33 };
34
35 watchdog@10060000 {
36 compatible = "samsung,s3c2410-wdt";
37 reg = <0x10060000 0x100>;
38 interrupts = <0 43 0>;
39 };
40
41 rtc@10070000 {
42 compatible = "samsung,s3c6410-rtc";
43 reg = <0x10070000 0x100>;
44 interrupts = <0 44 0>, <0 45 0>;
45 };
46
47 keypad@100A0000 {
48 compatible = "samsung,s5pv210-keypad";
49 reg = <0x100A0000 0x100>;
50 interrupts = <0 109 0>;
51 };
52
53 sdhci@12510000 {
54 compatible = "samsung,exynos4210-sdhci";
55 reg = <0x12510000 0x100>;
56 interrupts = <0 73 0>;
57 };
58
59 sdhci@12520000 {
60 compatible = "samsung,exynos4210-sdhci";
61 reg = <0x12520000 0x100>;
62 interrupts = <0 74 0>;
63 };
64
65 sdhci@12530000 {
66 compatible = "samsung,exynos4210-sdhci";
67 reg = <0x12530000 0x100>;
68 interrupts = <0 75 0>;
69 };
70
71 sdhci@12540000 {
72 compatible = "samsung,exynos4210-sdhci";
73 reg = <0x12540000 0x100>;
74 interrupts = <0 76 0>;
75 };
76
77 serial@13800000 {
78 compatible = "samsung,exynos4210-uart";
79 reg = <0x13800000 0x100>;
80 interrupts = <0 52 0>;
81 };
82
83 serial@13810000 {
84 compatible = "samsung,exynos4210-uart";
85 reg = <0x13810000 0x100>;
86 interrupts = <0 53 0>;
87 };
88
89 serial@13820000 {
90 compatible = "samsung,exynos4210-uart";
91 reg = <0x13820000 0x100>;
92 interrupts = <0 54 0>;
93 };
94
95 serial@13830000 {
96 compatible = "samsung,exynos4210-uart";
97 reg = <0x13830000 0x100>;
98 interrupts = <0 55 0>;
99 };
100
101 i2c@13860000 {
102 compatible = "samsung,s3c2440-i2c";
103 reg = <0x13860000 0x100>;
104 interrupts = <0 58 0>;
105 };
106
107 i2c@13870000 {
108 compatible = "samsung,s3c2440-i2c";
109 reg = <0x13870000 0x100>;
110 interrupts = <0 59 0>;
111 };
112
113 i2c@13880000 {
114 compatible = "samsung,s3c2440-i2c";
115 reg = <0x13880000 0x100>;
116 interrupts = <0 60 0>;
117 };
118
119 i2c@13890000 {
120 compatible = "samsung,s3c2440-i2c";
121 reg = <0x13890000 0x100>;
122 interrupts = <0 61 0>;
123 };
124
125 i2c@138A0000 {
126 compatible = "samsung,s3c2440-i2c";
127 reg = <0x138A0000 0x100>;
128 interrupts = <0 62 0>;
129 };
130
131 i2c@138B0000 {
132 compatible = "samsung,s3c2440-i2c";
133 reg = <0x138B0000 0x100>;
134 interrupts = <0 63 0>;
135 };
136
137 i2c@138C0000 {
138 compatible = "samsung,s3c2440-i2c";
139 reg = <0x138C0000 0x100>;
140 interrupts = <0 64 0>;
141 };
142
143 i2c@138D0000 {
144 compatible = "samsung,s3c2440-i2c";
145 reg = <0x138D0000 0x100>;
146 interrupts = <0 65 0>;
147 };
148
149 amba {
150 #address-cells = <1>;
151 #size-cells = <1>;
152 compatible = "arm,amba-bus";
153 interrupt-parent = <&gic>;
154 ranges;
155
156 pdma0: pdma@12680000 {
157 compatible = "arm,pl330", "arm,primecell";
158 reg = <0x12680000 0x1000>;
159 interrupts = <0 35 0>;
160 };
161
162 pdma1: pdma@12690000 {
163 compatible = "arm,pl330", "arm,primecell";
164 reg = <0x12690000 0x1000>;
165 interrupts = <0 36 0>;
166 };
167 };
168
169 gpio-controllers {
170 #address-cells = <1>;
171 #size-cells = <1>;
172 gpio-controller;
173 ranges;
174
175 gpa0: gpio-controller@11400000 {
176 compatible = "samsung,exynos4-gpio";
177 reg = <0x11400000 0x20>;
178 #gpio-cells = <4>;
179 };
180
181 gpa1: gpio-controller@11400020 {
182 compatible = "samsung,exynos4-gpio";
183 reg = <0x11400020 0x20>;
184 #gpio-cells = <4>;
185 };
186
187 gpb: gpio-controller@11400040 {
188 compatible = "samsung,exynos4-gpio";
189 reg = <0x11400040 0x20>;
190 #gpio-cells = <4>;
191 };
192
193 gpc0: gpio-controller@11400060 {
194 compatible = "samsung,exynos4-gpio";
195 reg = <0x11400060 0x20>;
196 #gpio-cells = <4>;
197 };
198
199 gpc1: gpio-controller@11400080 {
200 compatible = "samsung,exynos4-gpio";
201 reg = <0x11400080 0x20>;
202 #gpio-cells = <4>;
203 };
204
205 gpd0: gpio-controller@114000A0 {
206 compatible = "samsung,exynos4-gpio";
207 reg = <0x114000A0 0x20>;
208 #gpio-cells = <4>;
209 };
210
211 gpd1: gpio-controller@114000C0 {
212 compatible = "samsung,exynos4-gpio";
213 reg = <0x114000C0 0x20>;
214 #gpio-cells = <4>;
215 };
216
217 gpe0: gpio-controller@114000E0 {
218 compatible = "samsung,exynos4-gpio";
219 reg = <0x114000E0 0x20>;
220 #gpio-cells = <4>;
221 };
222
223 gpe1: gpio-controller@11400100 {
224 compatible = "samsung,exynos4-gpio";
225 reg = <0x11400100 0x20>;
226 #gpio-cells = <4>;
227 };
228
229 gpe2: gpio-controller@11400120 {
230 compatible = "samsung,exynos4-gpio";
231 reg = <0x11400120 0x20>;
232 #gpio-cells = <4>;
233 };
234
235 gpe3: gpio-controller@11400140 {
236 compatible = "samsung,exynos4-gpio";
237 reg = <0x11400140 0x20>;
238 #gpio-cells = <4>;
239 };
240
241 gpe4: gpio-controller@11400160 {
242 compatible = "samsung,exynos4-gpio";
243 reg = <0x11400160 0x20>;
244 #gpio-cells = <4>;
245 };
246
247 gpf0: gpio-controller@11400180 {
248 compatible = "samsung,exynos4-gpio";
249 reg = <0x11400180 0x20>;
250 #gpio-cells = <4>;
251 };
252
253 gpf1: gpio-controller@114001A0 {
254 compatible = "samsung,exynos4-gpio";
255 reg = <0x114001A0 0x20>;
256 #gpio-cells = <4>;
257 };
258
259 gpf2: gpio-controller@114001C0 {
260 compatible = "samsung,exynos4-gpio";
261 reg = <0x114001C0 0x20>;
262 #gpio-cells = <4>;
263 };
264
265 gpf3: gpio-controller@114001E0 {
266 compatible = "samsung,exynos4-gpio";
267 reg = <0x114001E0 0x20>;
268 #gpio-cells = <4>;
269 };
270
271 gpj0: gpio-controller@11000000 {
272 compatible = "samsung,exynos4-gpio";
273 reg = <0x11000000 0x20>;
274 #gpio-cells = <4>;
275 };
276
277 gpj1: gpio-controller@11000020 {
278 compatible = "samsung,exynos4-gpio";
279 reg = <0x11000020 0x20>;
280 #gpio-cells = <4>;
281 };
282
283 gpk0: gpio-controller@11000040 {
284 compatible = "samsung,exynos4-gpio";
285 reg = <0x11000040 0x20>;
286 #gpio-cells = <4>;
287 };
288
289 gpk1: gpio-controller@11000060 {
290 compatible = "samsung,exynos4-gpio";
291 reg = <0x11000060 0x20>;
292 #gpio-cells = <4>;
293 };
294
295 gpk2: gpio-controller@11000080 {
296 compatible = "samsung,exynos4-gpio";
297 reg = <0x11000080 0x20>;
298 #gpio-cells = <4>;
299 };
300
301 gpk3: gpio-controller@110000A0 {
302 compatible = "samsung,exynos4-gpio";
303 reg = <0x110000A0 0x20>;
304 #gpio-cells = <4>;
305 };
306
307 gpl0: gpio-controller@110000C0 {
308 compatible = "samsung,exynos4-gpio";
309 reg = <0x110000C0 0x20>;
310 #gpio-cells = <4>;
311 };
312
313 gpl1: gpio-controller@110000E0 {
314 compatible = "samsung,exynos4-gpio";
315 reg = <0x110000E0 0x20>;
316 #gpio-cells = <4>;
317 };
318
319 gpl2: gpio-controller@11000100 {
320 compatible = "samsung,exynos4-gpio";
321 reg = <0x11000100 0x20>;
322 #gpio-cells = <4>;
323 };
324
325 gpy0: gpio-controller@11000120 {
326 compatible = "samsung,exynos4-gpio";
327 reg = <0x11000120 0x20>;
328 #gpio-cells = <4>;
329 };
330
331 gpy1: gpio-controller@11000140 {
332 compatible = "samsung,exynos4-gpio";
333 reg = <0x11000140 0x20>;
334 #gpio-cells = <4>;
335 };
336
337 gpy2: gpio-controller@11000160 {
338 compatible = "samsung,exynos4-gpio";
339 reg = <0x11000160 0x20>;
340 #gpio-cells = <4>;
341 };
342
343 gpy3: gpio-controller@11000180 {
344 compatible = "samsung,exynos4-gpio";
345 reg = <0x11000180 0x20>;
346 #gpio-cells = <4>;
347 };
348
349 gpy4: gpio-controller@110001A0 {
350 compatible = "samsung,exynos4-gpio";
351 reg = <0x110001A0 0x20>;
352 #gpio-cells = <4>;
353 };
354
355 gpy5: gpio-controller@110001C0 {
356 compatible = "samsung,exynos4-gpio";
357 reg = <0x110001C0 0x20>;
358 #gpio-cells = <4>;
359 };
360
361 gpy6: gpio-controller@110001E0 {
362 compatible = "samsung,exynos4-gpio";
363 reg = <0x110001E0 0x20>;
364 #gpio-cells = <4>;
365 };
366
367 gpx0: gpio-controller@11000C00 {
368 compatible = "samsung,exynos4-gpio";
369 reg = <0x11000C00 0x20>;
370 #gpio-cells = <4>;
371 };
372
373 gpx1: gpio-controller@11000C20 {
374 compatible = "samsung,exynos4-gpio";
375 reg = <0x11000C20 0x20>;
376 #gpio-cells = <4>;
377 };
378
379 gpx2: gpio-controller@11000C40 {
380 compatible = "samsung,exynos4-gpio";
381 reg = <0x11000C40 0x20>;
382 #gpio-cells = <4>;
383 };
384
385 gpx3: gpio-controller@11000C60 {
386 compatible = "samsung,exynos4-gpio";
387 reg = <0x11000C60 0x20>;
388 #gpio-cells = <4>;
389 };
390
391 gpz: gpio-controller@03860000 {
392 compatible = "samsung,exynos4-gpio";
393 reg = <0x03860000 0x20>;
394 #gpio-cells = <4>;
395 };
396 };
397};
diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig
index 724ec0f3560d..0afcc3b0f870 100644
--- a/arch/arm/mach-exynos/Kconfig
+++ b/arch/arm/mach-exynos/Kconfig
@@ -57,6 +57,11 @@ config EXYNOS4_MCT
57 help 57 help
58 Use MCT (Multi Core Timer) as kernel timers 58 Use MCT (Multi Core Timer) as kernel timers
59 59
60config EXYNOS4_DEV_DMA
61 bool
62 help
63 Compile in amba device definitions for DMA controller
64
60config EXYNOS4_DEV_AHCI 65config EXYNOS4_DEV_AHCI
61 bool 66 bool
62 help 67 help
@@ -177,6 +182,7 @@ config MACH_SMDKV310
177 select SAMSUNG_DEV_BACKLIGHT 182 select SAMSUNG_DEV_BACKLIGHT
178 select EXYNOS4_DEV_AHCI 183 select EXYNOS4_DEV_AHCI
179 select SAMSUNG_DEV_KEYPAD 184 select SAMSUNG_DEV_KEYPAD
185 select EXYNOS4_DEV_DMA
180 select EXYNOS4_DEV_PD 186 select EXYNOS4_DEV_PD
181 select SAMSUNG_DEV_PWM 187 select SAMSUNG_DEV_PWM
182 select EXYNOS4_DEV_SYSMMU 188 select EXYNOS4_DEV_SYSMMU
@@ -197,6 +203,7 @@ config MACH_ARMLEX4210
197 select S3C_DEV_HSMMC2 203 select S3C_DEV_HSMMC2
198 select S3C_DEV_HSMMC3 204 select S3C_DEV_HSMMC3
199 select EXYNOS4_DEV_AHCI 205 select EXYNOS4_DEV_AHCI
206 select EXYNOS4_DEV_DMA
200 select EXYNOS4_DEV_SYSMMU 207 select EXYNOS4_DEV_SYSMMU
201 select EXYNOS4_SETUP_SDHCI 208 select EXYNOS4_SETUP_SDHCI
202 help 209 help
@@ -222,6 +229,7 @@ config MACH_UNIVERSAL_C210
222 select S5P_DEV_MFC 229 select S5P_DEV_MFC
223 select S5P_DEV_ONENAND 230 select S5P_DEV_ONENAND
224 select S5P_DEV_TV 231 select S5P_DEV_TV
232 select EXYNOS4_DEV_DMA
225 select EXYNOS4_DEV_PD 233 select EXYNOS4_DEV_PD
226 select EXYNOS4_SETUP_FIMD0 234 select EXYNOS4_SETUP_FIMD0
227 select EXYNOS4_SETUP_I2C1 235 select EXYNOS4_SETUP_I2C1
@@ -255,6 +263,7 @@ config MACH_NURI
255 select S5P_DEV_MFC 263 select S5P_DEV_MFC
256 select S5P_DEV_USB_EHCI 264 select S5P_DEV_USB_EHCI
257 select S5P_SETUP_MIPIPHY 265 select S5P_SETUP_MIPIPHY
266 select EXYNOS4_DEV_DMA
258 select EXYNOS4_DEV_PD 267 select EXYNOS4_DEV_PD
259 select EXYNOS4_SETUP_FIMC 268 select EXYNOS4_SETUP_FIMC
260 select EXYNOS4_SETUP_FIMD0 269 select EXYNOS4_SETUP_FIMD0
@@ -287,6 +296,7 @@ config MACH_ORIGEN
287 select S5P_DEV_USB_EHCI 296 select S5P_DEV_USB_EHCI
288 select SAMSUNG_DEV_BACKLIGHT 297 select SAMSUNG_DEV_BACKLIGHT
289 select SAMSUNG_DEV_PWM 298 select SAMSUNG_DEV_PWM
299 select EXYNOS4_DEV_DMA
290 select EXYNOS4_DEV_PD 300 select EXYNOS4_DEV_PD
291 select EXYNOS4_SETUP_FIMD0 301 select EXYNOS4_SETUP_FIMD0
292 select EXYNOS4_SETUP_SDHCI 302 select EXYNOS4_SETUP_SDHCI
@@ -327,6 +337,20 @@ config MACH_SMDK4412
327 Machine support for Samsung SMDK4412 337 Machine support for Samsung SMDK4412
328endif 338endif
329 339
340comment "Flattened Device Tree based board for Exynos4 based SoC"
341
342config MACH_EXYNOS4_DT
343 bool "Samsung Exynos4 Machine using device tree"
344 select CPU_EXYNOS4210
345 select USE_OF
346 select ARM_AMBA
347 select HAVE_SAMSUNG_KEYPAD if INPUT_KEYBOARD
348 help
349 Machine support for Samsung Exynos4 machine with device tree enabled.
350 Select this if a fdt blob is available for the Exynos4 SoC based board.
351 Note: This is under development and not all peripherals can be supported
352 with this machine file.
353
330if ARCH_EXYNOS4 354if ARCH_EXYNOS4
331 355
332comment "Configuration for HSMMC 8-bit bus width" 356comment "Configuration for HSMMC 8-bit bus width"
diff --git a/arch/arm/mach-exynos/Makefile b/arch/arm/mach-exynos/Makefile
index 59069a35e40b..8d85ae635ac2 100644
--- a/arch/arm/mach-exynos/Makefile
+++ b/arch/arm/mach-exynos/Makefile
@@ -13,7 +13,7 @@ obj- :=
13# Core support for EXYNOS4 system 13# Core support for EXYNOS4 system
14 14
15obj-$(CONFIG_ARCH_EXYNOS4) += cpu.o init.o clock.o irq-combiner.o setup-i2c0.o 15obj-$(CONFIG_ARCH_EXYNOS4) += cpu.o init.o clock.o irq-combiner.o setup-i2c0.o
16obj-$(CONFIG_ARCH_EXYNOS4) += irq-eint.o dma.o pmu.o 16obj-$(CONFIG_ARCH_EXYNOS4) += irq-eint.o pmu.o
17obj-$(CONFIG_CPU_EXYNOS4210) += clock-exynos4210.o 17obj-$(CONFIG_CPU_EXYNOS4210) += clock-exynos4210.o
18obj-$(CONFIG_SOC_EXYNOS4212) += clock-exynos4212.o 18obj-$(CONFIG_SOC_EXYNOS4212) += clock-exynos4212.o
19obj-$(CONFIG_PM) += pm.o 19obj-$(CONFIG_PM) += pm.o
@@ -37,6 +37,8 @@ obj-$(CONFIG_MACH_ORIGEN) += mach-origen.o
37obj-$(CONFIG_MACH_SMDK4212) += mach-smdk4x12.o 37obj-$(CONFIG_MACH_SMDK4212) += mach-smdk4x12.o
38obj-$(CONFIG_MACH_SMDK4412) += mach-smdk4x12.o 38obj-$(CONFIG_MACH_SMDK4412) += mach-smdk4x12.o
39 39
40obj-$(CONFIG_MACH_EXYNOS4_DT) += mach-exynos4-dt.o
41
40# device support 42# device support
41 43
42obj-$(CONFIG_ARCH_EXYNOS4) += dev-audio.o 44obj-$(CONFIG_ARCH_EXYNOS4) += dev-audio.o
@@ -44,6 +46,7 @@ obj-$(CONFIG_EXYNOS4_DEV_AHCI) += dev-ahci.o
44obj-$(CONFIG_EXYNOS4_DEV_PD) += dev-pd.o 46obj-$(CONFIG_EXYNOS4_DEV_PD) += dev-pd.o
45obj-$(CONFIG_EXYNOS4_DEV_SYSMMU) += dev-sysmmu.o 47obj-$(CONFIG_EXYNOS4_DEV_SYSMMU) += dev-sysmmu.o
46obj-$(CONFIG_EXYNOS4_DEV_DWMCI) += dev-dwmci.o 48obj-$(CONFIG_EXYNOS4_DEV_DWMCI) += dev-dwmci.o
49obj-$(CONFIG_EXYNOS4_DEV_DMA) += dma.o
47 50
48obj-$(CONFIG_EXYNOS4_SETUP_FIMC) += setup-fimc.o 51obj-$(CONFIG_EXYNOS4_SETUP_FIMC) += setup-fimc.o
49obj-$(CONFIG_EXYNOS4_SETUP_FIMD0) += setup-fimd0.o 52obj-$(CONFIG_EXYNOS4_SETUP_FIMD0) += setup-fimd0.o
diff --git a/arch/arm/mach-exynos/clock.c b/arch/arm/mach-exynos/clock.c
index 2894f0adef5c..7dee8694486a 100644
--- a/arch/arm/mach-exynos/clock.c
+++ b/arch/arm/mach-exynos/clock.c
@@ -553,16 +553,6 @@ static struct clk init_clocks_off[] = {
553 .enable = exynos4_clk_dac_ctrl, 553 .enable = exynos4_clk_dac_ctrl,
554 .ctrlbit = (1 << 0), 554 .ctrlbit = (1 << 0),
555 }, { 555 }, {
556 .name = "dma",
557 .devname = "dma-pl330.0",
558 .enable = exynos4_clk_ip_fsys_ctrl,
559 .ctrlbit = (1 << 0),
560 }, {
561 .name = "dma",
562 .devname = "dma-pl330.1",
563 .enable = exynos4_clk_ip_fsys_ctrl,
564 .ctrlbit = (1 << 1),
565 }, {
566 .name = "adc", 556 .name = "adc",
567 .enable = exynos4_clk_ip_peril_ctrl, 557 .enable = exynos4_clk_ip_peril_ctrl,
568 .ctrlbit = (1 << 15), 558 .ctrlbit = (1 << 15),
@@ -778,6 +768,20 @@ static struct clk init_clocks[] = {
778 } 768 }
779}; 769};
780 770
771static struct clk clk_pdma0 = {
772 .name = "dma",
773 .devname = "dma-pl330.0",
774 .enable = exynos4_clk_ip_fsys_ctrl,
775 .ctrlbit = (1 << 0),
776};
777
778static struct clk clk_pdma1 = {
779 .name = "dma",
780 .devname = "dma-pl330.1",
781 .enable = exynos4_clk_ip_fsys_ctrl,
782 .ctrlbit = (1 << 1),
783};
784
781struct clk *clkset_group_list[] = { 785struct clk *clkset_group_list[] = {
782 [0] = &clk_ext_xtal_mux, 786 [0] = &clk_ext_xtal_mux,
783 [1] = &clk_xusbxti, 787 [1] = &clk_xusbxti,
@@ -1009,46 +1013,6 @@ static struct clksrc_clk clk_dout_mmc4 = {
1009 1013
1010static struct clksrc_clk clksrcs[] = { 1014static struct clksrc_clk clksrcs[] = {
1011 { 1015 {
1012 .clk = {
1013 .name = "uclk1",
1014 .devname = "s5pv210-uart.0",
1015 .enable = exynos4_clksrc_mask_peril0_ctrl,
1016 .ctrlbit = (1 << 0),
1017 },
1018 .sources = &clkset_group,
1019 .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 0, .size = 4 },
1020 .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 0, .size = 4 },
1021 }, {
1022 .clk = {
1023 .name = "uclk1",
1024 .devname = "s5pv210-uart.1",
1025 .enable = exynos4_clksrc_mask_peril0_ctrl,
1026 .ctrlbit = (1 << 4),
1027 },
1028 .sources = &clkset_group,
1029 .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 4, .size = 4 },
1030 .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 4, .size = 4 },
1031 }, {
1032 .clk = {
1033 .name = "uclk1",
1034 .devname = "s5pv210-uart.2",
1035 .enable = exynos4_clksrc_mask_peril0_ctrl,
1036 .ctrlbit = (1 << 8),
1037 },
1038 .sources = &clkset_group,
1039 .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 8, .size = 4 },
1040 .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 8, .size = 4 },
1041 }, {
1042 .clk = {
1043 .name = "uclk1",
1044 .devname = "s5pv210-uart.3",
1045 .enable = exynos4_clksrc_mask_peril0_ctrl,
1046 .ctrlbit = (1 << 12),
1047 },
1048 .sources = &clkset_group,
1049 .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 12, .size = 4 },
1050 .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 12, .size = 4 },
1051 }, {
1052 .clk = { 1016 .clk = {
1053 .name = "sclk_pwm", 1017 .name = "sclk_pwm",
1054 .enable = exynos4_clksrc_mask_peril0_ctrl, 1018 .enable = exynos4_clksrc_mask_peril0_ctrl,
@@ -1237,6 +1201,54 @@ static struct clksrc_clk clksrcs[] = {
1237 } 1201 }
1238}; 1202};
1239 1203
1204static struct clksrc_clk clk_sclk_uart0 = {
1205 .clk = {
1206 .name = "uclk1",
1207 .devname = "exynos4210-uart.0",
1208 .enable = exynos4_clksrc_mask_peril0_ctrl,
1209 .ctrlbit = (1 << 0),
1210 },
1211 .sources = &clkset_group,
1212 .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 0, .size = 4 },
1213 .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 0, .size = 4 },
1214};
1215
1216static struct clksrc_clk clk_sclk_uart1 = {
1217 .clk = {
1218 .name = "uclk1",
1219 .devname = "exynos4210-uart.1",
1220 .enable = exynos4_clksrc_mask_peril0_ctrl,
1221 .ctrlbit = (1 << 4),
1222 },
1223 .sources = &clkset_group,
1224 .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 4, .size = 4 },
1225 .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 4, .size = 4 },
1226};
1227
1228static struct clksrc_clk clk_sclk_uart2 = {
1229 .clk = {
1230 .name = "uclk1",
1231 .devname = "exynos4210-uart.2",
1232 .enable = exynos4_clksrc_mask_peril0_ctrl,
1233 .ctrlbit = (1 << 8),
1234 },
1235 .sources = &clkset_group,
1236 .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 8, .size = 4 },
1237 .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 8, .size = 4 },
1238};
1239
1240static struct clksrc_clk clk_sclk_uart3 = {
1241 .clk = {
1242 .name = "uclk1",
1243 .devname = "exynos4210-uart.3",
1244 .enable = exynos4_clksrc_mask_peril0_ctrl,
1245 .ctrlbit = (1 << 12),
1246 },
1247 .sources = &clkset_group,
1248 .reg_src = { .reg = S5P_CLKSRC_PERIL0, .shift = 12, .size = 4 },
1249 .reg_div = { .reg = S5P_CLKDIV_PERIL0, .shift = 12, .size = 4 },
1250};
1251
1240/* Clock initialization code */ 1252/* Clock initialization code */
1241static struct clksrc_clk *sysclks[] = { 1253static struct clksrc_clk *sysclks[] = {
1242 &clk_mout_apll, 1254 &clk_mout_apll,
@@ -1271,6 +1283,27 @@ static struct clksrc_clk *sysclks[] = {
1271 &clk_mout_mfc1, 1283 &clk_mout_mfc1,
1272}; 1284};
1273 1285
1286static struct clk *clk_cdev[] = {
1287 &clk_pdma0,
1288 &clk_pdma1,
1289};
1290
1291static struct clksrc_clk *clksrc_cdev[] = {
1292 &clk_sclk_uart0,
1293 &clk_sclk_uart1,
1294 &clk_sclk_uart2,
1295 &clk_sclk_uart3,
1296};
1297
1298static struct clk_lookup exynos4_clk_lookup[] = {
1299 CLKDEV_INIT("exynos4210-uart.0", "clk_uart_baud0", &clk_sclk_uart0.clk),
1300 CLKDEV_INIT("exynos4210-uart.1", "clk_uart_baud0", &clk_sclk_uart1.clk),
1301 CLKDEV_INIT("exynos4210-uart.2", "clk_uart_baud0", &clk_sclk_uart2.clk),
1302 CLKDEV_INIT("exynos4210-uart.3", "clk_uart_baud0", &clk_sclk_uart3.clk),
1303 CLKDEV_INIT("dma-pl330.0", "apb_pclk", &clk_pdma0),
1304 CLKDEV_INIT("dma-pl330.1", "apb_pclk", &clk_pdma1),
1305};
1306
1274static int xtal_rate; 1307static int xtal_rate;
1275 1308
1276static unsigned long exynos4_fout_apll_get_rate(struct clk *clk) 1309static unsigned long exynos4_fout_apll_get_rate(struct clk *clk)
@@ -1478,11 +1511,19 @@ void __init exynos4_register_clocks(void)
1478 for (ptr = 0; ptr < ARRAY_SIZE(sclk_tv); ptr++) 1511 for (ptr = 0; ptr < ARRAY_SIZE(sclk_tv); ptr++)
1479 s3c_register_clksrc(sclk_tv[ptr], 1); 1512 s3c_register_clksrc(sclk_tv[ptr], 1);
1480 1513
1514 for (ptr = 0; ptr < ARRAY_SIZE(clksrc_cdev); ptr++)
1515 s3c_register_clksrc(clksrc_cdev[ptr], 1);
1516
1481 s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs)); 1517 s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
1482 s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks)); 1518 s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
1483 1519
1520 s3c24xx_register_clocks(clk_cdev, ARRAY_SIZE(clk_cdev));
1521 for (ptr = 0; ptr < ARRAY_SIZE(clk_cdev); ptr++)
1522 s3c_disable_clocks(clk_cdev[ptr], 1);
1523
1484 s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); 1524 s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
1485 s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); 1525 s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
1526 clkdev_add_table(exynos4_clk_lookup, ARRAY_SIZE(exynos4_clk_lookup));
1486 1527
1487 register_syscore_ops(&exynos4_clock_syscore_ops); 1528 register_syscore_ops(&exynos4_clock_syscore_ops);
1488 s3c24xx_register_clock(&dummy_apb_pclk); 1529 s3c24xx_register_clock(&dummy_apb_pclk);
diff --git a/arch/arm/mach-exynos/cpu.c b/arch/arm/mach-exynos/cpu.c
index 90ec247f3b37..0eb7b6a6903d 100644
--- a/arch/arm/mach-exynos/cpu.c
+++ b/arch/arm/mach-exynos/cpu.c
@@ -10,6 +10,8 @@
10 10
11#include <linux/sched.h> 11#include <linux/sched.h>
12#include <linux/sysdev.h> 12#include <linux/sysdev.h>
13#include <linux/of.h>
14#include <linux/of_irq.h>
13 15
14#include <asm/mach/map.h> 16#include <asm/mach/map.h>
15#include <asm/mach/irq.h> 17#include <asm/mach/irq.h>
@@ -218,13 +220,26 @@ static void exynos4_gic_irq_fix_base(struct irq_data *d)
218 (gic_bank_offset * smp_processor_id()); 220 (gic_bank_offset * smp_processor_id());
219} 221}
220 222
223#ifdef CONFIG_OF
224static const struct of_device_id exynos4_dt_irq_match[] = {
225 { .compatible = "arm,cortex-a9-gic", .data = gic_of_init, },
226 {},
227};
228#endif
229
221void __init exynos4_init_irq(void) 230void __init exynos4_init_irq(void)
222{ 231{
223 int irq; 232 int irq;
224 233
225 gic_bank_offset = soc_is_exynos4412() ? 0x4000 : 0x8000; 234 gic_bank_offset = soc_is_exynos4412() ? 0x4000 : 0x8000;
226 235
227 gic_init(0, IRQ_PPI(0), S5P_VA_GIC_DIST, S5P_VA_GIC_CPU); 236 if (!of_have_populated_dt())
237 gic_init(0, IRQ_PPI(0), S5P_VA_GIC_DIST, S5P_VA_GIC_CPU);
238#ifdef CONFIG_OF
239 else
240 of_irq_init(exynos4_dt_irq_match);
241#endif
242
228 gic_arch_extn.irq_eoi = exynos4_gic_irq_fix_base; 243 gic_arch_extn.irq_eoi = exynos4_gic_irq_fix_base;
229 gic_arch_extn.irq_unmask = exynos4_gic_irq_fix_base; 244 gic_arch_extn.irq_unmask = exynos4_gic_irq_fix_base;
230 gic_arch_extn.irq_mask = exynos4_gic_irq_fix_base; 245 gic_arch_extn.irq_mask = exynos4_gic_irq_fix_base;
diff --git a/arch/arm/mach-exynos/dma.c b/arch/arm/mach-exynos/dma.c
index 9667c61e64fb..b10fcd270f07 100644
--- a/arch/arm/mach-exynos/dma.c
+++ b/arch/arm/mach-exynos/dma.c
@@ -24,6 +24,7 @@
24#include <linux/dma-mapping.h> 24#include <linux/dma-mapping.h>
25#include <linux/amba/bus.h> 25#include <linux/amba/bus.h>
26#include <linux/amba/pl330.h> 26#include <linux/amba/pl330.h>
27#include <linux/of.h>
27 28
28#include <asm/irq.h> 29#include <asm/irq.h>
29#include <plat/devs.h> 30#include <plat/devs.h>
@@ -35,95 +36,42 @@
35 36
36static u64 dma_dmamask = DMA_BIT_MASK(32); 37static u64 dma_dmamask = DMA_BIT_MASK(32);
37 38
38struct dma_pl330_peri pdma0_peri[28] = { 39u8 pdma0_peri[] = {
39 { 40 DMACH_PCM0_RX,
40 .peri_id = (u8)DMACH_PCM0_RX, 41 DMACH_PCM0_TX,
41 .rqtype = DEVTOMEM, 42 DMACH_PCM2_RX,
42 }, { 43 DMACH_PCM2_TX,
43 .peri_id = (u8)DMACH_PCM0_TX, 44 DMACH_MSM_REQ0,
44 .rqtype = MEMTODEV, 45 DMACH_MSM_REQ2,
45 }, { 46 DMACH_SPI0_RX,
46 .peri_id = (u8)DMACH_PCM2_RX, 47 DMACH_SPI0_TX,
47 .rqtype = DEVTOMEM, 48 DMACH_SPI2_RX,
48 }, { 49 DMACH_SPI2_TX,
49 .peri_id = (u8)DMACH_PCM2_TX, 50 DMACH_I2S0S_TX,
50 .rqtype = MEMTODEV, 51 DMACH_I2S0_RX,
51 }, { 52 DMACH_I2S0_TX,
52 .peri_id = (u8)DMACH_MSM_REQ0, 53 DMACH_I2S2_RX,
53 }, { 54 DMACH_I2S2_TX,
54 .peri_id = (u8)DMACH_MSM_REQ2, 55 DMACH_UART0_RX,
55 }, { 56 DMACH_UART0_TX,
56 .peri_id = (u8)DMACH_SPI0_RX, 57 DMACH_UART2_RX,
57 .rqtype = DEVTOMEM, 58 DMACH_UART2_TX,
58 }, { 59 DMACH_UART4_RX,
59 .peri_id = (u8)DMACH_SPI0_TX, 60 DMACH_UART4_TX,
60 .rqtype = MEMTODEV, 61 DMACH_SLIMBUS0_RX,
61 }, { 62 DMACH_SLIMBUS0_TX,
62 .peri_id = (u8)DMACH_SPI2_RX, 63 DMACH_SLIMBUS2_RX,
63 .rqtype = DEVTOMEM, 64 DMACH_SLIMBUS2_TX,
64 }, { 65 DMACH_SLIMBUS4_RX,
65 .peri_id = (u8)DMACH_SPI2_TX, 66 DMACH_SLIMBUS4_TX,
66 .rqtype = MEMTODEV, 67 DMACH_AC97_MICIN,
67 }, { 68 DMACH_AC97_PCMIN,
68 .peri_id = (u8)DMACH_I2S0S_TX, 69 DMACH_AC97_PCMOUT,
69 .rqtype = MEMTODEV,
70 }, {
71 .peri_id = (u8)DMACH_I2S0_RX,
72 .rqtype = DEVTOMEM,
73 }, {
74 .peri_id = (u8)DMACH_I2S0_TX,
75 .rqtype = MEMTODEV,
76 }, {
77 .peri_id = (u8)DMACH_UART0_RX,
78 .rqtype = DEVTOMEM,
79 }, {
80 .peri_id = (u8)DMACH_UART0_TX,
81 .rqtype = MEMTODEV,
82 }, {
83 .peri_id = (u8)DMACH_UART2_RX,
84 .rqtype = DEVTOMEM,
85 }, {
86 .peri_id = (u8)DMACH_UART2_TX,
87 .rqtype = MEMTODEV,
88 }, {
89 .peri_id = (u8)DMACH_UART4_RX,
90 .rqtype = DEVTOMEM,
91 }, {
92 .peri_id = (u8)DMACH_UART4_TX,
93 .rqtype = MEMTODEV,
94 }, {
95 .peri_id = (u8)DMACH_SLIMBUS0_RX,
96 .rqtype = DEVTOMEM,
97 }, {
98 .peri_id = (u8)DMACH_SLIMBUS0_TX,
99 .rqtype = MEMTODEV,
100 }, {
101 .peri_id = (u8)DMACH_SLIMBUS2_RX,
102 .rqtype = DEVTOMEM,
103 }, {
104 .peri_id = (u8)DMACH_SLIMBUS2_TX,
105 .rqtype = MEMTODEV,
106 }, {
107 .peri_id = (u8)DMACH_SLIMBUS4_RX,
108 .rqtype = DEVTOMEM,
109 }, {
110 .peri_id = (u8)DMACH_SLIMBUS4_TX,
111 .rqtype = MEMTODEV,
112 }, {
113 .peri_id = (u8)DMACH_AC97_MICIN,
114 .rqtype = DEVTOMEM,
115 }, {
116 .peri_id = (u8)DMACH_AC97_PCMIN,
117 .rqtype = DEVTOMEM,
118 }, {
119 .peri_id = (u8)DMACH_AC97_PCMOUT,
120 .rqtype = MEMTODEV,
121 },
122}; 70};
123 71
124struct dma_pl330_platdata exynos4_pdma0_pdata = { 72struct dma_pl330_platdata exynos4_pdma0_pdata = {
125 .nr_valid_peri = ARRAY_SIZE(pdma0_peri), 73 .nr_valid_peri = ARRAY_SIZE(pdma0_peri),
126 .peri = pdma0_peri, 74 .peri_id = pdma0_peri,
127}; 75};
128 76
129struct amba_device exynos4_device_pdma0 = { 77struct amba_device exynos4_device_pdma0 = {
@@ -142,86 +90,37 @@ struct amba_device exynos4_device_pdma0 = {
142 .periphid = 0x00041330, 90 .periphid = 0x00041330,
143}; 91};
144 92
145struct dma_pl330_peri pdma1_peri[25] = { 93u8 pdma1_peri[] = {
146 { 94 DMACH_PCM0_RX,
147 .peri_id = (u8)DMACH_PCM0_RX, 95 DMACH_PCM0_TX,
148 .rqtype = DEVTOMEM, 96 DMACH_PCM1_RX,
149 }, { 97 DMACH_PCM1_TX,
150 .peri_id = (u8)DMACH_PCM0_TX, 98 DMACH_MSM_REQ1,
151 .rqtype = MEMTODEV, 99 DMACH_MSM_REQ3,
152 }, { 100 DMACH_SPI1_RX,
153 .peri_id = (u8)DMACH_PCM1_RX, 101 DMACH_SPI1_TX,
154 .rqtype = DEVTOMEM, 102 DMACH_I2S0S_TX,
155 }, { 103 DMACH_I2S0_RX,
156 .peri_id = (u8)DMACH_PCM1_TX, 104 DMACH_I2S0_TX,
157 .rqtype = MEMTODEV, 105 DMACH_I2S1_RX,
158 }, { 106 DMACH_I2S1_TX,
159 .peri_id = (u8)DMACH_MSM_REQ1, 107 DMACH_UART0_RX,
160 }, { 108 DMACH_UART0_TX,
161 .peri_id = (u8)DMACH_MSM_REQ3, 109 DMACH_UART1_RX,
162 }, { 110 DMACH_UART1_TX,
163 .peri_id = (u8)DMACH_SPI1_RX, 111 DMACH_UART3_RX,
164 .rqtype = DEVTOMEM, 112 DMACH_UART3_TX,
165 }, { 113 DMACH_SLIMBUS1_RX,
166 .peri_id = (u8)DMACH_SPI1_TX, 114 DMACH_SLIMBUS1_TX,
167 .rqtype = MEMTODEV, 115 DMACH_SLIMBUS3_RX,
168 }, { 116 DMACH_SLIMBUS3_TX,
169 .peri_id = (u8)DMACH_I2S0S_TX, 117 DMACH_SLIMBUS5_RX,
170 .rqtype = MEMTODEV, 118 DMACH_SLIMBUS5_TX,
171 }, {
172 .peri_id = (u8)DMACH_I2S0_RX,
173 .rqtype = DEVTOMEM,
174 }, {
175 .peri_id = (u8)DMACH_I2S0_TX,
176 .rqtype = MEMTODEV,
177 }, {
178 .peri_id = (u8)DMACH_I2S1_RX,
179 .rqtype = DEVTOMEM,
180 }, {
181 .peri_id = (u8)DMACH_I2S1_TX,
182 .rqtype = MEMTODEV,
183 }, {
184 .peri_id = (u8)DMACH_UART0_RX,
185 .rqtype = DEVTOMEM,
186 }, {
187 .peri_id = (u8)DMACH_UART0_TX,
188 .rqtype = MEMTODEV,
189 }, {
190 .peri_id = (u8)DMACH_UART1_RX,
191 .rqtype = DEVTOMEM,
192 }, {
193 .peri_id = (u8)DMACH_UART1_TX,
194 .rqtype = MEMTODEV,
195 }, {
196 .peri_id = (u8)DMACH_UART3_RX,
197 .rqtype = DEVTOMEM,
198 }, {
199 .peri_id = (u8)DMACH_UART3_TX,
200 .rqtype = MEMTODEV,
201 }, {
202 .peri_id = (u8)DMACH_SLIMBUS1_RX,
203 .rqtype = DEVTOMEM,
204 }, {
205 .peri_id = (u8)DMACH_SLIMBUS1_TX,
206 .rqtype = MEMTODEV,
207 }, {
208 .peri_id = (u8)DMACH_SLIMBUS3_RX,
209 .rqtype = DEVTOMEM,
210 }, {
211 .peri_id = (u8)DMACH_SLIMBUS3_TX,
212 .rqtype = MEMTODEV,
213 }, {
214 .peri_id = (u8)DMACH_SLIMBUS5_RX,
215 .rqtype = DEVTOMEM,
216 }, {
217 .peri_id = (u8)DMACH_SLIMBUS5_TX,
218 .rqtype = MEMTODEV,
219 },
220}; 119};
221 120
222struct dma_pl330_platdata exynos4_pdma1_pdata = { 121struct dma_pl330_platdata exynos4_pdma1_pdata = {
223 .nr_valid_peri = ARRAY_SIZE(pdma1_peri), 122 .nr_valid_peri = ARRAY_SIZE(pdma1_peri),
224 .peri = pdma1_peri, 123 .peri_id = pdma1_peri,
225}; 124};
226 125
227struct amba_device exynos4_device_pdma1 = { 126struct amba_device exynos4_device_pdma1 = {
@@ -242,7 +141,15 @@ struct amba_device exynos4_device_pdma1 = {
242 141
243static int __init exynos4_dma_init(void) 142static int __init exynos4_dma_init(void)
244{ 143{
144 if (of_have_populated_dt())
145 return 0;
146
147 dma_cap_set(DMA_SLAVE, exynos4_pdma0_pdata.cap_mask);
148 dma_cap_set(DMA_CYCLIC, exynos4_pdma0_pdata.cap_mask);
245 amba_device_register(&exynos4_device_pdma0, &iomem_resource); 149 amba_device_register(&exynos4_device_pdma0, &iomem_resource);
150
151 dma_cap_set(DMA_SLAVE, exynos4_pdma1_pdata.cap_mask);
152 dma_cap_set(DMA_CYCLIC, exynos4_pdma1_pdata.cap_mask);
246 amba_device_register(&exynos4_device_pdma1, &iomem_resource); 153 amba_device_register(&exynos4_device_pdma1, &iomem_resource);
247 154
248 return 0; 155 return 0;
diff --git a/arch/arm/mach-exynos/include/mach/entry-macro.S b/arch/arm/mach-exynos/include/mach/entry-macro.S
index f5e9fd8e37b4..d7dfcd7eb921 100644
--- a/arch/arm/mach-exynos/include/mach/entry-macro.S
+++ b/arch/arm/mach-exynos/include/mach/entry-macro.S
@@ -72,7 +72,6 @@
72 cmpcc \irqnr, \irqnr 72 cmpcc \irqnr, \irqnr
73 cmpne \irqnr, \tmp 73 cmpne \irqnr, \tmp
74 cmpcs \irqnr, \irqnr 74 cmpcs \irqnr, \irqnr
75 addne \irqnr, \irqnr, #32
76 75
77 .endm 76 .endm
78 77
diff --git a/arch/arm/mach-exynos/include/mach/irqs.h b/arch/arm/mach-exynos/include/mach/irqs.h
index dfd4b7eecb90..713dd5251c64 100644
--- a/arch/arm/mach-exynos/include/mach/irqs.h
+++ b/arch/arm/mach-exynos/include/mach/irqs.h
@@ -17,13 +17,13 @@
17 17
18/* PPI: Private Peripheral Interrupt */ 18/* PPI: Private Peripheral Interrupt */
19 19
20#define IRQ_PPI(x) S5P_IRQ(x+16) 20#define IRQ_PPI(x) (x+16)
21 21
22#define IRQ_MCT_LOCALTIMER IRQ_PPI(12) 22#define IRQ_MCT_LOCALTIMER IRQ_PPI(12)
23 23
24/* SPI: Shared Peripheral Interrupt */ 24/* SPI: Shared Peripheral Interrupt */
25 25
26#define IRQ_SPI(x) S5P_IRQ(x+32) 26#define IRQ_SPI(x) (x+32)
27 27
28#define IRQ_EINT0 IRQ_SPI(16) 28#define IRQ_EINT0 IRQ_SPI(16)
29#define IRQ_EINT1 IRQ_SPI(17) 29#define IRQ_EINT1 IRQ_SPI(17)
@@ -163,7 +163,9 @@
163#define IRQ_GPIO2_NR_GROUPS 9 163#define IRQ_GPIO2_NR_GROUPS 9
164#define IRQ_GPIO_END (S5P_GPIOINT_BASE + S5P_GPIOINT_COUNT) 164#define IRQ_GPIO_END (S5P_GPIOINT_BASE + S5P_GPIOINT_COUNT)
165 165
166#define IRQ_TIMER_BASE (IRQ_GPIO_END + 64)
167
166/* Set the default NR_IRQS */ 168/* Set the default NR_IRQS */
167#define NR_IRQS (IRQ_GPIO_END + 64) 169#define NR_IRQS (IRQ_TIMER_BASE + IRQ_TIMER_COUNT)
168 170
169#endif /* __ASM_ARCH_IRQS_H */ 171#endif /* __ASM_ARCH_IRQS_H */
diff --git a/arch/arm/mach-exynos/init.c b/arch/arm/mach-exynos/init.c
index a8a83e3881a4..5b35978029be 100644
--- a/arch/arm/mach-exynos/init.c
+++ b/arch/arm/mach-exynos/init.c
@@ -14,29 +14,14 @@
14#include <plat/devs.h> 14#include <plat/devs.h>
15#include <plat/regs-serial.h> 15#include <plat/regs-serial.h>
16 16
17static struct s3c24xx_uart_clksrc exynos4_serial_clocks[] = {
18 [0] = {
19 .name = "uclk1",
20 .divisor = 1,
21 .min_baud = 0,
22 .max_baud = 0,
23 },
24};
25
26/* uart registration process */ 17/* uart registration process */
27void __init exynos4_common_init_uarts(struct s3c2410_uartcfg *cfg, int no) 18void __init exynos4_common_init_uarts(struct s3c2410_uartcfg *cfg, int no)
28{ 19{
29 struct s3c2410_uartcfg *tcfg = cfg; 20 struct s3c2410_uartcfg *tcfg = cfg;
30 u32 ucnt; 21 u32 ucnt;
31 22
32 for (ucnt = 0; ucnt < no; ucnt++, tcfg++) { 23 for (ucnt = 0; ucnt < no; ucnt++, tcfg++)
33 if (!tcfg->clocks) { 24 tcfg->has_fracval = 1;
34 tcfg->has_fracval = 1;
35 tcfg->clocks = exynos4_serial_clocks;
36 tcfg->clocks_size = ARRAY_SIZE(exynos4_serial_clocks);
37 }
38 tcfg->flags |= NO_NEED_CHECK_CLKSRC;
39 }
40 25
41 s3c24xx_init_uartdevs("s5pv210-uart", s5p_uart_resources, cfg, no); 26 s3c24xx_init_uartdevs("exynos4210-uart", s5p_uart_resources, cfg, no);
42} 27}
diff --git a/arch/arm/mach-exynos/mach-exynos4-dt.c b/arch/arm/mach-exynos/mach-exynos4-dt.c
new file mode 100644
index 000000000000..85fa02767d67
--- /dev/null
+++ b/arch/arm/mach-exynos/mach-exynos4-dt.c
@@ -0,0 +1,85 @@
1/*
2 * Samsung's Exynos4210 flattened device tree enabled machine
3 *
4 * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
5 * http://www.samsung.com
6 * Copyright (c) 2010-2011 Linaro Ltd.
7 * www.linaro.org
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12*/
13
14#include <linux/of_platform.h>
15#include <linux/serial_core.h>
16
17#include <asm/mach/arch.h>
18#include <mach/map.h>
19
20#include <plat/cpu.h>
21#include <plat/regs-serial.h>
22#include <plat/exynos4.h>
23
24/*
25 * The following lookup table is used to override device names when devices
26 * are registered from device tree. This is temporarily added to enable
27 * device tree support addition for the Exynos4 architecture.
28 *
29 * For drivers that require platform data to be provided from the machine
30 * file, a platform data pointer can also be supplied along with the
31 * devices names. Usually, the platform data elements that cannot be parsed
32 * from the device tree by the drivers (example: function pointers) are
33 * supplied. But it should be noted that this is a temporary mechanism and
34 * at some point, the drivers should be capable of parsing all the platform
35 * data from the device tree.
36 */
37static const struct of_dev_auxdata exynos4210_auxdata_lookup[] __initconst = {
38 OF_DEV_AUXDATA("samsung,exynos4210-uart", S5P_PA_UART0,
39 "exynos4210-uart.0", NULL),
40 OF_DEV_AUXDATA("samsung,exynos4210-uart", S5P_PA_UART1,
41 "exynos4210-uart.1", NULL),
42 OF_DEV_AUXDATA("samsung,exynos4210-uart", S5P_PA_UART2,
43 "exynos4210-uart.2", NULL),
44 OF_DEV_AUXDATA("samsung,exynos4210-uart", S5P_PA_UART3,
45 "exynos4210-uart.3", NULL),
46 OF_DEV_AUXDATA("samsung,exynos4210-sdhci", EXYNOS4_PA_HSMMC(0),
47 "exynos4-sdhci.0", NULL),
48 OF_DEV_AUXDATA("samsung,exynos4210-sdhci", EXYNOS4_PA_HSMMC(1),
49 "exynos4-sdhci.1", NULL),
50 OF_DEV_AUXDATA("samsung,exynos4210-sdhci", EXYNOS4_PA_HSMMC(2),
51 "exynos4-sdhci.2", NULL),
52 OF_DEV_AUXDATA("samsung,exynos4210-sdhci", EXYNOS4_PA_HSMMC(3),
53 "exynos4-sdhci.3", NULL),
54 OF_DEV_AUXDATA("samsung,s3c2440-i2c", EXYNOS4_PA_IIC(0),
55 "s3c2440-i2c.0", NULL),
56 OF_DEV_AUXDATA("arm,pl330", EXYNOS4_PA_PDMA0, "dma-pl330.0", NULL),
57 OF_DEV_AUXDATA("arm,pl330", EXYNOS4_PA_PDMA1, "dma-pl330.1", NULL),
58 {},
59};
60
61static void __init exynos4210_dt_map_io(void)
62{
63 s5p_init_io(NULL, 0, S5P_VA_CHIPID);
64 s3c24xx_init_clocks(24000000);
65}
66
67static void __init exynos4210_dt_machine_init(void)
68{
69 of_platform_populate(NULL, of_default_bus_match_table,
70 exynos4210_auxdata_lookup, NULL);
71}
72
73static char const *exynos4210_dt_compat[] __initdata = {
74 "samsung,exynos4210",
75 NULL
76};
77
78DT_MACHINE_START(EXYNOS4210_DT, "Samsung Exynos4 (Flattened Device Tree)")
79 /* Maintainer: Thomas Abraham <thomas.abraham@linaro.org> */
80 .init_irq = exynos4_init_irq,
81 .map_io = exynos4210_dt_map_io,
82 .init_machine = exynos4210_dt_machine_init,
83 .timer = &exynos4_timer,
84 .dt_compat = exynos4210_dt_compat,
85MACHINE_END
diff --git a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c
index a20ae1ad4062..71b955877793 100644
--- a/arch/arm/mach-s3c2410/mach-bast.c
+++ b/arch/arm/mach-s3c2410/mach-bast.c
@@ -164,22 +164,6 @@ static struct map_desc bast_iodesc[] __initdata = {
164#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB 164#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
165#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE 165#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
166 166
167static struct s3c24xx_uart_clksrc bast_serial_clocks[] = {
168 [0] = {
169 .name = "uclk",
170 .divisor = 1,
171 .min_baud = 0,
172 .max_baud = 0,
173 },
174 [1] = {
175 .name = "pclk",
176 .divisor = 1,
177 .min_baud = 0,
178 .max_baud = 0,
179 }
180};
181
182
183static struct s3c2410_uartcfg bast_uartcfgs[] __initdata = { 167static struct s3c2410_uartcfg bast_uartcfgs[] __initdata = {
184 [0] = { 168 [0] = {
185 .hwport = 0, 169 .hwport = 0,
@@ -187,8 +171,6 @@ static struct s3c2410_uartcfg bast_uartcfgs[] __initdata = {
187 .ucon = UCON, 171 .ucon = UCON,
188 .ulcon = ULCON, 172 .ulcon = ULCON,
189 .ufcon = UFCON, 173 .ufcon = UFCON,
190 .clocks = bast_serial_clocks,
191 .clocks_size = ARRAY_SIZE(bast_serial_clocks),
192 }, 174 },
193 [1] = { 175 [1] = {
194 .hwport = 1, 176 .hwport = 1,
@@ -196,8 +178,6 @@ static struct s3c2410_uartcfg bast_uartcfgs[] __initdata = {
196 .ucon = UCON, 178 .ucon = UCON,
197 .ulcon = ULCON, 179 .ulcon = ULCON,
198 .ufcon = UFCON, 180 .ufcon = UFCON,
199 .clocks = bast_serial_clocks,
200 .clocks_size = ARRAY_SIZE(bast_serial_clocks),
201 }, 181 },
202 /* port 2 is not actually used */ 182 /* port 2 is not actually used */
203 [2] = { 183 [2] = {
@@ -206,8 +186,6 @@ static struct s3c2410_uartcfg bast_uartcfgs[] __initdata = {
206 .ucon = UCON, 186 .ucon = UCON,
207 .ulcon = ULCON, 187 .ulcon = ULCON,
208 .ufcon = UFCON, 188 .ufcon = UFCON,
209 .clocks = bast_serial_clocks,
210 .clocks_size = ARRAY_SIZE(bast_serial_clocks),
211 } 189 }
212}; 190};
213 191
diff --git a/arch/arm/mach-s3c2410/mach-vr1000.c b/arch/arm/mach-s3c2410/mach-vr1000.c
index df47e8e90065..0f0a9a1795e9 100644
--- a/arch/arm/mach-s3c2410/mach-vr1000.c
+++ b/arch/arm/mach-s3c2410/mach-vr1000.c
@@ -109,23 +109,6 @@ static struct map_desc vr1000_iodesc[] __initdata = {
109#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB 109#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
110#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE 110#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
111 111
112/* uart clock source(s) */
113
114static struct s3c24xx_uart_clksrc vr1000_serial_clocks[] = {
115 [0] = {
116 .name = "uclk",
117 .divisor = 1,
118 .min_baud = 0,
119 .max_baud = 0,
120 },
121 [1] = {
122 .name = "pclk",
123 .divisor = 1,
124 .min_baud = 0,
125 .max_baud = 0.
126 }
127};
128
129static struct s3c2410_uartcfg vr1000_uartcfgs[] __initdata = { 112static struct s3c2410_uartcfg vr1000_uartcfgs[] __initdata = {
130 [0] = { 113 [0] = {
131 .hwport = 0, 114 .hwport = 0,
@@ -133,8 +116,6 @@ static struct s3c2410_uartcfg vr1000_uartcfgs[] __initdata = {
133 .ucon = UCON, 116 .ucon = UCON,
134 .ulcon = ULCON, 117 .ulcon = ULCON,
135 .ufcon = UFCON, 118 .ufcon = UFCON,
136 .clocks = vr1000_serial_clocks,
137 .clocks_size = ARRAY_SIZE(vr1000_serial_clocks),
138 }, 119 },
139 [1] = { 120 [1] = {
140 .hwport = 1, 121 .hwport = 1,
@@ -142,8 +123,6 @@ static struct s3c2410_uartcfg vr1000_uartcfgs[] __initdata = {
142 .ucon = UCON, 123 .ucon = UCON,
143 .ulcon = ULCON, 124 .ulcon = ULCON,
144 .ufcon = UFCON, 125 .ufcon = UFCON,
145 .clocks = vr1000_serial_clocks,
146 .clocks_size = ARRAY_SIZE(vr1000_serial_clocks),
147 }, 126 },
148 /* port 2 is not actually used */ 127 /* port 2 is not actually used */
149 [2] = { 128 [2] = {
@@ -152,9 +131,6 @@ static struct s3c2410_uartcfg vr1000_uartcfgs[] __initdata = {
152 .ucon = UCON, 131 .ucon = UCON,
153 .ulcon = ULCON, 132 .ulcon = ULCON,
154 .ufcon = UFCON, 133 .ufcon = UFCON,
155 .clocks = vr1000_serial_clocks,
156 .clocks_size = ARRAY_SIZE(vr1000_serial_clocks),
157
158 } 134 }
159}; 135};
160 136
diff --git a/arch/arm/mach-s3c2410/s3c2410.c b/arch/arm/mach-s3c2410/s3c2410.c
index 3d7ebc557a72..af74927bca14 100644
--- a/arch/arm/mach-s3c2410/s3c2410.c
+++ b/arch/arm/mach-s3c2410/s3c2410.c
@@ -123,12 +123,18 @@ static struct clk s3c2410_armclk = {
123 .id = -1, 123 .id = -1,
124}; 124};
125 125
126static struct clk_lookup s3c2410_clk_lookup[] = {
127 CLKDEV_INIT(NULL, "clk_uart_baud0", &clk_p),
128 CLKDEV_INIT(NULL, "clk_uart_baud1", &s3c24xx_uclk),
129};
130
126void __init s3c2410_init_clocks(int xtal) 131void __init s3c2410_init_clocks(int xtal)
127{ 132{
128 s3c24xx_register_baseclocks(xtal); 133 s3c24xx_register_baseclocks(xtal);
129 s3c2410_setup_clocks(); 134 s3c2410_setup_clocks();
130 s3c2410_baseclk_add(); 135 s3c2410_baseclk_add();
131 s3c24xx_register_clock(&s3c2410_armclk); 136 s3c24xx_register_clock(&s3c2410_armclk);
137 clkdev_add_table(s3c2410_clk_lookup, ARRAY_SIZE(s3c2410_clk_lookup));
132} 138}
133 139
134struct sysdev_class s3c2410_sysclass = { 140struct sysdev_class s3c2410_sysclass = {
diff --git a/arch/arm/mach-s3c2412/clock.c b/arch/arm/mach-s3c2412/clock.c
index 140711db6c89..cd50291931f7 100644
--- a/arch/arm/mach-s3c2412/clock.c
+++ b/arch/arm/mach-s3c2412/clock.c
@@ -659,6 +659,12 @@ static struct clk *clks[] __initdata = {
659 &clk_armclk, 659 &clk_armclk,
660}; 660};
661 661
662static struct clk_lookup s3c2412_clk_lookup[] = {
663 CLKDEV_INIT(NULL, "clk_uart_baud1", &s3c24xx_uclk),
664 CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_p),
665 CLKDEV_INIT(NULL, "clk_uart_baud3", &clk_usysclk),
666};
667
662int __init s3c2412_baseclk_add(void) 668int __init s3c2412_baseclk_add(void)
663{ 669{
664 unsigned long clkcon = __raw_readl(S3C2410_CLKCON); 670 unsigned long clkcon = __raw_readl(S3C2410_CLKCON);
@@ -751,6 +757,7 @@ int __init s3c2412_baseclk_add(void)
751 s3c2412_clkcon_enable(clkp, 0); 757 s3c2412_clkcon_enable(clkp, 0);
752 } 758 }
753 759
760 clkdev_add_table(s3c2412_clk_lookup, ARRAY_SIZE(s3c2412_clk_lookup));
754 s3c_pwmclk_init(); 761 s3c_pwmclk_init();
755 return 0; 762 return 0;
756} 763}
diff --git a/arch/arm/mach-s3c2440/clock.c b/arch/arm/mach-s3c2440/clock.c
index f9e6bdaf41d2..c9879af42b08 100644
--- a/arch/arm/mach-s3c2440/clock.c
+++ b/arch/arm/mach-s3c2440/clock.c
@@ -34,6 +34,7 @@
34#include <linux/mutex.h> 34#include <linux/mutex.h>
35#include <linux/clk.h> 35#include <linux/clk.h>
36#include <linux/io.h> 36#include <linux/io.h>
37#include <linux/serial_core.h>
37 38
38#include <mach/hardware.h> 39#include <mach/hardware.h>
39#include <linux/atomic.h> 40#include <linux/atomic.h>
@@ -43,6 +44,7 @@
43 44
44#include <plat/clock.h> 45#include <plat/clock.h>
45#include <plat/cpu.h> 46#include <plat/cpu.h>
47#include <plat/regs-serial.h>
46 48
47/* S3C2440 extended clock support */ 49/* S3C2440 extended clock support */
48 50
@@ -108,6 +110,46 @@ static struct clk s3c2440_clk_ac97 = {
108 .ctrlbit = S3C2440_CLKCON_CAMERA, 110 .ctrlbit = S3C2440_CLKCON_CAMERA,
109}; 111};
110 112
113static unsigned long s3c2440_fclk_n_getrate(struct clk *clk)
114{
115 unsigned long ucon0, ucon1, ucon2, divisor;
116
117 /* the fun of calculating the uart divisors on the s3c2440 */
118 ucon0 = __raw_readl(S3C24XX_VA_UART0 + S3C2410_UCON);
119 ucon1 = __raw_readl(S3C24XX_VA_UART1 + S3C2410_UCON);
120 ucon2 = __raw_readl(S3C24XX_VA_UART2 + S3C2410_UCON);
121
122 ucon0 &= S3C2440_UCON0_DIVMASK;
123 ucon1 &= S3C2440_UCON1_DIVMASK;
124 ucon2 &= S3C2440_UCON2_DIVMASK;
125
126 if (ucon0 != 0)
127 divisor = (ucon0 >> S3C2440_UCON_DIVSHIFT) + 6;
128 else if (ucon1 != 0)
129 divisor = (ucon1 >> S3C2440_UCON_DIVSHIFT) + 21;
130 else if (ucon2 != 0)
131 divisor = (ucon2 >> S3C2440_UCON_DIVSHIFT) + 36;
132 else
133 /* manual calims 44, seems to be 9 */
134 divisor = 9;
135
136 return clk_get_rate(clk->parent) / divisor;
137}
138
139static struct clk s3c2440_clk_fclk_n = {
140 .name = "fclk_n",
141 .parent = &clk_f,
142 .ops = &(struct clk_ops) {
143 .get_rate = s3c2440_fclk_n_getrate,
144 },
145};
146
147static struct clk_lookup s3c2440_clk_lookup[] = {
148 CLKDEV_INIT(NULL, "clk_uart_baud1", &s3c24xx_uclk),
149 CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_p),
150 CLKDEV_INIT(NULL, "clk_uart_baud3", &s3c2440_clk_fclk_n),
151};
152
111static int s3c2440_clk_add(struct sys_device *sysdev) 153static int s3c2440_clk_add(struct sys_device *sysdev)
112{ 154{
113 struct clk *clock_upll; 155 struct clk *clock_upll;
@@ -126,10 +168,12 @@ static int s3c2440_clk_add(struct sys_device *sysdev)
126 s3c2440_clk_cam.parent = clock_h; 168 s3c2440_clk_cam.parent = clock_h;
127 s3c2440_clk_ac97.parent = clock_p; 169 s3c2440_clk_ac97.parent = clock_p;
128 s3c2440_clk_cam_upll.parent = clock_upll; 170 s3c2440_clk_cam_upll.parent = clock_upll;
171 s3c24xx_register_clock(&s3c2440_clk_fclk_n);
129 172
130 s3c24xx_register_clock(&s3c2440_clk_ac97); 173 s3c24xx_register_clock(&s3c2440_clk_ac97);
131 s3c24xx_register_clock(&s3c2440_clk_cam); 174 s3c24xx_register_clock(&s3c2440_clk_cam);
132 s3c24xx_register_clock(&s3c2440_clk_cam_upll); 175 s3c24xx_register_clock(&s3c2440_clk_cam_upll);
176 clkdev_add_table(s3c2440_clk_lookup, ARRAY_SIZE(s3c2440_clk_lookup));
133 177
134 clk_disable(&s3c2440_clk_ac97); 178 clk_disable(&s3c2440_clk_ac97);
135 clk_disable(&s3c2440_clk_cam); 179 clk_disable(&s3c2440_clk_cam);
diff --git a/arch/arm/mach-s3c2440/mach-anubis.c b/arch/arm/mach-s3c2440/mach-anubis.c
index 74f92fc3fd04..d8f36c0a16ad 100644
--- a/arch/arm/mach-s3c2440/mach-anubis.c
+++ b/arch/arm/mach-s3c2440/mach-anubis.c
@@ -96,22 +96,6 @@ static struct map_desc anubis_iodesc[] __initdata = {
96#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB 96#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
97#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE 97#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
98 98
99static struct s3c24xx_uart_clksrc anubis_serial_clocks[] = {
100 [0] = {
101 .name = "uclk",
102 .divisor = 1,
103 .min_baud = 0,
104 .max_baud = 0,
105 },
106 [1] = {
107 .name = "pclk",
108 .divisor = 1,
109 .min_baud = 0,
110 .max_baud = 0,
111 }
112};
113
114
115static struct s3c2410_uartcfg anubis_uartcfgs[] __initdata = { 99static struct s3c2410_uartcfg anubis_uartcfgs[] __initdata = {
116 [0] = { 100 [0] = {
117 .hwport = 0, 101 .hwport = 0,
@@ -119,8 +103,7 @@ static struct s3c2410_uartcfg anubis_uartcfgs[] __initdata = {
119 .ucon = UCON, 103 .ucon = UCON,
120 .ulcon = ULCON, 104 .ulcon = ULCON,
121 .ufcon = UFCON, 105 .ufcon = UFCON,
122 .clocks = anubis_serial_clocks, 106 .clk_sel = S3C2410_UCON_CLKSEL1 | S3C2410_UCON_CLKSEL2,
123 .clocks_size = ARRAY_SIZE(anubis_serial_clocks),
124 }, 107 },
125 [1] = { 108 [1] = {
126 .hwport = 2, 109 .hwport = 2,
@@ -128,8 +111,7 @@ static struct s3c2410_uartcfg anubis_uartcfgs[] __initdata = {
128 .ucon = UCON, 111 .ucon = UCON,
129 .ulcon = ULCON, 112 .ulcon = ULCON,
130 .ufcon = UFCON, 113 .ufcon = UFCON,
131 .clocks = anubis_serial_clocks, 114 .clk_sel = S3C2410_UCON_CLKSEL1 | S3C2410_UCON_CLKSEL2,
132 .clocks_size = ARRAY_SIZE(anubis_serial_clocks),
133 }, 115 },
134}; 116};
135 117
diff --git a/arch/arm/mach-s3c2440/mach-at2440evb.c b/arch/arm/mach-s3c2440/mach-at2440evb.c
index 38887ee0c784..aa86ca8fa1e9 100644
--- a/arch/arm/mach-s3c2440/mach-at2440evb.c
+++ b/arch/arm/mach-s3c2440/mach-at2440evb.c
@@ -57,22 +57,6 @@ static struct map_desc at2440evb_iodesc[] __initdata = {
57#define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE) 57#define ULCON (S3C2410_LCON_CS8 | S3C2410_LCON_PNONE)
58#define UFCON (S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE) 58#define UFCON (S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE)
59 59
60static struct s3c24xx_uart_clksrc at2440evb_serial_clocks[] = {
61 [0] = {
62 .name = "uclk",
63 .divisor = 1,
64 .min_baud = 0,
65 .max_baud = 0,
66 },
67 [1] = {
68 .name = "pclk",
69 .divisor = 1,
70 .min_baud = 0,
71 .max_baud = 0,
72 }
73};
74
75
76static struct s3c2410_uartcfg at2440evb_uartcfgs[] __initdata = { 60static struct s3c2410_uartcfg at2440evb_uartcfgs[] __initdata = {
77 [0] = { 61 [0] = {
78 .hwport = 0, 62 .hwport = 0,
@@ -80,8 +64,7 @@ static struct s3c2410_uartcfg at2440evb_uartcfgs[] __initdata = {
80 .ucon = UCON, 64 .ucon = UCON,
81 .ulcon = ULCON, 65 .ulcon = ULCON,
82 .ufcon = UFCON, 66 .ufcon = UFCON,
83 .clocks = at2440evb_serial_clocks, 67 .clk_sel = S3C2410_UCON_CLKSEL1 | S3C2410_UCON_CLKSEL2,
84 .clocks_size = ARRAY_SIZE(at2440evb_serial_clocks),
85 }, 68 },
86 [1] = { 69 [1] = {
87 .hwport = 1, 70 .hwport = 1,
@@ -89,8 +72,7 @@ static struct s3c2410_uartcfg at2440evb_uartcfgs[] __initdata = {
89 .ucon = UCON, 72 .ucon = UCON,
90 .ulcon = ULCON, 73 .ulcon = ULCON,
91 .ufcon = UFCON, 74 .ufcon = UFCON,
92 .clocks = at2440evb_serial_clocks, 75 .clk_sel = S3C2410_UCON_CLKSEL1 | S3C2410_UCON_CLKSEL2,
93 .clocks_size = ARRAY_SIZE(at2440evb_serial_clocks),
94 }, 76 },
95}; 77};
96 78
diff --git a/arch/arm/mach-s3c2440/mach-osiris.c b/arch/arm/mach-s3c2440/mach-osiris.c
index dc142ebf8cba..d7e47b2b6ec9 100644
--- a/arch/arm/mach-s3c2440/mach-osiris.c
+++ b/arch/arm/mach-s3c2440/mach-osiris.c
@@ -100,21 +100,6 @@ static struct map_desc osiris_iodesc[] __initdata = {
100#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB 100#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
101#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE 101#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
102 102
103static struct s3c24xx_uart_clksrc osiris_serial_clocks[] = {
104 [0] = {
105 .name = "uclk",
106 .divisor = 1,
107 .min_baud = 0,
108 .max_baud = 0,
109 },
110 [1] = {
111 .name = "pclk",
112 .divisor = 1,
113 .min_baud = 0,
114 .max_baud = 0,
115 }
116};
117
118static struct s3c2410_uartcfg osiris_uartcfgs[] __initdata = { 103static struct s3c2410_uartcfg osiris_uartcfgs[] __initdata = {
119 [0] = { 104 [0] = {
120 .hwport = 0, 105 .hwport = 0,
@@ -122,8 +107,7 @@ static struct s3c2410_uartcfg osiris_uartcfgs[] __initdata = {
122 .ucon = UCON, 107 .ucon = UCON,
123 .ulcon = ULCON, 108 .ulcon = ULCON,
124 .ufcon = UFCON, 109 .ufcon = UFCON,
125 .clocks = osiris_serial_clocks, 110 .clk_sel = S3C2410_UCON_CLKSEL1 | S3C2410_UCON_CLKSEL2,
126 .clocks_size = ARRAY_SIZE(osiris_serial_clocks),
127 }, 111 },
128 [1] = { 112 [1] = {
129 .hwport = 1, 113 .hwport = 1,
@@ -131,8 +115,7 @@ static struct s3c2410_uartcfg osiris_uartcfgs[] __initdata = {
131 .ucon = UCON, 115 .ucon = UCON,
132 .ulcon = ULCON, 116 .ulcon = ULCON,
133 .ufcon = UFCON, 117 .ufcon = UFCON,
134 .clocks = osiris_serial_clocks, 118 .clk_sel = S3C2410_UCON_CLKSEL1 | S3C2410_UCON_CLKSEL2,
135 .clocks_size = ARRAY_SIZE(osiris_serial_clocks),
136 }, 119 },
137 [2] = { 120 [2] = {
138 .hwport = 2, 121 .hwport = 2,
@@ -140,8 +123,7 @@ static struct s3c2410_uartcfg osiris_uartcfgs[] __initdata = {
140 .ucon = UCON, 123 .ucon = UCON,
141 .ulcon = ULCON, 124 .ulcon = ULCON,
142 .ufcon = UFCON, 125 .ufcon = UFCON,
143 .clocks = osiris_serial_clocks, 126 .clk_sel = S3C2410_UCON_CLKSEL1 | S3C2410_UCON_CLKSEL2,
144 .clocks_size = ARRAY_SIZE(osiris_serial_clocks),
145 } 127 }
146}; 128};
147 129
diff --git a/arch/arm/mach-s3c2440/mach-rx1950.c b/arch/arm/mach-s3c2440/mach-rx1950.c
index 0d3453bf567c..4267cd56bfe7 100644
--- a/arch/arm/mach-s3c2440/mach-rx1950.c
+++ b/arch/arm/mach-s3c2440/mach-rx1950.c
@@ -68,15 +68,6 @@
68static struct map_desc rx1950_iodesc[] __initdata = { 68static struct map_desc rx1950_iodesc[] __initdata = {
69}; 69};
70 70
71static struct s3c24xx_uart_clksrc rx1950_serial_clocks[] = {
72 [0] = {
73 .name = "fclk",
74 .divisor = 0x0a,
75 .min_baud = 0,
76 .max_baud = 0,
77 },
78};
79
80static struct s3c2410_uartcfg rx1950_uartcfgs[] __initdata = { 71static struct s3c2410_uartcfg rx1950_uartcfgs[] __initdata = {
81 [0] = { 72 [0] = {
82 .hwport = 0, 73 .hwport = 0,
@@ -84,8 +75,7 @@ static struct s3c2410_uartcfg rx1950_uartcfgs[] __initdata = {
84 .ucon = 0x3c5, 75 .ucon = 0x3c5,
85 .ulcon = 0x03, 76 .ulcon = 0x03,
86 .ufcon = 0x51, 77 .ufcon = 0x51,
87 .clocks = rx1950_serial_clocks, 78 .clk_sel = S3C2410_UCON_CLKSEL3,
88 .clocks_size = ARRAY_SIZE(rx1950_serial_clocks),
89 }, 79 },
90 [1] = { 80 [1] = {
91 .hwport = 1, 81 .hwport = 1,
@@ -93,8 +83,7 @@ static struct s3c2410_uartcfg rx1950_uartcfgs[] __initdata = {
93 .ucon = 0x3c5, 83 .ucon = 0x3c5,
94 .ulcon = 0x03, 84 .ulcon = 0x03,
95 .ufcon = 0x51, 85 .ufcon = 0x51,
96 .clocks = rx1950_serial_clocks, 86 .clk_sel = S3C2410_UCON_CLKSEL3,
97 .clocks_size = ARRAY_SIZE(rx1950_serial_clocks),
98 }, 87 },
99 /* IR port */ 88 /* IR port */
100 [2] = { 89 [2] = {
@@ -103,8 +92,7 @@ static struct s3c2410_uartcfg rx1950_uartcfgs[] __initdata = {
103 .ucon = 0x3c5, 92 .ucon = 0x3c5,
104 .ulcon = 0x43, 93 .ulcon = 0x43,
105 .ufcon = 0xf1, 94 .ufcon = 0xf1,
106 .clocks = rx1950_serial_clocks, 95 .clk_sel = S3C2410_UCON_CLKSEL3,
107 .clocks_size = ARRAY_SIZE(rx1950_serial_clocks),
108 }, 96 },
109}; 97};
110 98
diff --git a/arch/arm/mach-s3c2440/mach-rx3715.c b/arch/arm/mach-s3c2440/mach-rx3715.c
index e19499c2f909..3d5e2e67971e 100644
--- a/arch/arm/mach-s3c2440/mach-rx3715.c
+++ b/arch/arm/mach-s3c2440/mach-rx3715.c
@@ -67,16 +67,6 @@ static struct map_desc rx3715_iodesc[] __initdata = {
67 }, 67 },
68}; 68};
69 69
70
71static struct s3c24xx_uart_clksrc rx3715_serial_clocks[] = {
72 [0] = {
73 .name = "fclk",
74 .divisor = 0,
75 .min_baud = 0,
76 .max_baud = 0,
77 }
78};
79
80static struct s3c2410_uartcfg rx3715_uartcfgs[] = { 70static struct s3c2410_uartcfg rx3715_uartcfgs[] = {
81 [0] = { 71 [0] = {
82 .hwport = 0, 72 .hwport = 0,
@@ -84,8 +74,7 @@ static struct s3c2410_uartcfg rx3715_uartcfgs[] = {
84 .ucon = 0x3c5, 74 .ucon = 0x3c5,
85 .ulcon = 0x03, 75 .ulcon = 0x03,
86 .ufcon = 0x51, 76 .ufcon = 0x51,
87 .clocks = rx3715_serial_clocks, 77 .clk_sel = S3C2410_UCON_CLKSEL3,
88 .clocks_size = ARRAY_SIZE(rx3715_serial_clocks),
89 }, 78 },
90 [1] = { 79 [1] = {
91 .hwport = 1, 80 .hwport = 1,
@@ -93,8 +82,7 @@ static struct s3c2410_uartcfg rx3715_uartcfgs[] = {
93 .ucon = 0x3c5, 82 .ucon = 0x3c5,
94 .ulcon = 0x03, 83 .ulcon = 0x03,
95 .ufcon = 0x00, 84 .ufcon = 0x00,
96 .clocks = rx3715_serial_clocks, 85 .clk_sel = S3C2410_UCON_CLKSEL3,
97 .clocks_size = ARRAY_SIZE(rx3715_serial_clocks),
98 }, 86 },
99 /* IR port */ 87 /* IR port */
100 [2] = { 88 [2] = {
@@ -103,8 +91,7 @@ static struct s3c2410_uartcfg rx3715_uartcfgs[] = {
103 .ucon = 0x3c5, 91 .ucon = 0x3c5,
104 .ulcon = 0x43, 92 .ulcon = 0x43,
105 .ufcon = 0x51, 93 .ufcon = 0x51,
106 .clocks = rx3715_serial_clocks, 94 .clk_sel = S3C2410_UCON_CLKSEL3,
107 .clocks_size = ARRAY_SIZE(rx3715_serial_clocks),
108 } 95 }
109}; 96};
110 97
diff --git a/arch/arm/mach-s3c64xx/clock.c b/arch/arm/mach-s3c64xx/clock.c
index 39c238d7a3dc..2addd988141c 100644
--- a/arch/arm/mach-s3c64xx/clock.c
+++ b/arch/arm/mach-s3c64xx/clock.c
@@ -617,16 +617,6 @@ static struct clksrc_clk clksrcs[] = {
617 .sources = &clkset_uhost, 617 .sources = &clkset_uhost,
618 }, { 618 }, {
619 .clk = { 619 .clk = {
620 .name = "uclk1",
621 .ctrlbit = S3C_CLKCON_SCLK_UART,
622 .enable = s3c64xx_sclk_ctrl,
623 },
624 .reg_src = { .reg = S3C_CLK_SRC, .shift = 13, .size = 1 },
625 .reg_div = { .reg = S3C_CLK_DIV2, .shift = 16, .size = 4 },
626 .sources = &clkset_uart,
627 }, {
628/* Where does UCLK0 come from? */
629 .clk = {
630 .name = "spi-bus", 620 .name = "spi-bus",
631 .devname = "s3c64xx-spi.0", 621 .devname = "s3c64xx-spi.0",
632 .ctrlbit = S3C_CLKCON_SCLK_SPI0, 622 .ctrlbit = S3C_CLKCON_SCLK_SPI0,
@@ -695,6 +685,18 @@ static struct clksrc_clk clksrcs[] = {
695 }, 685 },
696}; 686};
697 687
688/* Where does UCLK0 come from? */
689static struct clksrc_clk clk_sclk_uclk = {
690 .clk = {
691 .name = "uclk1",
692 .ctrlbit = S3C_CLKCON_SCLK_UART,
693 .enable = s3c64xx_sclk_ctrl,
694 },
695 .reg_src = { .reg = S3C_CLK_SRC, .shift = 13, .size = 1 },
696 .reg_div = { .reg = S3C_CLK_DIV2, .shift = 16, .size = 4 },
697 .sources = &clkset_uart,
698};
699
698/* Clock initialisation code */ 700/* Clock initialisation code */
699 701
700static struct clksrc_clk *init_parents[] = { 702static struct clksrc_clk *init_parents[] = {
@@ -703,6 +705,15 @@ static struct clksrc_clk *init_parents[] = {
703 &clk_mout_mpll, 705 &clk_mout_mpll,
704}; 706};
705 707
708static struct clksrc_clk *clksrc_cdev[] = {
709 &clk_sclk_uclk,
710};
711
712static struct clk_lookup s3c64xx_clk_lookup[] = {
713 CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_p),
714 CLKDEV_INIT(NULL, "clk_uart_baud3", &clk_sclk_uclk.clk),
715};
716
706#define GET_DIV(clk, field) ((((clk) & field##_MASK) >> field##_SHIFT) + 1) 717#define GET_DIV(clk, field) ((((clk) & field##_MASK) >> field##_SHIFT) + 1)
707 718
708void __init_or_cpufreq s3c6400_setup_clocks(void) 719void __init_or_cpufreq s3c6400_setup_clocks(void)
@@ -811,6 +822,8 @@ static struct clk *clks[] __initdata = {
811void __init s3c64xx_register_clocks(unsigned long xtal, 822void __init s3c64xx_register_clocks(unsigned long xtal,
812 unsigned armclk_divlimit) 823 unsigned armclk_divlimit)
813{ 824{
825 unsigned int cnt;
826
814 armclk_mask = armclk_divlimit; 827 armclk_mask = armclk_divlimit;
815 828
816 s3c24xx_register_baseclocks(xtal); 829 s3c24xx_register_baseclocks(xtal);
@@ -823,5 +836,9 @@ void __init s3c64xx_register_clocks(unsigned long xtal,
823 836
824 s3c24xx_register_clocks(clks1, ARRAY_SIZE(clks1)); 837 s3c24xx_register_clocks(clks1, ARRAY_SIZE(clks1));
825 s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs)); 838 s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
839 for (cnt = 0; cnt < ARRAY_SIZE(clksrc_cdev); cnt++)
840 s3c_register_clksrc(clksrc_cdev[cnt], 1);
841 clkdev_add_table(s3c64xx_clk_lookup, ARRAY_SIZE(s3c64xx_clk_lookup));
842
826 s3c_pwmclk_init(); 843 s3c_pwmclk_init();
827} 844}
diff --git a/arch/arm/mach-s5p64x0/clock-s5p6440.c b/arch/arm/mach-s5p64x0/clock-s5p6440.c
index c54c65d511f0..bfb1917ad0da 100644
--- a/arch/arm/mach-s5p64x0/clock-s5p6440.c
+++ b/arch/arm/mach-s5p64x0/clock-s5p6440.c
@@ -421,15 +421,6 @@ static struct clksrc_clk clksrcs[] = {
421 .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 8, .size = 4 }, 421 .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 8, .size = 4 },
422 }, { 422 }, {
423 .clk = { 423 .clk = {
424 .name = "uclk1",
425 .ctrlbit = (1 << 5),
426 .enable = s5p64x0_sclk_ctrl,
427 },
428 .sources = &clkset_uart,
429 .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 13, .size = 1 },
430 .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 16, .size = 4 },
431 }, {
432 .clk = {
433 .name = "sclk_spi", 424 .name = "sclk_spi",
434 .devname = "s3c64xx-spi.0", 425 .devname = "s3c64xx-spi.0",
435 .ctrlbit = (1 << 20), 426 .ctrlbit = (1 << 20),
@@ -487,6 +478,17 @@ static struct clksrc_clk clksrcs[] = {
487 }, 478 },
488}; 479};
489 480
481static struct clksrc_clk clk_sclk_uclk = {
482 .clk = {
483 .name = "uclk1",
484 .ctrlbit = (1 << 5),
485 .enable = s5p64x0_sclk_ctrl,
486 },
487 .sources = &clkset_uart,
488 .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 13, .size = 1 },
489 .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 16, .size = 4 },
490};
491
490/* Clock initialization code */ 492/* Clock initialization code */
491static struct clksrc_clk *sysclks[] = { 493static struct clksrc_clk *sysclks[] = {
492 &clk_mout_apll, 494 &clk_mout_apll,
@@ -505,6 +507,15 @@ static struct clk dummy_apb_pclk = {
505 .id = -1, 507 .id = -1,
506}; 508};
507 509
510static struct clksrc_clk *clksrc_cdev[] = {
511 &clk_sclk_uclk,
512};
513
514static struct clk_lookup s5p6440_clk_lookup[] = {
515 CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_pclk_low.clk),
516 CLKDEV_INIT(NULL, "clk_uart_baud3", &clk_sclk_uclk.clk),
517};
518
508void __init_or_cpufreq s5p6440_setup_clocks(void) 519void __init_or_cpufreq s5p6440_setup_clocks(void)
509{ 520{
510 struct clk *xtal_clk; 521 struct clk *xtal_clk;
@@ -583,9 +594,12 @@ void __init s5p6440_register_clocks(void)
583 594
584 s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs)); 595 s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
585 s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks)); 596 s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
597 for (ptr = 0; ptr < ARRAY_SIZE(clksrc_cdev); ptr++)
598 s3c_register_clksrc(clksrc_cdev[ptr], 1);
586 599
587 s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); 600 s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
588 s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); 601 s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
602 clkdev_add_table(s5p6440_clk_lookup, ARRAY_SIZE(s5p6440_clk_lookup));
589 603
590 s3c24xx_register_clock(&dummy_apb_pclk); 604 s3c24xx_register_clock(&dummy_apb_pclk);
591 605
diff --git a/arch/arm/mach-s5p64x0/clock-s5p6450.c b/arch/arm/mach-s5p64x0/clock-s5p6450.c
index 2d04abfba12e..d132638c7b23 100644
--- a/arch/arm/mach-s5p64x0/clock-s5p6450.c
+++ b/arch/arm/mach-s5p64x0/clock-s5p6450.c
@@ -443,15 +443,6 @@ static struct clksrc_clk clksrcs[] = {
443 .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 8, .size = 4 }, 443 .reg_div = { .reg = S5P64X0_CLK_DIV1, .shift = 8, .size = 4 },
444 }, { 444 }, {
445 .clk = { 445 .clk = {
446 .name = "uclk1",
447 .ctrlbit = (1 << 5),
448 .enable = s5p64x0_sclk_ctrl,
449 },
450 .sources = &clkset_uart,
451 .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 13, .size = 1 },
452 .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 16, .size = 4 },
453 }, {
454 .clk = {
455 .name = "sclk_spi", 446 .name = "sclk_spi",
456 .devname = "s3c64xx-spi.0", 447 .devname = "s3c64xx-spi.0",
457 .ctrlbit = (1 << 20), 448 .ctrlbit = (1 << 20),
@@ -536,6 +527,26 @@ static struct clksrc_clk clksrcs[] = {
536 }, 527 },
537}; 528};
538 529
530static struct clksrc_clk clk_sclk_uclk = {
531 .clk = {
532 .name = "uclk1",
533 .ctrlbit = (1 << 5),
534 .enable = s5p64x0_sclk_ctrl,
535 },
536 .sources = &clkset_uart,
537 .reg_src = { .reg = S5P64X0_CLK_SRC0, .shift = 13, .size = 1 },
538 .reg_div = { .reg = S5P64X0_CLK_DIV2, .shift = 16, .size = 4 },
539};
540
541static struct clksrc_clk *clksrc_cdev[] = {
542 &clk_sclk_uclk,
543};
544
545static struct clk_lookup s5p6450_clk_lookup[] = {
546 CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_pclk_low.clk),
547 CLKDEV_INIT(NULL, "clk_uart_baud3", &clk_sclk_uclk.clk),
548};
549
539/* Clock initialization code */ 550/* Clock initialization code */
540static struct clksrc_clk *sysclks[] = { 551static struct clksrc_clk *sysclks[] = {
541 &clk_mout_apll, 552 &clk_mout_apll,
@@ -634,9 +645,12 @@ void __init s5p6450_register_clocks(void)
634 645
635 s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs)); 646 s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
636 s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks)); 647 s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
648 for (ptr = 0; ptr < ARRAY_SIZE(clksrc_cdev); ptr++)
649 s3c_register_clksrc(clksrc_cdev[ptr], 1);
637 650
638 s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); 651 s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
639 s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); 652 s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
653 clkdev_add_table(s5p6450_clk_lookup, ARRAY_SIZE(s5p6450_clk_lookup));
640 654
641 s3c24xx_register_clock(&dummy_apb_pclk); 655 s3c24xx_register_clock(&dummy_apb_pclk);
642 656
diff --git a/arch/arm/mach-s5p64x0/dma.c b/arch/arm/mach-s5p64x0/dma.c
index 442dd4ad12da..f820c0744405 100644
--- a/arch/arm/mach-s5p64x0/dma.c
+++ b/arch/arm/mach-s5p64x0/dma.c
@@ -38,176 +38,74 @@
38 38
39static u64 dma_dmamask = DMA_BIT_MASK(32); 39static u64 dma_dmamask = DMA_BIT_MASK(32);
40 40
41struct dma_pl330_peri s5p6440_pdma_peri[22] = { 41u8 s5p6440_pdma_peri[] = {
42 { 42 DMACH_UART0_RX,
43 .peri_id = (u8)DMACH_UART0_RX, 43 DMACH_UART0_TX,
44 .rqtype = DEVTOMEM, 44 DMACH_UART1_RX,
45 }, { 45 DMACH_UART1_TX,
46 .peri_id = (u8)DMACH_UART0_TX, 46 DMACH_UART2_RX,
47 .rqtype = MEMTODEV, 47 DMACH_UART2_TX,
48 }, { 48 DMACH_UART3_RX,
49 .peri_id = (u8)DMACH_UART1_RX, 49 DMACH_UART3_TX,
50 .rqtype = DEVTOMEM, 50 DMACH_MAX,
51 }, { 51 DMACH_MAX,
52 .peri_id = (u8)DMACH_UART1_TX, 52 DMACH_PCM0_TX,
53 .rqtype = MEMTODEV, 53 DMACH_PCM0_RX,
54 }, { 54 DMACH_I2S0_TX,
55 .peri_id = (u8)DMACH_UART2_RX, 55 DMACH_I2S0_RX,
56 .rqtype = DEVTOMEM, 56 DMACH_SPI0_TX,
57 }, { 57 DMACH_SPI0_RX,
58 .peri_id = (u8)DMACH_UART2_TX, 58 DMACH_MAX,
59 .rqtype = MEMTODEV, 59 DMACH_MAX,
60 }, { 60 DMACH_MAX,
61 .peri_id = (u8)DMACH_UART3_RX, 61 DMACH_MAX,
62 .rqtype = DEVTOMEM, 62 DMACH_SPI1_TX,
63 }, { 63 DMACH_SPI1_RX,
64 .peri_id = (u8)DMACH_UART3_TX,
65 .rqtype = MEMTODEV,
66 }, {
67 .peri_id = DMACH_MAX,
68 }, {
69 .peri_id = DMACH_MAX,
70 }, {
71 .peri_id = (u8)DMACH_PCM0_TX,
72 .rqtype = MEMTODEV,
73 }, {
74 .peri_id = (u8)DMACH_PCM0_RX,
75 .rqtype = DEVTOMEM,
76 }, {
77 .peri_id = (u8)DMACH_I2S0_TX,
78 .rqtype = MEMTODEV,
79 }, {
80 .peri_id = (u8)DMACH_I2S0_RX,
81 .rqtype = DEVTOMEM,
82 }, {
83 .peri_id = (u8)DMACH_SPI0_TX,
84 .rqtype = MEMTODEV,
85 }, {
86 .peri_id = (u8)DMACH_SPI0_RX,
87 .rqtype = DEVTOMEM,
88 }, {
89 .peri_id = (u8)DMACH_MAX,
90 }, {
91 .peri_id = (u8)DMACH_MAX,
92 }, {
93 .peri_id = (u8)DMACH_MAX,
94 }, {
95 .peri_id = (u8)DMACH_MAX,
96 }, {
97 .peri_id = (u8)DMACH_SPI1_TX,
98 .rqtype = MEMTODEV,
99 }, {
100 .peri_id = (u8)DMACH_SPI1_RX,
101 .rqtype = DEVTOMEM,
102 },
103}; 64};
104 65
105struct dma_pl330_platdata s5p6440_pdma_pdata = { 66struct dma_pl330_platdata s5p6440_pdma_pdata = {
106 .nr_valid_peri = ARRAY_SIZE(s5p6440_pdma_peri), 67 .nr_valid_peri = ARRAY_SIZE(s5p6440_pdma_peri),
107 .peri = s5p6440_pdma_peri, 68 .peri_id = s5p6440_pdma_peri,
108}; 69};
109 70
110struct dma_pl330_peri s5p6450_pdma_peri[32] = { 71u8 s5p6450_pdma_peri[] = {
111 { 72 DMACH_UART0_RX,
112 .peri_id = (u8)DMACH_UART0_RX, 73 DMACH_UART0_TX,
113 .rqtype = DEVTOMEM, 74 DMACH_UART1_RX,
114 }, { 75 DMACH_UART1_TX,
115 .peri_id = (u8)DMACH_UART0_TX, 76 DMACH_UART2_RX,
116 .rqtype = MEMTODEV, 77 DMACH_UART2_TX,
117 }, { 78 DMACH_UART3_RX,
118 .peri_id = (u8)DMACH_UART1_RX, 79 DMACH_UART3_TX,
119 .rqtype = DEVTOMEM, 80 DMACH_UART4_RX,
120 }, { 81 DMACH_UART4_TX,
121 .peri_id = (u8)DMACH_UART1_TX, 82 DMACH_PCM0_TX,
122 .rqtype = MEMTODEV, 83 DMACH_PCM0_RX,
123 }, { 84 DMACH_I2S0_TX,
124 .peri_id = (u8)DMACH_UART2_RX, 85 DMACH_I2S0_RX,
125 .rqtype = DEVTOMEM, 86 DMACH_SPI0_TX,
126 }, { 87 DMACH_SPI0_RX,
127 .peri_id = (u8)DMACH_UART2_TX, 88 DMACH_PCM1_TX,
128 .rqtype = MEMTODEV, 89 DMACH_PCM1_RX,
129 }, { 90 DMACH_PCM2_TX,
130 .peri_id = (u8)DMACH_UART3_RX, 91 DMACH_PCM2_RX,
131 .rqtype = DEVTOMEM, 92 DMACH_SPI1_TX,
132 }, { 93 DMACH_SPI1_RX,
133 .peri_id = (u8)DMACH_UART3_TX, 94 DMACH_USI_TX,
134 .rqtype = MEMTODEV, 95 DMACH_USI_RX,
135 }, { 96 DMACH_MAX,
136 .peri_id = (u8)DMACH_UART4_RX, 97 DMACH_I2S1_TX,
137 .rqtype = DEVTOMEM, 98 DMACH_I2S1_RX,
138 }, { 99 DMACH_I2S2_TX,
139 .peri_id = (u8)DMACH_UART4_TX, 100 DMACH_I2S2_RX,
140 .rqtype = MEMTODEV, 101 DMACH_PWM,
141 }, { 102 DMACH_UART5_RX,
142 .peri_id = (u8)DMACH_PCM0_TX, 103 DMACH_UART5_TX,
143 .rqtype = MEMTODEV,
144 }, {
145 .peri_id = (u8)DMACH_PCM0_RX,
146 .rqtype = DEVTOMEM,
147 }, {
148 .peri_id = (u8)DMACH_I2S0_TX,
149 .rqtype = MEMTODEV,
150 }, {
151 .peri_id = (u8)DMACH_I2S0_RX,
152 .rqtype = DEVTOMEM,
153 }, {
154 .peri_id = (u8)DMACH_SPI0_TX,
155 .rqtype = MEMTODEV,
156 }, {
157 .peri_id = (u8)DMACH_SPI0_RX,
158 .rqtype = DEVTOMEM,
159 }, {
160 .peri_id = (u8)DMACH_PCM1_TX,
161 .rqtype = MEMTODEV,
162 }, {
163 .peri_id = (u8)DMACH_PCM1_RX,
164 .rqtype = DEVTOMEM,
165 }, {
166 .peri_id = (u8)DMACH_PCM2_TX,
167 .rqtype = MEMTODEV,
168 }, {
169 .peri_id = (u8)DMACH_PCM2_RX,
170 .rqtype = DEVTOMEM,
171 }, {
172 .peri_id = (u8)DMACH_SPI1_TX,
173 .rqtype = MEMTODEV,
174 }, {
175 .peri_id = (u8)DMACH_SPI1_RX,
176 .rqtype = DEVTOMEM,
177 }, {
178 .peri_id = (u8)DMACH_USI_TX,
179 .rqtype = MEMTODEV,
180 }, {
181 .peri_id = (u8)DMACH_USI_RX,
182 .rqtype = DEVTOMEM,
183 }, {
184 .peri_id = (u8)DMACH_MAX,
185 }, {
186 .peri_id = (u8)DMACH_I2S1_TX,
187 .rqtype = MEMTODEV,
188 }, {
189 .peri_id = (u8)DMACH_I2S1_RX,
190 .rqtype = DEVTOMEM,
191 }, {
192 .peri_id = (u8)DMACH_I2S2_TX,
193 .rqtype = MEMTODEV,
194 }, {
195 .peri_id = (u8)DMACH_I2S2_RX,
196 .rqtype = DEVTOMEM,
197 }, {
198 .peri_id = (u8)DMACH_PWM,
199 }, {
200 .peri_id = (u8)DMACH_UART5_RX,
201 .rqtype = DEVTOMEM,
202 }, {
203 .peri_id = (u8)DMACH_UART5_TX,
204 .rqtype = MEMTODEV,
205 },
206}; 104};
207 105
208struct dma_pl330_platdata s5p6450_pdma_pdata = { 106struct dma_pl330_platdata s5p6450_pdma_pdata = {
209 .nr_valid_peri = ARRAY_SIZE(s5p6450_pdma_peri), 107 .nr_valid_peri = ARRAY_SIZE(s5p6450_pdma_peri),
210 .peri = s5p6450_pdma_peri, 108 .peri_id = s5p6450_pdma_peri,
211}; 109};
212 110
213struct amba_device s5p64x0_device_pdma = { 111struct amba_device s5p64x0_device_pdma = {
@@ -227,10 +125,15 @@ struct amba_device s5p64x0_device_pdma = {
227 125
228static int __init s5p64x0_dma_init(void) 126static int __init s5p64x0_dma_init(void)
229{ 127{
230 if (soc_is_s5p6450()) 128 if (soc_is_s5p6450()) {
129 dma_cap_set(DMA_SLAVE, s5p6450_pdma_pdata.cap_mask);
130 dma_cap_set(DMA_CYCLIC, s5p6450_pdma_pdata.cap_mask);
231 s5p64x0_device_pdma.dev.platform_data = &s5p6450_pdma_pdata; 131 s5p64x0_device_pdma.dev.platform_data = &s5p6450_pdma_pdata;
232 else 132 } else {
133 dma_cap_set(DMA_SLAVE, s5p6440_pdma_pdata.cap_mask);
134 dma_cap_set(DMA_CYCLIC, s5p6440_pdma_pdata.cap_mask);
233 s5p64x0_device_pdma.dev.platform_data = &s5p6440_pdma_pdata; 135 s5p64x0_device_pdma.dev.platform_data = &s5p6440_pdma_pdata;
136 }
234 137
235 amba_device_register(&s5p64x0_device_pdma, &iomem_resource); 138 amba_device_register(&s5p64x0_device_pdma, &iomem_resource);
236 139
diff --git a/arch/arm/mach-s5p64x0/include/mach/irqs.h b/arch/arm/mach-s5p64x0/include/mach/irqs.h
index 53982db9d259..5b845e849b30 100644
--- a/arch/arm/mach-s5p64x0/include/mach/irqs.h
+++ b/arch/arm/mach-s5p64x0/include/mach/irqs.h
@@ -141,6 +141,8 @@
141 141
142#define IRQ_EINT_GROUP(grp, x) (IRQ_EINT_GROUP##grp##_BASE + (x)) 142#define IRQ_EINT_GROUP(grp, x) (IRQ_EINT_GROUP##grp##_BASE + (x))
143 143
144#define IRQ_TIMER_BASE (11)
145
144/* Set the default NR_IRQS */ 146/* Set the default NR_IRQS */
145 147
146#define NR_IRQS (IRQ_EINT_GROUP8_BASE + IRQ_EINT_GROUP8_NR + 1) 148#define NR_IRQS (IRQ_EINT_GROUP8_BASE + IRQ_EINT_GROUP8_NR + 1)
diff --git a/arch/arm/mach-s5p64x0/init.c b/arch/arm/mach-s5p64x0/init.c
index 79833caf8165..659a66c131a1 100644
--- a/arch/arm/mach-s5p64x0/init.c
+++ b/arch/arm/mach-s5p64x0/init.c
@@ -23,36 +23,7 @@
23#include <plat/s5p6450.h> 23#include <plat/s5p6450.h>
24#include <plat/regs-serial.h> 24#include <plat/regs-serial.h>
25 25
26static struct s3c24xx_uart_clksrc s5p64x0_serial_clocks[] = {
27 [0] = {
28 .name = "pclk_low",
29 .divisor = 1,
30 .min_baud = 0,
31 .max_baud = 0,
32 },
33 [1] = {
34 .name = "uclk1",
35 .divisor = 1,
36 .min_baud = 0,
37 .max_baud = 0,
38 },
39};
40
41/* uart registration process */ 26/* uart registration process */
42
43void __init s5p64x0_common_init_uarts(struct s3c2410_uartcfg *cfg, int no)
44{
45 struct s3c2410_uartcfg *tcfg = cfg;
46 u32 ucnt;
47
48 for (ucnt = 0; ucnt < no; ucnt++, tcfg++) {
49 if (!tcfg->clocks) {
50 tcfg->clocks = s5p64x0_serial_clocks;
51 tcfg->clocks_size = ARRAY_SIZE(s5p64x0_serial_clocks);
52 }
53 }
54}
55
56void __init s5p6440_init_uarts(struct s3c2410_uartcfg *cfg, int no) 27void __init s5p6440_init_uarts(struct s3c2410_uartcfg *cfg, int no)
57{ 28{
58 int uart; 29 int uart;
@@ -62,12 +33,10 @@ void __init s5p6440_init_uarts(struct s3c2410_uartcfg *cfg, int no)
62 s5p_uart_resources[uart].resources->end = S5P6440_PA_UART(uart) + S5P_SZ_UART; 33 s5p_uart_resources[uart].resources->end = S5P6440_PA_UART(uart) + S5P_SZ_UART;
63 } 34 }
64 35
65 s5p64x0_common_init_uarts(cfg, no);
66 s3c24xx_init_uartdevs("s3c6400-uart", s5p_uart_resources, cfg, no); 36 s3c24xx_init_uartdevs("s3c6400-uart", s5p_uart_resources, cfg, no);
67} 37}
68 38
69void __init s5p6450_init_uarts(struct s3c2410_uartcfg *cfg, int no) 39void __init s5p6450_init_uarts(struct s3c2410_uartcfg *cfg, int no)
70{ 40{
71 s5p64x0_common_init_uarts(cfg, no);
72 s3c24xx_init_uartdevs("s3c6400-uart", s5p_uart_resources, cfg, no); 41 s3c24xx_init_uartdevs("s3c6400-uart", s5p_uart_resources, cfg, no);
73} 42}
diff --git a/arch/arm/mach-s5pc100/clock.c b/arch/arm/mach-s5pc100/clock.c
index 8d47709da713..9d644ece2604 100644
--- a/arch/arm/mach-s5pc100/clock.c
+++ b/arch/arm/mach-s5pc100/clock.c
@@ -962,16 +962,6 @@ static struct clksrc_clk clksrcs[] = {
962 .reg_div = { .reg = S5P_CLK_DIV2, .shift = 12, .size = 4 }, 962 .reg_div = { .reg = S5P_CLK_DIV2, .shift = 12, .size = 4 },
963 }, { 963 }, {
964 .clk = { 964 .clk = {
965 .name = "uclk1",
966 .ctrlbit = (1 << 3),
967 .enable = s5pc100_sclk0_ctrl,
968
969 },
970 .sources = &clk_src_group2,
971 .reg_src = { .reg = S5P_CLK_SRC1, .shift = 0, .size = 1 },
972 .reg_div = { .reg = S5P_CLK_DIV2, .shift = 0, .size = 4 },
973 }, {
974 .clk = {
975 .name = "sclk_mixer", 965 .name = "sclk_mixer",
976 .ctrlbit = (1 << 6), 966 .ctrlbit = (1 << 6),
977 .enable = s5pc100_sclk0_ctrl, 967 .enable = s5pc100_sclk0_ctrl,
@@ -1098,6 +1088,17 @@ static struct clksrc_clk clksrcs[] = {
1098 }, 1088 },
1099}; 1089};
1100 1090
1091static struct clksrc_clk clk_sclk_uart = {
1092 .clk = {
1093 .name = "uclk1",
1094 .ctrlbit = (1 << 3),
1095 .enable = s5pc100_sclk0_ctrl,
1096 },
1097 .sources = &clk_src_group2,
1098 .reg_src = { .reg = S5P_CLK_SRC1, .shift = 0, .size = 1 },
1099 .reg_div = { .reg = S5P_CLK_DIV2, .shift = 0, .size = 4 },
1100};
1101
1101/* Clock initialisation code */ 1102/* Clock initialisation code */
1102static struct clksrc_clk *sysclks[] = { 1103static struct clksrc_clk *sysclks[] = {
1103 &clk_mout_apll, 1104 &clk_mout_apll,
@@ -1127,6 +1128,10 @@ static struct clksrc_clk *sysclks[] = {
1127 &clk_sclk_spdif, 1128 &clk_sclk_spdif,
1128}; 1129};
1129 1130
1131static struct clksrc_clk *clksrc_cdev[] = {
1132 &clk_sclk_uart,
1133};
1134
1130void __init_or_cpufreq s5pc100_setup_clocks(void) 1135void __init_or_cpufreq s5pc100_setup_clocks(void)
1131{ 1136{
1132 unsigned long xtal; 1137 unsigned long xtal;
@@ -1266,6 +1271,11 @@ static struct clk *clks[] __initdata = {
1266 &clk_pcmcdclk1, 1271 &clk_pcmcdclk1,
1267}; 1272};
1268 1273
1274static struct clk_lookup s5pc100_clk_lookup[] = {
1275 CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_p),
1276 CLKDEV_INIT(NULL, "clk_uart_baud3", &clk_sclk_uart.clk),
1277};
1278
1269void __init s5pc100_register_clocks(void) 1279void __init s5pc100_register_clocks(void)
1270{ 1280{
1271 int ptr; 1281 int ptr;
@@ -1277,9 +1287,12 @@ void __init s5pc100_register_clocks(void)
1277 1287
1278 s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs)); 1288 s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
1279 s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks)); 1289 s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
1290 for (ptr = 0; ptr < ARRAY_SIZE(clksrc_cdev); ptr++)
1291 s3c_register_clksrc(clksrc_cdev[ptr], 1);
1280 1292
1281 s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); 1293 s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
1282 s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); 1294 s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
1295 clkdev_add_table(s5pc100_clk_lookup, ARRAY_SIZE(s5pc100_clk_lookup));
1283 1296
1284 s3c24xx_register_clock(&dummy_apb_pclk); 1297 s3c24xx_register_clock(&dummy_apb_pclk);
1285 1298
diff --git a/arch/arm/mach-s5pc100/dma.c b/arch/arm/mach-s5pc100/dma.c
index 065a087f5a8b..c841f4d313f2 100644
--- a/arch/arm/mach-s5pc100/dma.c
+++ b/arch/arm/mach-s5pc100/dma.c
@@ -35,100 +35,42 @@
35 35
36static u64 dma_dmamask = DMA_BIT_MASK(32); 36static u64 dma_dmamask = DMA_BIT_MASK(32);
37 37
38struct dma_pl330_peri pdma0_peri[30] = { 38u8 pdma0_peri[] = {
39 { 39 DMACH_UART0_RX,
40 .peri_id = (u8)DMACH_UART0_RX, 40 DMACH_UART0_TX,
41 .rqtype = DEVTOMEM, 41 DMACH_UART1_RX,
42 }, { 42 DMACH_UART1_TX,
43 .peri_id = (u8)DMACH_UART0_TX, 43 DMACH_UART2_RX,
44 .rqtype = MEMTODEV, 44 DMACH_UART2_TX,
45 }, { 45 DMACH_UART3_RX,
46 .peri_id = (u8)DMACH_UART1_RX, 46 DMACH_UART3_TX,
47 .rqtype = DEVTOMEM, 47 DMACH_IRDA,
48 }, { 48 DMACH_I2S0_RX,
49 .peri_id = (u8)DMACH_UART1_TX, 49 DMACH_I2S0_TX,
50 .rqtype = MEMTODEV, 50 DMACH_I2S0S_TX,
51 }, { 51 DMACH_I2S1_RX,
52 .peri_id = (u8)DMACH_UART2_RX, 52 DMACH_I2S1_TX,
53 .rqtype = DEVTOMEM, 53 DMACH_I2S2_RX,
54 }, { 54 DMACH_I2S2_TX,
55 .peri_id = (u8)DMACH_UART2_TX, 55 DMACH_SPI0_RX,
56 .rqtype = MEMTODEV, 56 DMACH_SPI0_TX,
57 }, { 57 DMACH_SPI1_RX,
58 .peri_id = (u8)DMACH_UART3_RX, 58 DMACH_SPI1_TX,
59 .rqtype = DEVTOMEM, 59 DMACH_SPI2_RX,
60 }, { 60 DMACH_SPI2_TX,
61 .peri_id = (u8)DMACH_UART3_TX, 61 DMACH_AC97_MICIN,
62 .rqtype = MEMTODEV, 62 DMACH_AC97_PCMIN,
63 }, { 63 DMACH_AC97_PCMOUT,
64 .peri_id = DMACH_IRDA, 64 DMACH_EXTERNAL,
65 }, { 65 DMACH_PWM,
66 .peri_id = (u8)DMACH_I2S0_RX, 66 DMACH_SPDIF,
67 .rqtype = DEVTOMEM, 67 DMACH_HSI_RX,
68 }, { 68 DMACH_HSI_TX,
69 .peri_id = (u8)DMACH_I2S0_TX,
70 .rqtype = MEMTODEV,
71 }, {
72 .peri_id = (u8)DMACH_I2S0S_TX,
73 .rqtype = MEMTODEV,
74 }, {
75 .peri_id = (u8)DMACH_I2S1_RX,
76 .rqtype = DEVTOMEM,
77 }, {
78 .peri_id = (u8)DMACH_I2S1_TX,
79 .rqtype = MEMTODEV,
80 }, {
81 .peri_id = (u8)DMACH_I2S2_RX,
82 .rqtype = DEVTOMEM,
83 }, {
84 .peri_id = (u8)DMACH_I2S2_TX,
85 .rqtype = MEMTODEV,
86 }, {
87 .peri_id = (u8)DMACH_SPI0_RX,
88 .rqtype = DEVTOMEM,
89 }, {
90 .peri_id = (u8)DMACH_SPI0_TX,
91 .rqtype = MEMTODEV,
92 }, {
93 .peri_id = (u8)DMACH_SPI1_RX,
94 .rqtype = DEVTOMEM,
95 }, {
96 .peri_id = (u8)DMACH_SPI1_TX,
97 .rqtype = MEMTODEV,
98 }, {
99 .peri_id = (u8)DMACH_SPI2_RX,
100 .rqtype = DEVTOMEM,
101 }, {
102 .peri_id = (u8)DMACH_SPI2_TX,
103 .rqtype = MEMTODEV,
104 }, {
105 .peri_id = (u8)DMACH_AC97_MICIN,
106 .rqtype = DEVTOMEM,
107 }, {
108 .peri_id = (u8)DMACH_AC97_PCMIN,
109 .rqtype = DEVTOMEM,
110 }, {
111 .peri_id = (u8)DMACH_AC97_PCMOUT,
112 .rqtype = MEMTODEV,
113 }, {
114 .peri_id = (u8)DMACH_EXTERNAL,
115 }, {
116 .peri_id = (u8)DMACH_PWM,
117 }, {
118 .peri_id = (u8)DMACH_SPDIF,
119 .rqtype = MEMTODEV,
120 }, {
121 .peri_id = (u8)DMACH_HSI_RX,
122 .rqtype = DEVTOMEM,
123 }, {
124 .peri_id = (u8)DMACH_HSI_TX,
125 .rqtype = MEMTODEV,
126 },
127}; 69};
128 70
129struct dma_pl330_platdata s5pc100_pdma0_pdata = { 71struct dma_pl330_platdata s5pc100_pdma0_pdata = {
130 .nr_valid_peri = ARRAY_SIZE(pdma0_peri), 72 .nr_valid_peri = ARRAY_SIZE(pdma0_peri),
131 .peri = pdma0_peri, 73 .peri_id = pdma0_peri,
132}; 74};
133 75
134struct amba_device s5pc100_device_pdma0 = { 76struct amba_device s5pc100_device_pdma0 = {
@@ -147,98 +89,42 @@ struct amba_device s5pc100_device_pdma0 = {
147 .periphid = 0x00041330, 89 .periphid = 0x00041330,
148}; 90};
149 91
150struct dma_pl330_peri pdma1_peri[30] = { 92u8 pdma1_peri[] = {
151 { 93 DMACH_UART0_RX,
152 .peri_id = (u8)DMACH_UART0_RX, 94 DMACH_UART0_TX,
153 .rqtype = DEVTOMEM, 95 DMACH_UART1_RX,
154 }, { 96 DMACH_UART1_TX,
155 .peri_id = (u8)DMACH_UART0_TX, 97 DMACH_UART2_RX,
156 .rqtype = MEMTODEV, 98 DMACH_UART2_TX,
157 }, { 99 DMACH_UART3_RX,
158 .peri_id = (u8)DMACH_UART1_RX, 100 DMACH_UART3_TX,
159 .rqtype = DEVTOMEM, 101 DMACH_IRDA,
160 }, { 102 DMACH_I2S0_RX,
161 .peri_id = (u8)DMACH_UART1_TX, 103 DMACH_I2S0_TX,
162 .rqtype = MEMTODEV, 104 DMACH_I2S0S_TX,
163 }, { 105 DMACH_I2S1_RX,
164 .peri_id = (u8)DMACH_UART2_RX, 106 DMACH_I2S1_TX,
165 .rqtype = DEVTOMEM, 107 DMACH_I2S2_RX,
166 }, { 108 DMACH_I2S2_TX,
167 .peri_id = (u8)DMACH_UART2_TX, 109 DMACH_SPI0_RX,
168 .rqtype = MEMTODEV, 110 DMACH_SPI0_TX,
169 }, { 111 DMACH_SPI1_RX,
170 .peri_id = (u8)DMACH_UART3_RX, 112 DMACH_SPI1_TX,
171 .rqtype = DEVTOMEM, 113 DMACH_SPI2_RX,
172 }, { 114 DMACH_SPI2_TX,
173 .peri_id = (u8)DMACH_UART3_TX, 115 DMACH_PCM0_RX,
174 .rqtype = MEMTODEV, 116 DMACH_PCM0_TX,
175 }, { 117 DMACH_PCM1_RX,
176 .peri_id = DMACH_IRDA, 118 DMACH_PCM1_TX,
177 }, { 119 DMACH_MSM_REQ0,
178 .peri_id = (u8)DMACH_I2S0_RX, 120 DMACH_MSM_REQ1,
179 .rqtype = DEVTOMEM, 121 DMACH_MSM_REQ2,
180 }, { 122 DMACH_MSM_REQ3,
181 .peri_id = (u8)DMACH_I2S0_TX,
182 .rqtype = MEMTODEV,
183 }, {
184 .peri_id = (u8)DMACH_I2S0S_TX,
185 .rqtype = MEMTODEV,
186 }, {
187 .peri_id = (u8)DMACH_I2S1_RX,
188 .rqtype = DEVTOMEM,
189 }, {
190 .peri_id = (u8)DMACH_I2S1_TX,
191 .rqtype = MEMTODEV,
192 }, {
193 .peri_id = (u8)DMACH_I2S2_RX,
194 .rqtype = DEVTOMEM,
195 }, {
196 .peri_id = (u8)DMACH_I2S2_TX,
197 .rqtype = MEMTODEV,
198 }, {
199 .peri_id = (u8)DMACH_SPI0_RX,
200 .rqtype = DEVTOMEM,
201 }, {
202 .peri_id = (u8)DMACH_SPI0_TX,
203 .rqtype = MEMTODEV,
204 }, {
205 .peri_id = (u8)DMACH_SPI1_RX,
206 .rqtype = DEVTOMEM,
207 }, {
208 .peri_id = (u8)DMACH_SPI1_TX,
209 .rqtype = MEMTODEV,
210 }, {
211 .peri_id = (u8)DMACH_SPI2_RX,
212 .rqtype = DEVTOMEM,
213 }, {
214 .peri_id = (u8)DMACH_SPI2_TX,
215 .rqtype = MEMTODEV,
216 }, {
217 .peri_id = (u8)DMACH_PCM0_RX,
218 .rqtype = DEVTOMEM,
219 }, {
220 .peri_id = (u8)DMACH_PCM1_TX,
221 .rqtype = MEMTODEV,
222 }, {
223 .peri_id = (u8)DMACH_PCM1_RX,
224 .rqtype = DEVTOMEM,
225 }, {
226 .peri_id = (u8)DMACH_PCM1_TX,
227 .rqtype = MEMTODEV,
228 }, {
229 .peri_id = (u8)DMACH_MSM_REQ0,
230 }, {
231 .peri_id = (u8)DMACH_MSM_REQ1,
232 }, {
233 .peri_id = (u8)DMACH_MSM_REQ2,
234 }, {
235 .peri_id = (u8)DMACH_MSM_REQ3,
236 },
237}; 123};
238 124
239struct dma_pl330_platdata s5pc100_pdma1_pdata = { 125struct dma_pl330_platdata s5pc100_pdma1_pdata = {
240 .nr_valid_peri = ARRAY_SIZE(pdma1_peri), 126 .nr_valid_peri = ARRAY_SIZE(pdma1_peri),
241 .peri = pdma1_peri, 127 .peri_id = pdma1_peri,
242}; 128};
243 129
244struct amba_device s5pc100_device_pdma1 = { 130struct amba_device s5pc100_device_pdma1 = {
@@ -259,7 +145,12 @@ struct amba_device s5pc100_device_pdma1 = {
259 145
260static int __init s5pc100_dma_init(void) 146static int __init s5pc100_dma_init(void)
261{ 147{
148 dma_cap_set(DMA_SLAVE, s5pc100_pdma0_pdata.cap_mask);
149 dma_cap_set(DMA_CYCLIC, s5pc100_pdma0_pdata.cap_mask);
262 amba_device_register(&s5pc100_device_pdma0, &iomem_resource); 150 amba_device_register(&s5pc100_device_pdma0, &iomem_resource);
151
152 dma_cap_set(DMA_SLAVE, s5pc100_pdma1_pdata.cap_mask);
153 dma_cap_set(DMA_CYCLIC, s5pc100_pdma1_pdata.cap_mask);
263 amba_device_register(&s5pc100_device_pdma1, &iomem_resource); 154 amba_device_register(&s5pc100_device_pdma1, &iomem_resource);
264 155
265 return 0; 156 return 0;
diff --git a/arch/arm/mach-s5pc100/include/mach/irqs.h b/arch/arm/mach-s5pc100/include/mach/irqs.h
index d2eb4757381f..2870f12c7926 100644
--- a/arch/arm/mach-s5pc100/include/mach/irqs.h
+++ b/arch/arm/mach-s5pc100/include/mach/irqs.h
@@ -97,6 +97,8 @@
97#define IRQ_SDMFIQ S5P_IRQ_VIC2(31) 97#define IRQ_SDMFIQ S5P_IRQ_VIC2(31)
98#define IRQ_VIC_END S5P_IRQ_VIC2(31) 98#define IRQ_VIC_END S5P_IRQ_VIC2(31)
99 99
100#define IRQ_TIMER_BASE (11)
101
100#define S5P_EINT_BASE1 (S5P_IRQ_VIC0(0)) 102#define S5P_EINT_BASE1 (S5P_IRQ_VIC0(0))
101#define S5P_EINT_BASE2 (IRQ_VIC_END + 1) 103#define S5P_EINT_BASE2 (IRQ_VIC_END + 1)
102 104
diff --git a/arch/arm/mach-s5pv210/clock.c b/arch/arm/mach-s5pv210/clock.c
index 4c5ac7a69e9e..43a045d354ec 100644
--- a/arch/arm/mach-s5pv210/clock.c
+++ b/arch/arm/mach-s5pv210/clock.c
@@ -809,46 +809,6 @@ static struct clksrc_clk clksrcs[] = {
809 .reg_div = { .reg = S5P_CLK_DIV6, .shift = 12, .size = 3 }, 809 .reg_div = { .reg = S5P_CLK_DIV6, .shift = 12, .size = 3 },
810 }, { 810 }, {
811 .clk = { 811 .clk = {
812 .name = "uclk1",
813 .devname = "s5pv210-uart.0",
814 .enable = s5pv210_clk_mask0_ctrl,
815 .ctrlbit = (1 << 12),
816 },
817 .sources = &clkset_uart,
818 .reg_src = { .reg = S5P_CLK_SRC4, .shift = 16, .size = 4 },
819 .reg_div = { .reg = S5P_CLK_DIV4, .shift = 16, .size = 4 },
820 }, {
821 .clk = {
822 .name = "uclk1",
823 .devname = "s5pv210-uart.1",
824 .enable = s5pv210_clk_mask0_ctrl,
825 .ctrlbit = (1 << 13),
826 },
827 .sources = &clkset_uart,
828 .reg_src = { .reg = S5P_CLK_SRC4, .shift = 20, .size = 4 },
829 .reg_div = { .reg = S5P_CLK_DIV4, .shift = 20, .size = 4 },
830 }, {
831 .clk = {
832 .name = "uclk1",
833 .devname = "s5pv210-uart.2",
834 .enable = s5pv210_clk_mask0_ctrl,
835 .ctrlbit = (1 << 14),
836 },
837 .sources = &clkset_uart,
838 .reg_src = { .reg = S5P_CLK_SRC4, .shift = 24, .size = 4 },
839 .reg_div = { .reg = S5P_CLK_DIV4, .shift = 24, .size = 4 },
840 }, {
841 .clk = {
842 .name = "uclk1",
843 .devname = "s5pv210-uart.3",
844 .enable = s5pv210_clk_mask0_ctrl,
845 .ctrlbit = (1 << 15),
846 },
847 .sources = &clkset_uart,
848 .reg_src = { .reg = S5P_CLK_SRC4, .shift = 28, .size = 4 },
849 .reg_div = { .reg = S5P_CLK_DIV4, .shift = 28, .size = 4 },
850 }, {
851 .clk = {
852 .name = "sclk_fimc", 812 .name = "sclk_fimc",
853 .devname = "s5pv210-fimc.0", 813 .devname = "s5pv210-fimc.0",
854 .enable = s5pv210_clk_mask1_ctrl, 814 .enable = s5pv210_clk_mask1_ctrl,
@@ -1022,6 +982,61 @@ static struct clksrc_clk clksrcs[] = {
1022 }, 982 },
1023}; 983};
1024 984
985static struct clksrc_clk clk_sclk_uart0 = {
986 .clk = {
987 .name = "uclk1",
988 .devname = "s5pv210-uart.0",
989 .enable = s5pv210_clk_mask0_ctrl,
990 .ctrlbit = (1 << 12),
991 },
992 .sources = &clkset_uart,
993 .reg_src = { .reg = S5P_CLK_SRC4, .shift = 16, .size = 4 },
994 .reg_div = { .reg = S5P_CLK_DIV4, .shift = 16, .size = 4 },
995};
996
997static struct clksrc_clk clk_sclk_uart1 = {
998 .clk = {
999 .name = "uclk1",
1000 .devname = "s5pv210-uart.1",
1001 .enable = s5pv210_clk_mask0_ctrl,
1002 .ctrlbit = (1 << 13),
1003 },
1004 .sources = &clkset_uart,
1005 .reg_src = { .reg = S5P_CLK_SRC4, .shift = 20, .size = 4 },
1006 .reg_div = { .reg = S5P_CLK_DIV4, .shift = 20, .size = 4 },
1007};
1008
1009static struct clksrc_clk clk_sclk_uart2 = {
1010 .clk = {
1011 .name = "uclk1",
1012 .devname = "s5pv210-uart.2",
1013 .enable = s5pv210_clk_mask0_ctrl,
1014 .ctrlbit = (1 << 14),
1015 },
1016 .sources = &clkset_uart,
1017 .reg_src = { .reg = S5P_CLK_SRC4, .shift = 24, .size = 4 },
1018 .reg_div = { .reg = S5P_CLK_DIV4, .shift = 24, .size = 4 },
1019};
1020
1021static struct clksrc_clk clk_sclk_uart3 = {
1022 .clk = {
1023 .name = "uclk1",
1024 .devname = "s5pv210-uart.3",
1025 .enable = s5pv210_clk_mask0_ctrl,
1026 .ctrlbit = (1 << 15),
1027 },
1028 .sources = &clkset_uart,
1029 .reg_src = { .reg = S5P_CLK_SRC4, .shift = 28, .size = 4 },
1030 .reg_div = { .reg = S5P_CLK_DIV4, .shift = 28, .size = 4 },
1031};
1032
1033static struct clksrc_clk *clksrc_cdev[] = {
1034 &clk_sclk_uart0,
1035 &clk_sclk_uart1,
1036 &clk_sclk_uart2,
1037 &clk_sclk_uart3,
1038};
1039
1025/* Clock initialisation code */ 1040/* Clock initialisation code */
1026static struct clksrc_clk *sysclks[] = { 1041static struct clksrc_clk *sysclks[] = {
1027 &clk_mout_apll, 1042 &clk_mout_apll,
@@ -1261,6 +1276,14 @@ static struct clk *clks[] __initdata = {
1261 &clk_pcmcdclk2, 1276 &clk_pcmcdclk2,
1262}; 1277};
1263 1278
1279static struct clk_lookup s5pv210_clk_lookup[] = {
1280 CLKDEV_INIT(NULL, "clk_uart_baud0", &clk_p),
1281 CLKDEV_INIT("s5pv210-uart.0", "clk_uart_baud1", &clk_sclk_uart0.clk),
1282 CLKDEV_INIT("s5pv210-uart.1", "clk_uart_baud1", &clk_sclk_uart1.clk),
1283 CLKDEV_INIT("s5pv210-uart.2", "clk_uart_baud1", &clk_sclk_uart2.clk),
1284 CLKDEV_INIT("s5pv210-uart.3", "clk_uart_baud1", &clk_sclk_uart3.clk),
1285};
1286
1264void __init s5pv210_register_clocks(void) 1287void __init s5pv210_register_clocks(void)
1265{ 1288{
1266 int ptr; 1289 int ptr;
@@ -1273,11 +1296,15 @@ void __init s5pv210_register_clocks(void)
1273 for (ptr = 0; ptr < ARRAY_SIZE(sclk_tv); ptr++) 1296 for (ptr = 0; ptr < ARRAY_SIZE(sclk_tv); ptr++)
1274 s3c_register_clksrc(sclk_tv[ptr], 1); 1297 s3c_register_clksrc(sclk_tv[ptr], 1);
1275 1298
1299 for (ptr = 0; ptr < ARRAY_SIZE(clksrc_cdev); ptr++)
1300 s3c_register_clksrc(clksrc_cdev[ptr], 1);
1301
1276 s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs)); 1302 s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs));
1277 s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks)); 1303 s3c_register_clocks(init_clocks, ARRAY_SIZE(init_clocks));
1278 1304
1279 s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); 1305 s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
1280 s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); 1306 s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
1307 clkdev_add_table(s5pv210_clk_lookup, ARRAY_SIZE(s5pv210_clk_lookup));
1281 1308
1282 s3c24xx_register_clock(&dummy_apb_pclk); 1309 s3c24xx_register_clock(&dummy_apb_pclk);
1283 s3c_pwmclk_init(); 1310 s3c_pwmclk_init();
diff --git a/arch/arm/mach-s5pv210/dma.c b/arch/arm/mach-s5pv210/dma.c
index 86b749c18b77..a6113e0267f2 100644
--- a/arch/arm/mach-s5pv210/dma.c
+++ b/arch/arm/mach-s5pv210/dma.c
@@ -35,90 +35,40 @@
35 35
36static u64 dma_dmamask = DMA_BIT_MASK(32); 36static u64 dma_dmamask = DMA_BIT_MASK(32);
37 37
38struct dma_pl330_peri pdma0_peri[28] = { 38u8 pdma0_peri[] = {
39 { 39 DMACH_UART0_RX,
40 .peri_id = (u8)DMACH_UART0_RX, 40 DMACH_UART0_TX,
41 .rqtype = DEVTOMEM, 41 DMACH_UART1_RX,
42 }, { 42 DMACH_UART1_TX,
43 .peri_id = (u8)DMACH_UART0_TX, 43 DMACH_UART2_RX,
44 .rqtype = MEMTODEV, 44 DMACH_UART2_TX,
45 }, { 45 DMACH_UART3_RX,
46 .peri_id = (u8)DMACH_UART1_RX, 46 DMACH_UART3_TX,
47 .rqtype = DEVTOMEM, 47 DMACH_MAX,
48 }, { 48 DMACH_I2S0_RX,
49 .peri_id = (u8)DMACH_UART1_TX, 49 DMACH_I2S0_TX,
50 .rqtype = MEMTODEV, 50 DMACH_I2S0S_TX,
51 }, { 51 DMACH_I2S1_RX,
52 .peri_id = (u8)DMACH_UART2_RX, 52 DMACH_I2S1_TX,
53 .rqtype = DEVTOMEM, 53 DMACH_MAX,
54 }, { 54 DMACH_MAX,
55 .peri_id = (u8)DMACH_UART2_TX, 55 DMACH_SPI0_RX,
56 .rqtype = MEMTODEV, 56 DMACH_SPI0_TX,
57 }, { 57 DMACH_SPI1_RX,
58 .peri_id = (u8)DMACH_UART3_RX, 58 DMACH_SPI1_TX,
59 .rqtype = DEVTOMEM, 59 DMACH_MAX,
60 }, { 60 DMACH_MAX,
61 .peri_id = (u8)DMACH_UART3_TX, 61 DMACH_AC97_MICIN,
62 .rqtype = MEMTODEV, 62 DMACH_AC97_PCMIN,
63 }, { 63 DMACH_AC97_PCMOUT,
64 .peri_id = DMACH_MAX, 64 DMACH_MAX,
65 }, { 65 DMACH_PWM,
66 .peri_id = (u8)DMACH_I2S0_RX, 66 DMACH_SPDIF,
67 .rqtype = DEVTOMEM,
68 }, {
69 .peri_id = (u8)DMACH_I2S0_TX,
70 .rqtype = MEMTODEV,
71 }, {
72 .peri_id = (u8)DMACH_I2S0S_TX,
73 .rqtype = MEMTODEV,
74 }, {
75 .peri_id = (u8)DMACH_I2S1_RX,
76 .rqtype = DEVTOMEM,
77 }, {
78 .peri_id = (u8)DMACH_I2S1_TX,
79 .rqtype = MEMTODEV,
80 }, {
81 .peri_id = (u8)DMACH_MAX,
82 }, {
83 .peri_id = (u8)DMACH_MAX,
84 }, {
85 .peri_id = (u8)DMACH_SPI0_RX,
86 .rqtype = DEVTOMEM,
87 }, {
88 .peri_id = (u8)DMACH_SPI0_TX,
89 .rqtype = MEMTODEV,
90 }, {
91 .peri_id = (u8)DMACH_SPI1_RX,
92 .rqtype = DEVTOMEM,
93 }, {
94 .peri_id = (u8)DMACH_SPI1_TX,
95 .rqtype = MEMTODEV,
96 }, {
97 .peri_id = (u8)DMACH_MAX,
98 }, {
99 .peri_id = (u8)DMACH_MAX,
100 }, {
101 .peri_id = (u8)DMACH_AC97_MICIN,
102 .rqtype = DEVTOMEM,
103 }, {
104 .peri_id = (u8)DMACH_AC97_PCMIN,
105 .rqtype = DEVTOMEM,
106 }, {
107 .peri_id = (u8)DMACH_AC97_PCMOUT,
108 .rqtype = MEMTODEV,
109 }, {
110 .peri_id = (u8)DMACH_MAX,
111 }, {
112 .peri_id = (u8)DMACH_PWM,
113 }, {
114 .peri_id = (u8)DMACH_SPDIF,
115 .rqtype = MEMTODEV,
116 },
117}; 67};
118 68
119struct dma_pl330_platdata s5pv210_pdma0_pdata = { 69struct dma_pl330_platdata s5pv210_pdma0_pdata = {
120 .nr_valid_peri = ARRAY_SIZE(pdma0_peri), 70 .nr_valid_peri = ARRAY_SIZE(pdma0_peri),
121 .peri = pdma0_peri, 71 .peri_id = pdma0_peri,
122}; 72};
123 73
124struct amba_device s5pv210_device_pdma0 = { 74struct amba_device s5pv210_device_pdma0 = {
@@ -137,102 +87,44 @@ struct amba_device s5pv210_device_pdma0 = {
137 .periphid = 0x00041330, 87 .periphid = 0x00041330,
138}; 88};
139 89
140struct dma_pl330_peri pdma1_peri[32] = { 90u8 pdma1_peri[] = {
141 { 91 DMACH_UART0_RX,
142 .peri_id = (u8)DMACH_UART0_RX, 92 DMACH_UART0_TX,
143 .rqtype = DEVTOMEM, 93 DMACH_UART1_RX,
144 }, { 94 DMACH_UART1_TX,
145 .peri_id = (u8)DMACH_UART0_TX, 95 DMACH_UART2_RX,
146 .rqtype = MEMTODEV, 96 DMACH_UART2_TX,
147 }, { 97 DMACH_UART3_RX,
148 .peri_id = (u8)DMACH_UART1_RX, 98 DMACH_UART3_TX,
149 .rqtype = DEVTOMEM, 99 DMACH_MAX,
150 }, { 100 DMACH_I2S0_RX,
151 .peri_id = (u8)DMACH_UART1_TX, 101 DMACH_I2S0_TX,
152 .rqtype = MEMTODEV, 102 DMACH_I2S0S_TX,
153 }, { 103 DMACH_I2S1_RX,
154 .peri_id = (u8)DMACH_UART2_RX, 104 DMACH_I2S1_TX,
155 .rqtype = DEVTOMEM, 105 DMACH_I2S2_RX,
156 }, { 106 DMACH_I2S2_TX,
157 .peri_id = (u8)DMACH_UART2_TX, 107 DMACH_SPI0_RX,
158 .rqtype = MEMTODEV, 108 DMACH_SPI0_TX,
159 }, { 109 DMACH_SPI1_RX,
160 .peri_id = (u8)DMACH_UART3_RX, 110 DMACH_SPI1_TX,
161 .rqtype = DEVTOMEM, 111 DMACH_MAX,
162 }, { 112 DMACH_MAX,
163 .peri_id = (u8)DMACH_UART3_TX, 113 DMACH_PCM0_RX,
164 .rqtype = MEMTODEV, 114 DMACH_PCM0_TX,
165 }, { 115 DMACH_PCM1_RX,
166 .peri_id = DMACH_MAX, 116 DMACH_PCM1_TX,
167 }, { 117 DMACH_MSM_REQ0,
168 .peri_id = (u8)DMACH_I2S0_RX, 118 DMACH_MSM_REQ1,
169 .rqtype = DEVTOMEM, 119 DMACH_MSM_REQ2,
170 }, { 120 DMACH_MSM_REQ3,
171 .peri_id = (u8)DMACH_I2S0_TX, 121 DMACH_PCM2_RX,
172 .rqtype = MEMTODEV, 122 DMACH_PCM2_TX,
173 }, {
174 .peri_id = (u8)DMACH_I2S0S_TX,
175 .rqtype = MEMTODEV,
176 }, {
177 .peri_id = (u8)DMACH_I2S1_RX,
178 .rqtype = DEVTOMEM,
179 }, {
180 .peri_id = (u8)DMACH_I2S1_TX,
181 .rqtype = MEMTODEV,
182 }, {
183 .peri_id = (u8)DMACH_I2S2_RX,
184 .rqtype = DEVTOMEM,
185 }, {
186 .peri_id = (u8)DMACH_I2S2_TX,
187 .rqtype = MEMTODEV,
188 }, {
189 .peri_id = (u8)DMACH_SPI0_RX,
190 .rqtype = DEVTOMEM,
191 }, {
192 .peri_id = (u8)DMACH_SPI0_TX,
193 .rqtype = MEMTODEV,
194 }, {
195 .peri_id = (u8)DMACH_SPI1_RX,
196 .rqtype = DEVTOMEM,
197 }, {
198 .peri_id = (u8)DMACH_SPI1_TX,
199 .rqtype = MEMTODEV,
200 }, {
201 .peri_id = (u8)DMACH_MAX,
202 }, {
203 .peri_id = (u8)DMACH_MAX,
204 }, {
205 .peri_id = (u8)DMACH_PCM0_RX,
206 .rqtype = DEVTOMEM,
207 }, {
208 .peri_id = (u8)DMACH_PCM0_TX,
209 .rqtype = MEMTODEV,
210 }, {
211 .peri_id = (u8)DMACH_PCM1_RX,
212 .rqtype = DEVTOMEM,
213 }, {
214 .peri_id = (u8)DMACH_PCM1_TX,
215 .rqtype = MEMTODEV,
216 }, {
217 .peri_id = (u8)DMACH_MSM_REQ0,
218 }, {
219 .peri_id = (u8)DMACH_MSM_REQ1,
220 }, {
221 .peri_id = (u8)DMACH_MSM_REQ2,
222 }, {
223 .peri_id = (u8)DMACH_MSM_REQ3,
224 }, {
225 .peri_id = (u8)DMACH_PCM2_RX,
226 .rqtype = DEVTOMEM,
227 }, {
228 .peri_id = (u8)DMACH_PCM2_TX,
229 .rqtype = MEMTODEV,
230 },
231}; 123};
232 124
233struct dma_pl330_platdata s5pv210_pdma1_pdata = { 125struct dma_pl330_platdata s5pv210_pdma1_pdata = {
234 .nr_valid_peri = ARRAY_SIZE(pdma1_peri), 126 .nr_valid_peri = ARRAY_SIZE(pdma1_peri),
235 .peri = pdma1_peri, 127 .peri_id = pdma1_peri,
236}; 128};
237 129
238struct amba_device s5pv210_device_pdma1 = { 130struct amba_device s5pv210_device_pdma1 = {
@@ -253,7 +145,12 @@ struct amba_device s5pv210_device_pdma1 = {
253 145
254static int __init s5pv210_dma_init(void) 146static int __init s5pv210_dma_init(void)
255{ 147{
148 dma_cap_set(DMA_SLAVE, s5pv210_pdma0_pdata.cap_mask);
149 dma_cap_set(DMA_CYCLIC, s5pv210_pdma0_pdata.cap_mask);
256 amba_device_register(&s5pv210_device_pdma0, &iomem_resource); 150 amba_device_register(&s5pv210_device_pdma0, &iomem_resource);
151
152 dma_cap_set(DMA_SLAVE, s5pv210_pdma1_pdata.cap_mask);
153 dma_cap_set(DMA_CYCLIC, s5pv210_pdma1_pdata.cap_mask);
257 amba_device_register(&s5pv210_device_pdma1, &iomem_resource); 154 amba_device_register(&s5pv210_device_pdma1, &iomem_resource);
258 155
259 return 0; 156 return 0;
diff --git a/arch/arm/mach-s5pv210/include/mach/irqs.h b/arch/arm/mach-s5pv210/include/mach/irqs.h
index 5e0de3a31f3d..e777e010ed2e 100644
--- a/arch/arm/mach-s5pv210/include/mach/irqs.h
+++ b/arch/arm/mach-s5pv210/include/mach/irqs.h
@@ -118,6 +118,8 @@
118#define IRQ_MDNIE3 S5P_IRQ_VIC3(8) 118#define IRQ_MDNIE3 S5P_IRQ_VIC3(8)
119#define IRQ_VIC_END S5P_IRQ_VIC3(31) 119#define IRQ_VIC_END S5P_IRQ_VIC3(31)
120 120
121#define IRQ_TIMER_BASE (11)
122
121#define S5P_EINT_BASE1 (S5P_IRQ_VIC0(0)) 123#define S5P_EINT_BASE1 (S5P_IRQ_VIC0(0))
122#define S5P_EINT_BASE2 (IRQ_VIC_END + 1) 124#define S5P_EINT_BASE2 (IRQ_VIC_END + 1)
123 125
diff --git a/arch/arm/mach-s5pv210/init.c b/arch/arm/mach-s5pv210/init.c
index 4865ae2c475a..468a5f886193 100644
--- a/arch/arm/mach-s5pv210/init.c
+++ b/arch/arm/mach-s5pv210/init.c
@@ -18,27 +18,8 @@
18#include <plat/s5pv210.h> 18#include <plat/s5pv210.h>
19#include <plat/regs-serial.h> 19#include <plat/regs-serial.h>
20 20
21static struct s3c24xx_uart_clksrc s5pv210_serial_clocks[] = {
22 [0] = {
23 .name = "pclk",
24 .divisor = 1,
25 .min_baud = 0,
26 .max_baud = 0,
27 },
28};
29
30/* uart registration process */ 21/* uart registration process */
31void __init s5pv210_common_init_uarts(struct s3c2410_uartcfg *cfg, int no) 22void __init s5pv210_common_init_uarts(struct s3c2410_uartcfg *cfg, int no)
32{ 23{
33 struct s3c2410_uartcfg *tcfg = cfg;
34 u32 ucnt;
35
36 for (ucnt = 0; ucnt < no; ucnt++, tcfg++) {
37 if (!tcfg->clocks) {
38 tcfg->clocks = s5pv210_serial_clocks;
39 tcfg->clocks_size = ARRAY_SIZE(s5pv210_serial_clocks);
40 }
41 }
42
43 s3c24xx_init_uartdevs("s5pv210-uart", s5p_uart_resources, cfg, no); 24 s3c24xx_init_uartdevs("s5pv210-uart", s5p_uart_resources, cfg, no);
44} 25}
diff --git a/arch/arm/plat-s3c24xx/s3c2443-clock.c b/arch/arm/plat-s3c24xx/s3c2443-clock.c
index 5a21b15b2a97..4eab2cca2d92 100644
--- a/arch/arm/plat-s3c24xx/s3c2443-clock.c
+++ b/arch/arm/plat-s3c24xx/s3c2443-clock.c
@@ -297,13 +297,6 @@ static struct clksrc_clk clk_usb_bus_host = {
297 297
298static struct clksrc_clk clksrc_clks[] = { 298static struct clksrc_clk clksrc_clks[] = {
299 { 299 {
300 /* ART baud-rate clock sourced from esysclk via a divisor */
301 .clk = {
302 .name = "uartclk",
303 .parent = &clk_esysclk.clk,
304 },
305 .reg_div = { .reg = S3C2443_CLKDIV1, .size = 4, .shift = 8 },
306 }, {
307 /* camera interface bus-clock, divided down from esysclk */ 300 /* camera interface bus-clock, divided down from esysclk */
308 .clk = { 301 .clk = {
309 .name = "camif-upll", /* same as 2440 name */ 302 .name = "camif-upll", /* same as 2440 name */
@@ -323,6 +316,15 @@ static struct clksrc_clk clksrc_clks[] = {
323 }, 316 },
324}; 317};
325 318
319static struct clksrc_clk clk_esys_uart = {
320 /* ART baud-rate clock sourced from esysclk via a divisor */
321 .clk = {
322 .name = "uartclk",
323 .parent = &clk_esysclk.clk,
324 },
325 .reg_div = { .reg = S3C2443_CLKDIV1, .size = 4, .shift = 8 },
326};
327
326static struct clk clk_i2s_ext = { 328static struct clk clk_i2s_ext = {
327 .name = "i2s-ext", 329 .name = "i2s-ext",
328}; 330};
@@ -589,6 +591,12 @@ static struct clksrc_clk *clksrcs[] __initdata = {
589 &clk_arm, 591 &clk_arm,
590}; 592};
591 593
594static struct clk_lookup s3c2443_clk_lookup[] = {
595 CLKDEV_INIT(NULL, "clk_uart_baud1", &s3c24xx_uclk),
596 CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_p),
597 CLKDEV_INIT(NULL, "clk_uart_baud3", &clk_esys_uart.clk),
598};
599
592void __init s3c2443_common_init_clocks(int xtal, pll_fn get_mpll, 600void __init s3c2443_common_init_clocks(int xtal, pll_fn get_mpll,
593 unsigned int *divs, int nr_divs, 601 unsigned int *divs, int nr_divs,
594 int divmask) 602 int divmask)
@@ -618,6 +626,7 @@ void __init s3c2443_common_init_clocks(int xtal, pll_fn get_mpll,
618 /* See s3c2443/etc notes on disabling clocks at init time */ 626 /* See s3c2443/etc notes on disabling clocks at init time */
619 s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); 627 s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
620 s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); 628 s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
629 clkdev_add_table(s3c2443_clk_lookup, ARRAY_SIZE(s3c2443_clk_lookup));
621 630
622 s3c2443_common_setup_clocks(get_mpll); 631 s3c2443_common_setup_clocks(get_mpll);
623} 632}
diff --git a/arch/arm/plat-samsung/dma-ops.c b/arch/arm/plat-samsung/dma-ops.c
index 93a994a5dd8f..2cded872f22b 100644
--- a/arch/arm/plat-samsung/dma-ops.c
+++ b/arch/arm/plat-samsung/dma-ops.c
@@ -18,23 +18,24 @@
18 18
19#include <mach/dma.h> 19#include <mach/dma.h>
20 20
21static inline bool pl330_filter(struct dma_chan *chan, void *param)
22{
23 struct dma_pl330_peri *peri = chan->private;
24 return peri->peri_id == (unsigned)param;
25}
26
27static unsigned samsung_dmadev_request(enum dma_ch dma_ch, 21static unsigned samsung_dmadev_request(enum dma_ch dma_ch,
28 struct samsung_dma_info *info) 22 struct samsung_dma_info *info)
29{ 23{
30 struct dma_chan *chan; 24 struct dma_chan *chan;
31 dma_cap_mask_t mask; 25 dma_cap_mask_t mask;
32 struct dma_slave_config slave_config; 26 struct dma_slave_config slave_config;
27 void *filter_param;
33 28
34 dma_cap_zero(mask); 29 dma_cap_zero(mask);
35 dma_cap_set(info->cap, mask); 30 dma_cap_set(info->cap, mask);
36 31
37 chan = dma_request_channel(mask, pl330_filter, (void *)dma_ch); 32 /*
33 * If a dma channel property of a device node from device tree is
34 * specified, use that as the fliter parameter.
35 */
36 filter_param = (dma_ch == DMACH_DT_PROP) ? (void *)info->dt_dmach_prop :
37 (void *)dma_ch;
38 chan = dma_request_channel(mask, pl330_filter, filter_param);
38 39
39 if (info->direction == DMA_FROM_DEVICE) { 40 if (info->direction == DMA_FROM_DEVICE) {
40 memset(&slave_config, 0, sizeof(struct dma_slave_config)); 41 memset(&slave_config, 0, sizeof(struct dma_slave_config));
diff --git a/arch/arm/plat-samsung/include/plat/dma-ops.h b/arch/arm/plat-samsung/include/plat/dma-ops.h
index 4c1a363526cf..22eafc310bd7 100644
--- a/arch/arm/plat-samsung/include/plat/dma-ops.h
+++ b/arch/arm/plat-samsung/include/plat/dma-ops.h
@@ -31,6 +31,7 @@ struct samsung_dma_info {
31 enum dma_slave_buswidth width; 31 enum dma_slave_buswidth width;
32 dma_addr_t fifo; 32 dma_addr_t fifo;
33 struct s3c2410_dma_client *client; 33 struct s3c2410_dma_client *client;
34 struct property *dt_dmach_prop;
34}; 35};
35 36
36struct samsung_dma_ops { 37struct samsung_dma_ops {
diff --git a/arch/arm/plat-samsung/include/plat/dma-pl330.h b/arch/arm/plat-samsung/include/plat/dma-pl330.h
index 2e55e5958674..c5eaad529de5 100644
--- a/arch/arm/plat-samsung/include/plat/dma-pl330.h
+++ b/arch/arm/plat-samsung/include/plat/dma-pl330.h
@@ -21,7 +21,8 @@
21 * use these just as IDs. 21 * use these just as IDs.
22 */ 22 */
23enum dma_ch { 23enum dma_ch {
24 DMACH_UART0_RX, 24 DMACH_DT_PROP = -1,
25 DMACH_UART0_RX = 0,
25 DMACH_UART0_TX, 26 DMACH_UART0_TX,
26 DMACH_UART1_RX, 27 DMACH_UART1_RX,
27 DMACH_UART1_TX, 28 DMACH_UART1_TX,
diff --git a/arch/arm/plat-samsung/include/plat/irqs.h b/arch/arm/plat-samsung/include/plat/irqs.h
index 08d1a7ef97b7..df46b776976a 100644
--- a/arch/arm/plat-samsung/include/plat/irqs.h
+++ b/arch/arm/plat-samsung/include/plat/irqs.h
@@ -44,13 +44,14 @@
44#define S5P_IRQ_VIC2(x) (S5P_VIC2_BASE + (x)) 44#define S5P_IRQ_VIC2(x) (S5P_VIC2_BASE + (x))
45#define S5P_IRQ_VIC3(x) (S5P_VIC3_BASE + (x)) 45#define S5P_IRQ_VIC3(x) (S5P_VIC3_BASE + (x))
46 46
47#define S5P_TIMER_IRQ(x) (11 + (x)) 47#define S5P_TIMER_IRQ(x) (IRQ_TIMER_BASE + (x))
48 48
49#define IRQ_TIMER0 S5P_TIMER_IRQ(0) 49#define IRQ_TIMER0 S5P_TIMER_IRQ(0)
50#define IRQ_TIMER1 S5P_TIMER_IRQ(1) 50#define IRQ_TIMER1 S5P_TIMER_IRQ(1)
51#define IRQ_TIMER2 S5P_TIMER_IRQ(2) 51#define IRQ_TIMER2 S5P_TIMER_IRQ(2)
52#define IRQ_TIMER3 S5P_TIMER_IRQ(3) 52#define IRQ_TIMER3 S5P_TIMER_IRQ(3)
53#define IRQ_TIMER4 S5P_TIMER_IRQ(4) 53#define IRQ_TIMER4 S5P_TIMER_IRQ(4)
54#define IRQ_TIMER_COUNT (5)
54 55
55#define IRQ_EINT(x) ((x) < 16 ? ((x) + S5P_EINT_BASE1) \ 56#define IRQ_EINT(x) ((x) < 16 ? ((x) + S5P_EINT_BASE1) \
56 : ((x) - 16 + S5P_EINT_BASE2)) 57 : ((x) - 16 + S5P_EINT_BASE2))
diff --git a/arch/arm/plat-samsung/include/plat/regs-serial.h b/arch/arm/plat-samsung/include/plat/regs-serial.h
index 720734847027..29c26a818842 100644
--- a/arch/arm/plat-samsung/include/plat/regs-serial.h
+++ b/arch/arm/plat-samsung/include/plat/regs-serial.h
@@ -71,6 +71,7 @@
71#define S3C2410_LCON_IRM (1<<6) 71#define S3C2410_LCON_IRM (1<<6)
72 72
73#define S3C2440_UCON_CLKMASK (3<<10) 73#define S3C2440_UCON_CLKMASK (3<<10)
74#define S3C2440_UCON_CLKSHIFT (10)
74#define S3C2440_UCON_PCLK (0<<10) 75#define S3C2440_UCON_PCLK (0<<10)
75#define S3C2440_UCON_UCLK (1<<10) 76#define S3C2440_UCON_UCLK (1<<10)
76#define S3C2440_UCON_PCLK2 (2<<10) 77#define S3C2440_UCON_PCLK2 (2<<10)
@@ -78,6 +79,7 @@
78#define S3C2443_UCON_EPLL (3<<10) 79#define S3C2443_UCON_EPLL (3<<10)
79 80
80#define S3C6400_UCON_CLKMASK (3<<10) 81#define S3C6400_UCON_CLKMASK (3<<10)
82#define S3C6400_UCON_CLKSHIFT (10)
81#define S3C6400_UCON_PCLK (0<<10) 83#define S3C6400_UCON_PCLK (0<<10)
82#define S3C6400_UCON_PCLK2 (2<<10) 84#define S3C6400_UCON_PCLK2 (2<<10)
83#define S3C6400_UCON_UCLK0 (1<<10) 85#define S3C6400_UCON_UCLK0 (1<<10)
@@ -90,11 +92,14 @@
90#define S3C2440_UCON_DIVSHIFT (12) 92#define S3C2440_UCON_DIVSHIFT (12)
91 93
92#define S3C2412_UCON_CLKMASK (3<<10) 94#define S3C2412_UCON_CLKMASK (3<<10)
95#define S3C2412_UCON_CLKSHIFT (10)
93#define S3C2412_UCON_UCLK (1<<10) 96#define S3C2412_UCON_UCLK (1<<10)
94#define S3C2412_UCON_USYSCLK (3<<10) 97#define S3C2412_UCON_USYSCLK (3<<10)
95#define S3C2412_UCON_PCLK (0<<10) 98#define S3C2412_UCON_PCLK (0<<10)
96#define S3C2412_UCON_PCLK2 (2<<10) 99#define S3C2412_UCON_PCLK2 (2<<10)
97 100
101#define S3C2410_UCON_CLKMASK (1 << 10)
102#define S3C2410_UCON_CLKSHIFT (10)
98#define S3C2410_UCON_UCLK (1<<10) 103#define S3C2410_UCON_UCLK (1<<10)
99#define S3C2410_UCON_SBREAK (1<<4) 104#define S3C2410_UCON_SBREAK (1<<4)
100 105
@@ -193,6 +198,7 @@
193 198
194/* Following are specific to S5PV210 */ 199/* Following are specific to S5PV210 */
195#define S5PV210_UCON_CLKMASK (1<<10) 200#define S5PV210_UCON_CLKMASK (1<<10)
201#define S5PV210_UCON_CLKSHIFT (10)
196#define S5PV210_UCON_PCLK (0<<10) 202#define S5PV210_UCON_PCLK (0<<10)
197#define S5PV210_UCON_UCLK (1<<10) 203#define S5PV210_UCON_UCLK (1<<10)
198 204
@@ -221,29 +227,24 @@
221#define S5PV210_UFSTAT_RXMASK (255<<0) 227#define S5PV210_UFSTAT_RXMASK (255<<0)
222#define S5PV210_UFSTAT_RXSHIFT (0) 228#define S5PV210_UFSTAT_RXSHIFT (0)
223 229
224#define NO_NEED_CHECK_CLKSRC 1 230#define S3C2410_UCON_CLKSEL0 (1 << 0)
231#define S3C2410_UCON_CLKSEL1 (1 << 1)
232#define S3C2410_UCON_CLKSEL2 (1 << 2)
233#define S3C2410_UCON_CLKSEL3 (1 << 3)
225 234
226#ifndef __ASSEMBLY__ 235/* Default values for s5pv210 UCON and UFCON uart registers */
236#define S5PV210_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
237 S3C2410_UCON_RXILEVEL | \
238 S3C2410_UCON_TXIRQMODE | \
239 S3C2410_UCON_RXIRQMODE | \
240 S3C2410_UCON_RXFIFO_TOI | \
241 S3C2443_UCON_RXERR_IRQEN)
227 242
228/* struct s3c24xx_uart_clksrc 243#define S5PV210_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE | \
229 * 244 S5PV210_UFCON_TXTRIG4 | \
230 * this structure defines a named clock source that can be used for the 245 S5PV210_UFCON_RXTRIG4)
231 * uart, so that the best clock can be selected for the requested baud
232 * rate.
233 *
234 * min_baud and max_baud define the range of baud-rates this clock is
235 * acceptable for, if they are both zero, it is assumed any baud rate that
236 * can be generated from this clock will be used.
237 *
238 * divisor gives the divisor from the clock to the one seen by the uart
239*/
240 246
241struct s3c24xx_uart_clksrc { 247#ifndef __ASSEMBLY__
242 const char *name;
243 unsigned int divisor;
244 unsigned int min_baud;
245 unsigned int max_baud;
246};
247 248
248/* configuration structure for per-machine configurations for the 249/* configuration structure for per-machine configurations for the
249 * serial port 250 * serial port
@@ -257,15 +258,13 @@ struct s3c2410_uartcfg {
257 unsigned char unused; 258 unsigned char unused;
258 unsigned short flags; 259 unsigned short flags;
259 upf_t uart_flags; /* default uart flags */ 260 upf_t uart_flags; /* default uart flags */
261 unsigned int clk_sel;
260 262
261 unsigned int has_fracval; 263 unsigned int has_fracval;
262 264
263 unsigned long ucon; /* value of ucon for port */ 265 unsigned long ucon; /* value of ucon for port */
264 unsigned long ulcon; /* value of ulcon for port */ 266 unsigned long ulcon; /* value of ulcon for port */
265 unsigned long ufcon; /* value of ufcon for port */ 267 unsigned long ufcon; /* value of ufcon for port */
266
267 struct s3c24xx_uart_clksrc *clocks;
268 unsigned int clocks_size;
269}; 268};
270 269
271/* s3c24xx_uart_devs 270/* s3c24xx_uart_devs
diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c
index 571041477ab2..a626e15799a5 100644
--- a/drivers/dma/pl330.c
+++ b/drivers/dma/pl330.c
@@ -19,6 +19,7 @@
19#include <linux/amba/pl330.h> 19#include <linux/amba/pl330.h>
20#include <linux/pm_runtime.h> 20#include <linux/pm_runtime.h>
21#include <linux/scatterlist.h> 21#include <linux/scatterlist.h>
22#include <linux/of.h>
22 23
23#define NR_DEFAULT_DESC 16 24#define NR_DEFAULT_DESC 16
24 25
@@ -116,6 +117,9 @@ struct dma_pl330_desc {
116 struct dma_pl330_chan *pchan; 117 struct dma_pl330_chan *pchan;
117}; 118};
118 119
120/* forward declaration */
121static struct amba_driver pl330_driver;
122
119static inline struct dma_pl330_chan * 123static inline struct dma_pl330_chan *
120to_pchan(struct dma_chan *ch) 124to_pchan(struct dma_chan *ch)
121{ 125{
@@ -267,6 +271,32 @@ static void dma_pl330_rqcb(void *token, enum pl330_op_err err)
267 tasklet_schedule(&pch->task); 271 tasklet_schedule(&pch->task);
268} 272}
269 273
274bool pl330_filter(struct dma_chan *chan, void *param)
275{
276 u8 *peri_id;
277
278 if (chan->device->dev->driver != &pl330_driver.drv)
279 return false;
280
281#ifdef CONFIG_OF
282 if (chan->device->dev->of_node) {
283 const __be32 *prop_value;
284 phandle phandle;
285 struct device_node *node;
286
287 prop_value = ((struct property *)param)->value;
288 phandle = be32_to_cpup(prop_value++);
289 node = of_find_node_by_phandle(phandle);
290 return ((chan->private == node) &&
291 (chan->chan_id == be32_to_cpup(prop_value)));
292 }
293#endif
294
295 peri_id = chan->private;
296 return *peri_id == (unsigned)param;
297}
298EXPORT_SYMBOL(pl330_filter);
299
270static int pl330_alloc_chan_resources(struct dma_chan *chan) 300static int pl330_alloc_chan_resources(struct dma_chan *chan)
271{ 301{
272 struct dma_pl330_chan *pch = to_pchan(chan); 302 struct dma_pl330_chan *pch = to_pchan(chan);
@@ -497,7 +527,7 @@ pluck_desc(struct dma_pl330_dmac *pdmac)
497static struct dma_pl330_desc *pl330_get_desc(struct dma_pl330_chan *pch) 527static struct dma_pl330_desc *pl330_get_desc(struct dma_pl330_chan *pch)
498{ 528{
499 struct dma_pl330_dmac *pdmac = pch->dmac; 529 struct dma_pl330_dmac *pdmac = pch->dmac;
500 struct dma_pl330_peri *peri = pch->chan.private; 530 u8 *peri_id = pch->chan.private;
501 struct dma_pl330_desc *desc; 531 struct dma_pl330_desc *desc;
502 532
503 /* Pluck one desc from the pool of DMAC */ 533 /* Pluck one desc from the pool of DMAC */
@@ -522,13 +552,7 @@ static struct dma_pl330_desc *pl330_get_desc(struct dma_pl330_chan *pch)
522 desc->txd.cookie = 0; 552 desc->txd.cookie = 0;
523 async_tx_ack(&desc->txd); 553 async_tx_ack(&desc->txd);
524 554
525 if (peri) { 555 desc->req.peri = peri_id ? pch->chan.chan_id : 0;
526 desc->req.rqtype = peri->rqtype;
527 desc->req.peri = pch->chan.chan_id;
528 } else {
529 desc->req.rqtype = MEMTOMEM;
530 desc->req.peri = 0;
531 }
532 556
533 dma_async_tx_descriptor_init(&desc->txd, &pch->chan); 557 dma_async_tx_descriptor_init(&desc->txd, &pch->chan);
534 558
@@ -615,12 +639,14 @@ static struct dma_async_tx_descriptor *pl330_prep_dma_cyclic(
615 case DMA_TO_DEVICE: 639 case DMA_TO_DEVICE:
616 desc->rqcfg.src_inc = 1; 640 desc->rqcfg.src_inc = 1;
617 desc->rqcfg.dst_inc = 0; 641 desc->rqcfg.dst_inc = 0;
642 desc->req.rqtype = MEMTODEV;
618 src = dma_addr; 643 src = dma_addr;
619 dst = pch->fifo_addr; 644 dst = pch->fifo_addr;
620 break; 645 break;
621 case DMA_FROM_DEVICE: 646 case DMA_FROM_DEVICE:
622 desc->rqcfg.src_inc = 0; 647 desc->rqcfg.src_inc = 0;
623 desc->rqcfg.dst_inc = 1; 648 desc->rqcfg.dst_inc = 1;
649 desc->req.rqtype = DEVTOMEM;
624 src = pch->fifo_addr; 650 src = pch->fifo_addr;
625 dst = dma_addr; 651 dst = dma_addr;
626 break; 652 break;
@@ -646,16 +672,12 @@ pl330_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dst,
646{ 672{
647 struct dma_pl330_desc *desc; 673 struct dma_pl330_desc *desc;
648 struct dma_pl330_chan *pch = to_pchan(chan); 674 struct dma_pl330_chan *pch = to_pchan(chan);
649 struct dma_pl330_peri *peri = chan->private;
650 struct pl330_info *pi; 675 struct pl330_info *pi;
651 int burst; 676 int burst;
652 677
653 if (unlikely(!pch || !len)) 678 if (unlikely(!pch || !len))
654 return NULL; 679 return NULL;
655 680
656 if (peri && peri->rqtype != MEMTOMEM)
657 return NULL;
658
659 pi = &pch->dmac->pif; 681 pi = &pch->dmac->pif;
660 682
661 desc = __pl330_prep_dma_memcpy(pch, dst, src, len); 683 desc = __pl330_prep_dma_memcpy(pch, dst, src, len);
@@ -664,6 +686,7 @@ pl330_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dst,
664 686
665 desc->rqcfg.src_inc = 1; 687 desc->rqcfg.src_inc = 1;
666 desc->rqcfg.dst_inc = 1; 688 desc->rqcfg.dst_inc = 1;
689 desc->req.rqtype = MEMTOMEM;
667 690
668 /* Select max possible burst size */ 691 /* Select max possible burst size */
669 burst = pi->pcfg.data_bus_width / 8; 692 burst = pi->pcfg.data_bus_width / 8;
@@ -692,25 +715,14 @@ pl330_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
692{ 715{
693 struct dma_pl330_desc *first, *desc = NULL; 716 struct dma_pl330_desc *first, *desc = NULL;
694 struct dma_pl330_chan *pch = to_pchan(chan); 717 struct dma_pl330_chan *pch = to_pchan(chan);
695 struct dma_pl330_peri *peri = chan->private;
696 struct scatterlist *sg; 718 struct scatterlist *sg;
697 unsigned long flags; 719 unsigned long flags;
698 int i; 720 int i;
699 dma_addr_t addr; 721 dma_addr_t addr;
700 722
701 if (unlikely(!pch || !sgl || !sg_len || !peri)) 723 if (unlikely(!pch || !sgl || !sg_len))
702 return NULL; 724 return NULL;
703 725
704 /* Make sure the direction is consistent */
705 if ((direction == DMA_TO_DEVICE &&
706 peri->rqtype != MEMTODEV) ||
707 (direction == DMA_FROM_DEVICE &&
708 peri->rqtype != DEVTOMEM)) {
709 dev_err(pch->dmac->pif.dev, "%s:%d Invalid Direction\n",
710 __func__, __LINE__);
711 return NULL;
712 }
713
714 addr = pch->fifo_addr; 726 addr = pch->fifo_addr;
715 727
716 first = NULL; 728 first = NULL;
@@ -750,11 +762,13 @@ pl330_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl,
750 if (direction == DMA_TO_DEVICE) { 762 if (direction == DMA_TO_DEVICE) {
751 desc->rqcfg.src_inc = 1; 763 desc->rqcfg.src_inc = 1;
752 desc->rqcfg.dst_inc = 0; 764 desc->rqcfg.dst_inc = 0;
765 desc->req.rqtype = MEMTODEV;
753 fill_px(&desc->px, 766 fill_px(&desc->px,
754 addr, sg_dma_address(sg), sg_dma_len(sg)); 767 addr, sg_dma_address(sg), sg_dma_len(sg));
755 } else { 768 } else {
756 desc->rqcfg.src_inc = 0; 769 desc->rqcfg.src_inc = 0;
757 desc->rqcfg.dst_inc = 1; 770 desc->rqcfg.dst_inc = 1;
771 desc->req.rqtype = DEVTOMEM;
758 fill_px(&desc->px, 772 fill_px(&desc->px,
759 sg_dma_address(sg), addr, sg_dma_len(sg)); 773 sg_dma_address(sg), addr, sg_dma_len(sg));
760 } 774 }
@@ -856,32 +870,16 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
856 INIT_LIST_HEAD(&pd->channels); 870 INIT_LIST_HEAD(&pd->channels);
857 871
858 /* Initialize channel parameters */ 872 /* Initialize channel parameters */
859 num_chan = max(pdat ? pdat->nr_valid_peri : 0, (u8)pi->pcfg.num_chan); 873 num_chan = max(pdat ? pdat->nr_valid_peri : (u8)pi->pcfg.num_peri,
874 (u8)pi->pcfg.num_chan);
860 pdmac->peripherals = kzalloc(num_chan * sizeof(*pch), GFP_KERNEL); 875 pdmac->peripherals = kzalloc(num_chan * sizeof(*pch), GFP_KERNEL);
861 876
862 for (i = 0; i < num_chan; i++) { 877 for (i = 0; i < num_chan; i++) {
863 pch = &pdmac->peripherals[i]; 878 pch = &pdmac->peripherals[i];
864 if (pdat) { 879 if (!adev->dev.of_node)
865 struct dma_pl330_peri *peri = &pdat->peri[i]; 880 pch->chan.private = pdat ? &pdat->peri_id[i] : NULL;
866 881 else
867 switch (peri->rqtype) { 882 pch->chan.private = adev->dev.of_node;
868 case MEMTOMEM:
869 dma_cap_set(DMA_MEMCPY, pd->cap_mask);
870 break;
871 case MEMTODEV:
872 case DEVTOMEM:
873 dma_cap_set(DMA_SLAVE, pd->cap_mask);
874 dma_cap_set(DMA_CYCLIC, pd->cap_mask);
875 break;
876 default:
877 dev_err(&adev->dev, "DEVTODEV Not Supported\n");
878 continue;
879 }
880 pch->chan.private = peri;
881 } else {
882 dma_cap_set(DMA_MEMCPY, pd->cap_mask);
883 pch->chan.private = NULL;
884 }
885 883
886 INIT_LIST_HEAD(&pch->work_list); 884 INIT_LIST_HEAD(&pch->work_list);
887 spin_lock_init(&pch->lock); 885 spin_lock_init(&pch->lock);
@@ -894,6 +892,15 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id)
894 } 892 }
895 893
896 pd->dev = &adev->dev; 894 pd->dev = &adev->dev;
895 if (pdat) {
896 pd->cap_mask = pdat->cap_mask;
897 } else {
898 dma_cap_set(DMA_MEMCPY, pd->cap_mask);
899 if (pi->pcfg.num_peri) {
900 dma_cap_set(DMA_SLAVE, pd->cap_mask);
901 dma_cap_set(DMA_CYCLIC, pd->cap_mask);
902 }
903 }
897 904
898 pd->device_alloc_chan_resources = pl330_alloc_chan_resources; 905 pd->device_alloc_chan_resources = pl330_alloc_chan_resources;
899 pd->device_free_chan_resources = pl330_free_chan_resources; 906 pd->device_free_chan_resources = pl330_free_chan_resources;
diff --git a/drivers/gpio/gpio-samsung.c b/drivers/gpio/gpio-samsung.c
index 866251852719..6b4d23fd158e 100644
--- a/drivers/gpio/gpio-samsung.c
+++ b/drivers/gpio/gpio-samsung.c
@@ -24,6 +24,9 @@
24#include <linux/interrupt.h> 24#include <linux/interrupt.h>
25#include <linux/sysdev.h> 25#include <linux/sysdev.h>
26#include <linux/ioport.h> 26#include <linux/ioport.h>
27#include <linux/of.h>
28#include <linux/slab.h>
29#include <linux/of_address.h>
27 30
28#include <asm/irq.h> 31#include <asm/irq.h>
29 32
@@ -2374,6 +2377,63 @@ static struct samsung_gpio_chip exynos4_gpios_3[] = {
2374#endif 2377#endif
2375}; 2378};
2376 2379
2380#if defined(CONFIG_ARCH_EXYNOS4) && defined(CONFIG_OF)
2381static int exynos4_gpio_xlate(struct gpio_chip *gc, struct device_node *np,
2382 const void *gpio_spec, u32 *flags)
2383{
2384 const __be32 *gpio = gpio_spec;
2385 const u32 n = be32_to_cpup(gpio);
2386 unsigned int pin = gc->base + be32_to_cpu(gpio[0]);
2387
2388 if (WARN_ON(gc->of_gpio_n_cells < 4))
2389 return -EINVAL;
2390
2391 if (n > gc->ngpio)
2392 return -EINVAL;
2393
2394 if (s3c_gpio_cfgpin(pin, S3C_GPIO_SFN(be32_to_cpu(gpio[1]))))
2395 pr_warn("gpio_xlate: failed to set pin function\n");
2396 if (s3c_gpio_setpull(pin, be32_to_cpu(gpio[2])))
2397 pr_warn("gpio_xlate: failed to set pin pull up/down\n");
2398 if (s5p_gpio_set_drvstr(pin, be32_to_cpu(gpio[3])))
2399 pr_warn("gpio_xlate: failed to set pin drive strength\n");
2400
2401 return n;
2402}
2403
2404static const struct of_device_id exynos4_gpio_dt_match[] __initdata = {
2405 { .compatible = "samsung,exynos4-gpio", },
2406 {}
2407};
2408
2409static __init void exynos4_gpiolib_attach_ofnode(struct samsung_gpio_chip *chip,
2410 u64 base, u64 offset)
2411{
2412 struct gpio_chip *gc = &chip->chip;
2413 u64 address;
2414
2415 if (!of_have_populated_dt())
2416 return;
2417
2418 address = chip->base ? base + ((u32)chip->base & 0xfff) : base + offset;
2419 gc->of_node = of_find_matching_node_by_address(NULL,
2420 exynos4_gpio_dt_match, address);
2421 if (!gc->of_node) {
2422 pr_info("gpio: device tree node not found for gpio controller"
2423 " with base address %08llx\n", address);
2424 return;
2425 }
2426 gc->of_gpio_n_cells = 4;
2427 gc->of_xlate = exynos4_gpio_xlate;
2428}
2429#elif defined(CONFIG_ARCH_EXYNOS4)
2430static __init void exynos4_gpiolib_attach_ofnode(struct samsung_gpio_chip *chip,
2431 u64 base, u64 offset)
2432{
2433 return;
2434}
2435#endif /* defined(CONFIG_ARCH_EXYNOS4) && defined(CONFIG_OF) */
2436
2377/* TODO: cleanup soc_is_* */ 2437/* TODO: cleanup soc_is_* */
2378static __init int samsung_gpiolib_init(void) 2438static __init int samsung_gpiolib_init(void)
2379{ 2439{
@@ -2455,6 +2515,10 @@ static __init int samsung_gpiolib_init(void)
2455 chip->config = &exynos4_gpio_cfg; 2515 chip->config = &exynos4_gpio_cfg;
2456 chip->group = group++; 2516 chip->group = group++;
2457 } 2517 }
2518#ifdef CONFIG_CPU_EXYNOS4210
2519 exynos4_gpiolib_attach_ofnode(chip,
2520 EXYNOS4_PA_GPIO1, i * 0x20);
2521#endif
2458 } 2522 }
2459 samsung_gpiolib_add_4bit_chips(exynos4_gpios_1, nr_chips, S5P_VA_GPIO1); 2523 samsung_gpiolib_add_4bit_chips(exynos4_gpios_1, nr_chips, S5P_VA_GPIO1);
2460 2524
@@ -2467,6 +2531,10 @@ static __init int samsung_gpiolib_init(void)
2467 chip->config = &exynos4_gpio_cfg; 2531 chip->config = &exynos4_gpio_cfg;
2468 chip->group = group++; 2532 chip->group = group++;
2469 } 2533 }
2534#ifdef CONFIG_CPU_EXYNOS4210
2535 exynos4_gpiolib_attach_ofnode(chip,
2536 EXYNOS4_PA_GPIO2, i * 0x20);
2537#endif
2470 } 2538 }
2471 samsung_gpiolib_add_4bit_chips(exynos4_gpios_2, nr_chips, S5P_VA_GPIO2); 2539 samsung_gpiolib_add_4bit_chips(exynos4_gpios_2, nr_chips, S5P_VA_GPIO2);
2472 2540
@@ -2479,6 +2547,10 @@ static __init int samsung_gpiolib_init(void)
2479 chip->config = &exynos4_gpio_cfg; 2547 chip->config = &exynos4_gpio_cfg;
2480 chip->group = group++; 2548 chip->group = group++;
2481 } 2549 }
2550#ifdef CONFIG_CPU_EXYNOS4210
2551 exynos4_gpiolib_attach_ofnode(chip,
2552 EXYNOS4_PA_GPIO3, i * 0x20);
2553#endif
2482 } 2554 }
2483 samsung_gpiolib_add_4bit_chips(exynos4_gpios_3, nr_chips, S5P_VA_GPIO3); 2555 samsung_gpiolib_add_4bit_chips(exynos4_gpios_3, nr_chips, S5P_VA_GPIO3);
2484 2556
diff --git a/drivers/input/keyboard/samsung-keypad.c b/drivers/input/keyboard/samsung-keypad.c
index f689f49e3109..8a0060cd3982 100644
--- a/drivers/input/keyboard/samsung-keypad.c
+++ b/drivers/input/keyboard/samsung-keypad.c
@@ -21,6 +21,8 @@
21#include <linux/module.h> 21#include <linux/module.h>
22#include <linux/platform_device.h> 22#include <linux/platform_device.h>
23#include <linux/slab.h> 23#include <linux/slab.h>
24#include <linux/of.h>
25#include <linux/of_gpio.h>
24#include <linux/sched.h> 26#include <linux/sched.h>
25#include <plat/keypad.h> 27#include <plat/keypad.h>
26 28
@@ -68,31 +70,26 @@ struct samsung_keypad {
68 wait_queue_head_t wait; 70 wait_queue_head_t wait;
69 bool stopped; 71 bool stopped;
70 int irq; 72 int irq;
73 enum samsung_keypad_type type;
71 unsigned int row_shift; 74 unsigned int row_shift;
72 unsigned int rows; 75 unsigned int rows;
73 unsigned int cols; 76 unsigned int cols;
74 unsigned int row_state[SAMSUNG_MAX_COLS]; 77 unsigned int row_state[SAMSUNG_MAX_COLS];
78#ifdef CONFIG_OF
79 int row_gpios[SAMSUNG_MAX_ROWS];
80 int col_gpios[SAMSUNG_MAX_COLS];
81#endif
75 unsigned short keycodes[]; 82 unsigned short keycodes[];
76}; 83};
77 84
78static int samsung_keypad_is_s5pv210(struct device *dev)
79{
80 struct platform_device *pdev = to_platform_device(dev);
81 enum samsung_keypad_type type =
82 platform_get_device_id(pdev)->driver_data;
83
84 return type == KEYPAD_TYPE_S5PV210;
85}
86
87static void samsung_keypad_scan(struct samsung_keypad *keypad, 85static void samsung_keypad_scan(struct samsung_keypad *keypad,
88 unsigned int *row_state) 86 unsigned int *row_state)
89{ 87{
90 struct device *dev = keypad->input_dev->dev.parent;
91 unsigned int col; 88 unsigned int col;
92 unsigned int val; 89 unsigned int val;
93 90
94 for (col = 0; col < keypad->cols; col++) { 91 for (col = 0; col < keypad->cols; col++) {
95 if (samsung_keypad_is_s5pv210(dev)) { 92 if (keypad->type == KEYPAD_TYPE_S5PV210) {
96 val = S5PV210_KEYIFCOLEN_MASK; 93 val = S5PV210_KEYIFCOLEN_MASK;
97 val &= ~(1 << col) << 8; 94 val &= ~(1 << col) << 8;
98 } else { 95 } else {
@@ -235,6 +232,126 @@ static void samsung_keypad_close(struct input_dev *input_dev)
235 samsung_keypad_stop(keypad); 232 samsung_keypad_stop(keypad);
236} 233}
237 234
235#ifdef CONFIG_OF
236static struct samsung_keypad_platdata *samsung_keypad_parse_dt(
237 struct device *dev)
238{
239 struct samsung_keypad_platdata *pdata;
240 struct matrix_keymap_data *keymap_data;
241 uint32_t *keymap, num_rows = 0, num_cols = 0;
242 struct device_node *np = dev->of_node, *key_np;
243 unsigned int key_count = 0;
244
245 pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
246 if (!pdata) {
247 dev_err(dev, "could not allocate memory for platform data\n");
248 return NULL;
249 }
250
251 of_property_read_u32(np, "samsung,keypad-num-rows", &num_rows);
252 of_property_read_u32(np, "samsung,keypad-num-columns", &num_cols);
253 if (!num_rows || !num_cols) {
254 dev_err(dev, "number of keypad rows/columns not specified\n");
255 return NULL;
256 }
257 pdata->rows = num_rows;
258 pdata->cols = num_cols;
259
260 keymap_data = devm_kzalloc(dev, sizeof(*keymap_data), GFP_KERNEL);
261 if (!keymap_data) {
262 dev_err(dev, "could not allocate memory for keymap data\n");
263 return NULL;
264 }
265 pdata->keymap_data = keymap_data;
266
267 for_each_child_of_node(np, key_np)
268 key_count++;
269
270 keymap_data->keymap_size = key_count;
271 keymap = devm_kzalloc(dev, sizeof(uint32_t) * key_count, GFP_KERNEL);
272 if (!keymap) {
273 dev_err(dev, "could not allocate memory for keymap\n");
274 return NULL;
275 }
276 keymap_data->keymap = keymap;
277
278 for_each_child_of_node(np, key_np) {
279 u32 row, col, key_code;
280 of_property_read_u32(key_np, "keypad,row", &row);
281 of_property_read_u32(key_np, "keypad,column", &col);
282 of_property_read_u32(key_np, "linux,code", &key_code);
283 *keymap++ = KEY(row, col, key_code);
284 }
285
286 if (of_get_property(np, "linux,input-no-autorepeat", NULL))
287 pdata->no_autorepeat = true;
288 if (of_get_property(np, "linux,input-wakeup", NULL))
289 pdata->wakeup = true;
290
291 return pdata;
292}
293
294static void samsung_keypad_parse_dt_gpio(struct device *dev,
295 struct samsung_keypad *keypad)
296{
297 struct device_node *np = dev->of_node;
298 int gpio, ret, row, col;
299
300 for (row = 0; row < keypad->rows; row++) {
301 gpio = of_get_named_gpio(np, "row-gpios", row);
302 keypad->row_gpios[row] = gpio;
303 if (!gpio_is_valid(gpio)) {
304 dev_err(dev, "keypad row[%d]: invalid gpio %d\n",
305 row, gpio);
306 continue;
307 }
308
309 ret = gpio_request(gpio, "keypad-row");
310 if (ret)
311 dev_err(dev, "keypad row[%d] gpio request failed\n",
312 row);
313 }
314
315 for (col = 0; col < keypad->cols; col++) {
316 gpio = of_get_named_gpio(np, "col-gpios", col);
317 keypad->col_gpios[col] = gpio;
318 if (!gpio_is_valid(gpio)) {
319 dev_err(dev, "keypad column[%d]: invalid gpio %d\n",
320 col, gpio);
321 continue;
322 }
323
324 ret = gpio_request(gpio, "keypad-col");
325 if (ret)
326 dev_err(dev, "keypad column[%d] gpio request failed\n",
327 col);
328 }
329}
330
331static void samsung_keypad_dt_gpio_free(struct samsung_keypad *keypad)
332{
333 int cnt;
334
335 for (cnt = 0; cnt < keypad->rows; cnt++)
336 if (gpio_is_valid(keypad->row_gpios[cnt]))
337 gpio_free(keypad->row_gpios[cnt]);
338
339 for (cnt = 0; cnt < keypad->cols; cnt++)
340 if (gpio_is_valid(keypad->col_gpios[cnt]))
341 gpio_free(keypad->col_gpios[cnt]);
342}
343#else
344static
345struct samsung_keypad_platdata *samsung_keypad_parse_dt(struct device *dev)
346{
347 return NULL;
348}
349
350static void samsung_keypad_dt_gpio_free(struct samsung_keypad *keypad)
351{
352}
353#endif
354
238static int __devinit samsung_keypad_probe(struct platform_device *pdev) 355static int __devinit samsung_keypad_probe(struct platform_device *pdev)
239{ 356{
240 const struct samsung_keypad_platdata *pdata; 357 const struct samsung_keypad_platdata *pdata;
@@ -246,7 +363,10 @@ static int __devinit samsung_keypad_probe(struct platform_device *pdev)
246 unsigned int keymap_size; 363 unsigned int keymap_size;
247 int error; 364 int error;
248 365
249 pdata = pdev->dev.platform_data; 366 if (pdev->dev.of_node)
367 pdata = samsung_keypad_parse_dt(&pdev->dev);
368 else
369 pdata = pdev->dev.platform_data;
250 if (!pdata) { 370 if (!pdata) {
251 dev_err(&pdev->dev, "no platform data defined\n"); 371 dev_err(&pdev->dev, "no platform data defined\n");
252 return -EINVAL; 372 return -EINVAL;
@@ -303,6 +423,16 @@ static int __devinit samsung_keypad_probe(struct platform_device *pdev)
303 keypad->cols = pdata->cols; 423 keypad->cols = pdata->cols;
304 init_waitqueue_head(&keypad->wait); 424 init_waitqueue_head(&keypad->wait);
305 425
426 if (pdev->dev.of_node) {
427#ifdef CONFIG_OF
428 samsung_keypad_parse_dt_gpio(&pdev->dev, keypad);
429 keypad->type = of_device_is_compatible(pdev->dev.of_node,
430 "samsung,s5pv210-keypad");
431#endif
432 } else {
433 keypad->type = platform_get_device_id(pdev)->driver_data;
434 }
435
306 input_dev->name = pdev->name; 436 input_dev->name = pdev->name;
307 input_dev->id.bustype = BUS_HOST; 437 input_dev->id.bustype = BUS_HOST;
308 input_dev->dev.parent = &pdev->dev; 438 input_dev->dev.parent = &pdev->dev;
@@ -343,12 +473,19 @@ static int __devinit samsung_keypad_probe(struct platform_device *pdev)
343 473
344 device_init_wakeup(&pdev->dev, pdata->wakeup); 474 device_init_wakeup(&pdev->dev, pdata->wakeup);
345 platform_set_drvdata(pdev, keypad); 475 platform_set_drvdata(pdev, keypad);
476
477 if (pdev->dev.of_node) {
478 devm_kfree(&pdev->dev, (void *)pdata->keymap_data->keymap);
479 devm_kfree(&pdev->dev, (void *)pdata->keymap_data);
480 devm_kfree(&pdev->dev, (void *)pdata);
481 }
346 return 0; 482 return 0;
347 483
348err_free_irq: 484err_free_irq:
349 free_irq(keypad->irq, keypad); 485 free_irq(keypad->irq, keypad);
350err_put_clk: 486err_put_clk:
351 clk_put(keypad->clk); 487 clk_put(keypad->clk);
488 samsung_keypad_dt_gpio_free(keypad);
352err_unmap_base: 489err_unmap_base:
353 iounmap(keypad->base); 490 iounmap(keypad->base);
354err_free_mem: 491err_free_mem:
@@ -374,6 +511,7 @@ static int __devexit samsung_keypad_remove(struct platform_device *pdev)
374 free_irq(keypad->irq, keypad); 511 free_irq(keypad->irq, keypad);
375 512
376 clk_put(keypad->clk); 513 clk_put(keypad->clk);
514 samsung_keypad_dt_gpio_free(keypad);
377 515
378 iounmap(keypad->base); 516 iounmap(keypad->base);
379 kfree(keypad); 517 kfree(keypad);
@@ -447,6 +585,17 @@ static const struct dev_pm_ops samsung_keypad_pm_ops = {
447}; 585};
448#endif 586#endif
449 587
588#ifdef CONFIG_OF
589static const struct of_device_id samsung_keypad_dt_match[] = {
590 { .compatible = "samsung,s3c6410-keypad" },
591 { .compatible = "samsung,s5pv210-keypad" },
592 {},
593};
594MODULE_DEVICE_TABLE(of, samsung_keypad_dt_match);
595#else
596#define samsung_keypad_dt_match NULL
597#endif
598
450static struct platform_device_id samsung_keypad_driver_ids[] = { 599static struct platform_device_id samsung_keypad_driver_ids[] = {
451 { 600 {
452 .name = "samsung-keypad", 601 .name = "samsung-keypad",
@@ -465,6 +614,7 @@ static struct platform_driver samsung_keypad_driver = {
465 .driver = { 614 .driver = {
466 .name = "samsung-keypad", 615 .name = "samsung-keypad",
467 .owner = THIS_MODULE, 616 .owner = THIS_MODULE,
617 .of_match_table = samsung_keypad_dt_match,
468#ifdef CONFIG_PM 618#ifdef CONFIG_PM
469 .pm = &samsung_keypad_pm_ops, 619 .pm = &samsung_keypad_pm_ops,
470#endif 620#endif
diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c
index 5b979d9cc332..175067a17c46 100644
--- a/drivers/rtc/rtc-s3c.c
+++ b/drivers/rtc/rtc-s3c.c
@@ -25,6 +25,7 @@
25#include <linux/clk.h> 25#include <linux/clk.h>
26#include <linux/log2.h> 26#include <linux/log2.h>
27#include <linux/slab.h> 27#include <linux/slab.h>
28#include <linux/of.h>
28 29
29#include <mach/hardware.h> 30#include <mach/hardware.h>
30#include <asm/uaccess.h> 31#include <asm/uaccess.h>
@@ -507,7 +508,13 @@ static int __devinit s3c_rtc_probe(struct platform_device *pdev)
507 goto err_nortc; 508 goto err_nortc;
508 } 509 }
509 510
510 s3c_rtc_cpu_type = platform_get_device_id(pdev)->driver_data; 511#ifdef CONFIG_OF
512 if (pdev->dev.of_node)
513 s3c_rtc_cpu_type = of_device_is_compatible(pdev->dev.of_node,
514 "samsung,s3c6410-rtc") ? TYPE_S3C64XX : TYPE_S3C2410;
515 else
516#endif
517 s3c_rtc_cpu_type = platform_get_device_id(pdev)->driver_data;
511 518
512 /* Check RTC Time */ 519 /* Check RTC Time */
513 520
@@ -629,6 +636,17 @@ static int s3c_rtc_resume(struct platform_device *pdev)
629#define s3c_rtc_resume NULL 636#define s3c_rtc_resume NULL
630#endif 637#endif
631 638
639#ifdef CONFIG_OF
640static const struct of_device_id s3c_rtc_dt_match[] = {
641 { .compatible = "samsung,s3c2410-rtc" },
642 { .compatible = "samsung,s3c6410-rtc" },
643 {},
644};
645MODULE_DEVICE_TABLE(of, s3c_rtc_dt_match);
646#else
647#define s3c_rtc_dt_match NULL
648#endif
649
632static struct platform_device_id s3c_rtc_driver_ids[] = { 650static struct platform_device_id s3c_rtc_driver_ids[] = {
633 { 651 {
634 .name = "s3c2410-rtc", 652 .name = "s3c2410-rtc",
@@ -651,6 +669,7 @@ static struct platform_driver s3c_rtc_driver = {
651 .driver = { 669 .driver = {
652 .name = "s3c-rtc", 670 .name = "s3c-rtc",
653 .owner = THIS_MODULE, 671 .owner = THIS_MODULE,
672 .of_match_table = s3c_rtc_dt_match,
654 }, 673 },
655}; 674};
656 675
diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
index 925a1e547a83..fb89b85d0d81 100644
--- a/drivers/tty/serial/Kconfig
+++ b/drivers/tty/serial/Kconfig
@@ -457,7 +457,7 @@ config SERIAL_SAMSUNG
457config SERIAL_SAMSUNG_UARTS_4 457config SERIAL_SAMSUNG_UARTS_4
458 bool 458 bool
459 depends on ARM && PLAT_SAMSUNG 459 depends on ARM && PLAT_SAMSUNG
460 default y if CPU_S3C2443 460 default y if !(CPU_S3C2410 || SERIAL_S3C2412 || CPU_S3C2440 || CPU_S3C2442)
461 help 461 help
462 Internal node for the common case of 4 Samsung compatible UARTs 462 Internal node for the common case of 4 Samsung compatible UARTs
463 463
@@ -465,7 +465,7 @@ config SERIAL_SAMSUNG_UARTS
465 int 465 int
466 depends on ARM && PLAT_SAMSUNG 466 depends on ARM && PLAT_SAMSUNG
467 default 6 if ARCH_S5P6450 467 default 6 if ARCH_S5P6450
468 default 4 if SERIAL_SAMSUNG_UARTS_4 468 default 4 if SERIAL_SAMSUNG_UARTS_4 || CPU_S3C2416
469 default 3 469 default 3
470 help 470 help
471 Select the number of available UART ports for the Samsung S3C 471 Select the number of available UART ports for the Samsung S3C
@@ -495,47 +495,6 @@ config SERIAL_SAMSUNG_CONSOLE
495 your boot loader about how to pass options to the kernel at 495 your boot loader about how to pass options to the kernel at
496 boot time.) 496 boot time.)
497 497
498config SERIAL_S3C2410
499 tristate "Samsung S3C2410 Serial port support"
500 depends on SERIAL_SAMSUNG && CPU_S3C2410
501 default y if CPU_S3C2410
502 help
503 Serial port support for the Samsung S3C2410 SoC
504
505config SERIAL_S3C2412
506 tristate "Samsung S3C2412/S3C2413 Serial port support"
507 depends on SERIAL_SAMSUNG && CPU_S3C2412
508 default y if CPU_S3C2412
509 help
510 Serial port support for the Samsung S3C2412 and S3C2413 SoC
511
512config SERIAL_S3C2440
513 tristate "Samsung S3C2440/S3C2442/S3C2416 Serial port support"
514 depends on SERIAL_SAMSUNG && (CPU_S3C2440 || CPU_S3C2442 || CPU_S3C2416)
515 default y if CPU_S3C2440
516 default y if CPU_S3C2442
517 select SERIAL_SAMSUNG_UARTS_4 if CPU_S3C2416
518 help
519 Serial port support for the Samsung S3C2440, S3C2416 and S3C2442 SoC
520
521config SERIAL_S3C6400
522 tristate "Samsung S3C6400/S3C6410/S5P6440/S5P6450/S5PC100 Serial port support"
523 depends on SERIAL_SAMSUNG && (CPU_S3C6400 || CPU_S3C6410 || CPU_S5P6440 || CPU_S5P6450 || CPU_S5PC100)
524 select SERIAL_SAMSUNG_UARTS_4
525 default y
526 help
527 Serial port support for the Samsung S3C6400, S3C6410, S5P6440, S5P6450
528 and S5PC100 SoCs
529
530config SERIAL_S5PV210
531 tristate "Samsung S5PV210 Serial port support"
532 depends on SERIAL_SAMSUNG && (CPU_S5PV210 || CPU_EXYNOS4210 || SOC_EXYNOS4212)
533 select SERIAL_SAMSUNG_UARTS_4 if (CPU_S5PV210 || CPU_EXYNOS4210 || SOC_EXYNOS4212)
534 default y
535 help
536 Serial port support for Samsung's S5P Family of SoC's
537
538
539config SERIAL_MAX3100 498config SERIAL_MAX3100
540 tristate "MAX3100 support" 499 tristate "MAX3100 support"
541 depends on SPI 500 depends on SPI
diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile
index e10cf5b54b6d..84bc2e5a57be 100644
--- a/drivers/tty/serial/Makefile
+++ b/drivers/tty/serial/Makefile
@@ -39,11 +39,6 @@ obj-$(CONFIG_SERIAL_BCM63XX) += bcm63xx_uart.o
39obj-$(CONFIG_SERIAL_BFIN) += bfin_uart.o 39obj-$(CONFIG_SERIAL_BFIN) += bfin_uart.o
40obj-$(CONFIG_SERIAL_BFIN_SPORT) += bfin_sport_uart.o 40obj-$(CONFIG_SERIAL_BFIN_SPORT) += bfin_sport_uart.o
41obj-$(CONFIG_SERIAL_SAMSUNG) += samsung.o 41obj-$(CONFIG_SERIAL_SAMSUNG) += samsung.o
42obj-$(CONFIG_SERIAL_S3C2410) += s3c2410.o
43obj-$(CONFIG_SERIAL_S3C2412) += s3c2412.o
44obj-$(CONFIG_SERIAL_S3C2440) += s3c2440.o
45obj-$(CONFIG_SERIAL_S3C6400) += s3c6400.o
46obj-$(CONFIG_SERIAL_S5PV210) += s5pv210.o
47obj-$(CONFIG_SERIAL_MAX3100) += max3100.o 42obj-$(CONFIG_SERIAL_MAX3100) += max3100.o
48obj-$(CONFIG_SERIAL_MAX3107) += max3107.o 43obj-$(CONFIG_SERIAL_MAX3107) += max3107.o
49obj-$(CONFIG_SERIAL_MAX3107_AAVA) += max3107-aava.o 44obj-$(CONFIG_SERIAL_MAX3107_AAVA) += max3107-aava.o
diff --git a/drivers/tty/serial/s3c2410.c b/drivers/tty/serial/s3c2410.c
deleted file mode 100644
index b1d7e7c1849d..000000000000
--- a/drivers/tty/serial/s3c2410.c
+++ /dev/null
@@ -1,115 +0,0 @@
1/*
2 * Driver for Samsung S3C2410 SoC onboard UARTs.
3 *
4 * Ben Dooks, Copyright (c) 2003-2008 Simtec Electronics
5 * http://armlinux.simtec.co.uk/
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/module.h>
13#include <linux/ioport.h>
14#include <linux/io.h>
15#include <linux/platform_device.h>
16#include <linux/init.h>
17#include <linux/serial_core.h>
18#include <linux/serial.h>
19
20#include <asm/irq.h>
21#include <mach/hardware.h>
22
23#include <plat/regs-serial.h>
24#include <mach/regs-gpio.h>
25
26#include "samsung.h"
27
28static int s3c2410_serial_setsource(struct uart_port *port,
29 struct s3c24xx_uart_clksrc *clk)
30{
31 unsigned long ucon = rd_regl(port, S3C2410_UCON);
32
33 if (strcmp(clk->name, "uclk") == 0)
34 ucon |= S3C2410_UCON_UCLK;
35 else
36 ucon &= ~S3C2410_UCON_UCLK;
37
38 wr_regl(port, S3C2410_UCON, ucon);
39 return 0;
40}
41
42static int s3c2410_serial_getsource(struct uart_port *port,
43 struct s3c24xx_uart_clksrc *clk)
44{
45 unsigned long ucon = rd_regl(port, S3C2410_UCON);
46
47 clk->divisor = 1;
48 clk->name = (ucon & S3C2410_UCON_UCLK) ? "uclk" : "pclk";
49
50 return 0;
51}
52
53static int s3c2410_serial_resetport(struct uart_port *port,
54 struct s3c2410_uartcfg *cfg)
55{
56 dbg("s3c2410_serial_resetport: port=%p (%08lx), cfg=%p\n",
57 port, port->mapbase, cfg);
58
59 wr_regl(port, S3C2410_UCON, cfg->ucon);
60 wr_regl(port, S3C2410_ULCON, cfg->ulcon);
61
62 /* reset both fifos */
63
64 wr_regl(port, S3C2410_UFCON, cfg->ufcon | S3C2410_UFCON_RESETBOTH);
65 wr_regl(port, S3C2410_UFCON, cfg->ufcon);
66
67 return 0;
68}
69
70static struct s3c24xx_uart_info s3c2410_uart_inf = {
71 .name = "Samsung S3C2410 UART",
72 .type = PORT_S3C2410,
73 .fifosize = 16,
74 .rx_fifomask = S3C2410_UFSTAT_RXMASK,
75 .rx_fifoshift = S3C2410_UFSTAT_RXSHIFT,
76 .rx_fifofull = S3C2410_UFSTAT_RXFULL,
77 .tx_fifofull = S3C2410_UFSTAT_TXFULL,
78 .tx_fifomask = S3C2410_UFSTAT_TXMASK,
79 .tx_fifoshift = S3C2410_UFSTAT_TXSHIFT,
80 .get_clksrc = s3c2410_serial_getsource,
81 .set_clksrc = s3c2410_serial_setsource,
82 .reset_port = s3c2410_serial_resetport,
83};
84
85static int s3c2410_serial_probe(struct platform_device *dev)
86{
87 return s3c24xx_serial_probe(dev, &s3c2410_uart_inf);
88}
89
90static struct platform_driver s3c2410_serial_driver = {
91 .probe = s3c2410_serial_probe,
92 .remove = __devexit_p(s3c24xx_serial_remove),
93 .driver = {
94 .name = "s3c2410-uart",
95 .owner = THIS_MODULE,
96 },
97};
98
99static int __init s3c2410_serial_init(void)
100{
101 return s3c24xx_serial_init(&s3c2410_serial_driver, &s3c2410_uart_inf);
102}
103
104static void __exit s3c2410_serial_exit(void)
105{
106 platform_driver_unregister(&s3c2410_serial_driver);
107}
108
109module_init(s3c2410_serial_init);
110module_exit(s3c2410_serial_exit);
111
112MODULE_LICENSE("GPL v2");
113MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
114MODULE_DESCRIPTION("Samsung S3C2410 SoC Serial port driver");
115MODULE_ALIAS("platform:s3c2410-uart");
diff --git a/drivers/tty/serial/s3c2412.c b/drivers/tty/serial/s3c2412.c
deleted file mode 100644
index 2234bf9ced45..000000000000
--- a/drivers/tty/serial/s3c2412.c
+++ /dev/null
@@ -1,149 +0,0 @@
1/*
2 * Driver for Samsung S3C2412 and S3C2413 SoC onboard UARTs.
3 *
4 * Ben Dooks, Copyright (c) 2003-2008 Simtec Electronics
5 * http://armlinux.simtec.co.uk/
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/module.h>
13#include <linux/ioport.h>
14#include <linux/io.h>
15#include <linux/platform_device.h>
16#include <linux/init.h>
17#include <linux/serial_core.h>
18#include <linux/serial.h>
19
20#include <asm/irq.h>
21#include <mach/hardware.h>
22
23#include <plat/regs-serial.h>
24#include <mach/regs-gpio.h>
25
26#include "samsung.h"
27
28static int s3c2412_serial_setsource(struct uart_port *port,
29 struct s3c24xx_uart_clksrc *clk)
30{
31 unsigned long ucon = rd_regl(port, S3C2410_UCON);
32
33 ucon &= ~S3C2412_UCON_CLKMASK;
34
35 if (strcmp(clk->name, "uclk") == 0)
36 ucon |= S3C2440_UCON_UCLK;
37 else if (strcmp(clk->name, "pclk") == 0)
38 ucon |= S3C2440_UCON_PCLK;
39 else if (strcmp(clk->name, "usysclk") == 0)
40 ucon |= S3C2412_UCON_USYSCLK;
41 else {
42 printk(KERN_ERR "unknown clock source %s\n", clk->name);
43 return -EINVAL;
44 }
45
46 wr_regl(port, S3C2410_UCON, ucon);
47 return 0;
48}
49
50
51static int s3c2412_serial_getsource(struct uart_port *port,
52 struct s3c24xx_uart_clksrc *clk)
53{
54 unsigned long ucon = rd_regl(port, S3C2410_UCON);
55
56 switch (ucon & S3C2412_UCON_CLKMASK) {
57 case S3C2412_UCON_UCLK:
58 clk->divisor = 1;
59 clk->name = "uclk";
60 break;
61
62 case S3C2412_UCON_PCLK:
63 case S3C2412_UCON_PCLK2:
64 clk->divisor = 1;
65 clk->name = "pclk";
66 break;
67
68 case S3C2412_UCON_USYSCLK:
69 clk->divisor = 1;
70 clk->name = "usysclk";
71 break;
72 }
73
74 return 0;
75}
76
77static int s3c2412_serial_resetport(struct uart_port *port,
78 struct s3c2410_uartcfg *cfg)
79{
80 unsigned long ucon = rd_regl(port, S3C2410_UCON);
81
82 dbg("%s: port=%p (%08lx), cfg=%p\n",
83 __func__, port, port->mapbase, cfg);
84
85 /* ensure we don't change the clock settings... */
86
87 ucon &= S3C2412_UCON_CLKMASK;
88
89 wr_regl(port, S3C2410_UCON, ucon | cfg->ucon);
90 wr_regl(port, S3C2410_ULCON, cfg->ulcon);
91
92 /* reset both fifos */
93
94 wr_regl(port, S3C2410_UFCON, cfg->ufcon | S3C2410_UFCON_RESETBOTH);
95 wr_regl(port, S3C2410_UFCON, cfg->ufcon);
96
97 return 0;
98}
99
100static struct s3c24xx_uart_info s3c2412_uart_inf = {
101 .name = "Samsung S3C2412 UART",
102 .type = PORT_S3C2412,
103 .fifosize = 64,
104 .has_divslot = 1,
105 .rx_fifomask = S3C2440_UFSTAT_RXMASK,
106 .rx_fifoshift = S3C2440_UFSTAT_RXSHIFT,
107 .rx_fifofull = S3C2440_UFSTAT_RXFULL,
108 .tx_fifofull = S3C2440_UFSTAT_TXFULL,
109 .tx_fifomask = S3C2440_UFSTAT_TXMASK,
110 .tx_fifoshift = S3C2440_UFSTAT_TXSHIFT,
111 .get_clksrc = s3c2412_serial_getsource,
112 .set_clksrc = s3c2412_serial_setsource,
113 .reset_port = s3c2412_serial_resetport,
114};
115
116/* device management */
117
118static int s3c2412_serial_probe(struct platform_device *dev)
119{
120 dbg("s3c2440_serial_probe: dev=%p\n", dev);
121 return s3c24xx_serial_probe(dev, &s3c2412_uart_inf);
122}
123
124static struct platform_driver s3c2412_serial_driver = {
125 .probe = s3c2412_serial_probe,
126 .remove = __devexit_p(s3c24xx_serial_remove),
127 .driver = {
128 .name = "s3c2412-uart",
129 .owner = THIS_MODULE,
130 },
131};
132
133static inline int s3c2412_serial_init(void)
134{
135 return s3c24xx_serial_init(&s3c2412_serial_driver, &s3c2412_uart_inf);
136}
137
138static inline void s3c2412_serial_exit(void)
139{
140 platform_driver_unregister(&s3c2412_serial_driver);
141}
142
143module_init(s3c2412_serial_init);
144module_exit(s3c2412_serial_exit);
145
146MODULE_DESCRIPTION("Samsung S3C2412,S3C2413 SoC Serial port driver");
147MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
148MODULE_LICENSE("GPL v2");
149MODULE_ALIAS("platform:s3c2412-uart");
diff --git a/drivers/tty/serial/s3c2440.c b/drivers/tty/serial/s3c2440.c
deleted file mode 100644
index 1d0c324b813f..000000000000
--- a/drivers/tty/serial/s3c2440.c
+++ /dev/null
@@ -1,178 +0,0 @@
1/*
2 * Driver for Samsung S3C2440 and S3C2442 SoC onboard UARTs.
3 *
4 * Ben Dooks, Copyright (c) 2003-2008 Simtec Electronics
5 * http://armlinux.simtec.co.uk/
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/module.h>
13#include <linux/ioport.h>
14#include <linux/io.h>
15#include <linux/platform_device.h>
16#include <linux/init.h>
17#include <linux/serial_core.h>
18#include <linux/serial.h>
19
20#include <asm/irq.h>
21#include <mach/hardware.h>
22
23#include <plat/regs-serial.h>
24#include <mach/regs-gpio.h>
25
26#include "samsung.h"
27
28
29static int s3c2440_serial_setsource(struct uart_port *port,
30 struct s3c24xx_uart_clksrc *clk)
31{
32 unsigned long ucon = rd_regl(port, S3C2410_UCON);
33
34 /* todo - proper fclk<>nonfclk switch. */
35
36 ucon &= ~S3C2440_UCON_CLKMASK;
37
38 if (strcmp(clk->name, "uclk") == 0)
39 ucon |= S3C2440_UCON_UCLK;
40 else if (strcmp(clk->name, "pclk") == 0)
41 ucon |= S3C2440_UCON_PCLK;
42 else if (strcmp(clk->name, "fclk") == 0)
43 ucon |= S3C2440_UCON_FCLK;
44 else {
45 printk(KERN_ERR "unknown clock source %s\n", clk->name);
46 return -EINVAL;
47 }
48
49 wr_regl(port, S3C2410_UCON, ucon);
50 return 0;
51}
52
53
54static int s3c2440_serial_getsource(struct uart_port *port,
55 struct s3c24xx_uart_clksrc *clk)
56{
57 unsigned long ucon = rd_regl(port, S3C2410_UCON);
58 unsigned long ucon0, ucon1, ucon2;
59
60 switch (ucon & S3C2440_UCON_CLKMASK) {
61 case S3C2440_UCON_UCLK:
62 clk->divisor = 1;
63 clk->name = "uclk";
64 break;
65
66 case S3C2440_UCON_PCLK:
67 case S3C2440_UCON_PCLK2:
68 clk->divisor = 1;
69 clk->name = "pclk";
70 break;
71
72 case S3C2440_UCON_FCLK:
73 /* the fun of calculating the uart divisors on
74 * the s3c2440 */
75
76 ucon0 = __raw_readl(S3C24XX_VA_UART0 + S3C2410_UCON);
77 ucon1 = __raw_readl(S3C24XX_VA_UART1 + S3C2410_UCON);
78 ucon2 = __raw_readl(S3C24XX_VA_UART2 + S3C2410_UCON);
79
80 printk("ucons: %08lx, %08lx, %08lx\n", ucon0, ucon1, ucon2);
81
82 ucon0 &= S3C2440_UCON0_DIVMASK;
83 ucon1 &= S3C2440_UCON1_DIVMASK;
84 ucon2 &= S3C2440_UCON2_DIVMASK;
85
86 if (ucon0 != 0) {
87 clk->divisor = ucon0 >> S3C2440_UCON_DIVSHIFT;
88 clk->divisor += 6;
89 } else if (ucon1 != 0) {
90 clk->divisor = ucon1 >> S3C2440_UCON_DIVSHIFT;
91 clk->divisor += 21;
92 } else if (ucon2 != 0) {
93 clk->divisor = ucon2 >> S3C2440_UCON_DIVSHIFT;
94 clk->divisor += 36;
95 } else {
96 /* manual calims 44, seems to be 9 */
97 clk->divisor = 9;
98 }
99
100 clk->name = "fclk";
101 break;
102 }
103
104 return 0;
105}
106
107static int s3c2440_serial_resetport(struct uart_port *port,
108 struct s3c2410_uartcfg *cfg)
109{
110 unsigned long ucon = rd_regl(port, S3C2410_UCON);
111
112 dbg("s3c2440_serial_resetport: port=%p (%08lx), cfg=%p\n",
113 port, port->mapbase, cfg);
114
115 /* ensure we don't change the clock settings... */
116
117 ucon &= (S3C2440_UCON0_DIVMASK | (3<<10));
118
119 wr_regl(port, S3C2410_UCON, ucon | cfg->ucon);
120 wr_regl(port, S3C2410_ULCON, cfg->ulcon);
121
122 /* reset both fifos */
123
124 wr_regl(port, S3C2410_UFCON, cfg->ufcon | S3C2410_UFCON_RESETBOTH);
125 wr_regl(port, S3C2410_UFCON, cfg->ufcon);
126
127 return 0;
128}
129
130static struct s3c24xx_uart_info s3c2440_uart_inf = {
131 .name = "Samsung S3C2440 UART",
132 .type = PORT_S3C2440,
133 .fifosize = 64,
134 .rx_fifomask = S3C2440_UFSTAT_RXMASK,
135 .rx_fifoshift = S3C2440_UFSTAT_RXSHIFT,
136 .rx_fifofull = S3C2440_UFSTAT_RXFULL,
137 .tx_fifofull = S3C2440_UFSTAT_TXFULL,
138 .tx_fifomask = S3C2440_UFSTAT_TXMASK,
139 .tx_fifoshift = S3C2440_UFSTAT_TXSHIFT,
140 .get_clksrc = s3c2440_serial_getsource,
141 .set_clksrc = s3c2440_serial_setsource,
142 .reset_port = s3c2440_serial_resetport,
143};
144
145/* device management */
146
147static int s3c2440_serial_probe(struct platform_device *dev)
148{
149 dbg("s3c2440_serial_probe: dev=%p\n", dev);
150 return s3c24xx_serial_probe(dev, &s3c2440_uart_inf);
151}
152
153static struct platform_driver s3c2440_serial_driver = {
154 .probe = s3c2440_serial_probe,
155 .remove = __devexit_p(s3c24xx_serial_remove),
156 .driver = {
157 .name = "s3c2440-uart",
158 .owner = THIS_MODULE,
159 },
160};
161
162static int __init s3c2440_serial_init(void)
163{
164 return s3c24xx_serial_init(&s3c2440_serial_driver, &s3c2440_uart_inf);
165}
166
167static void __exit s3c2440_serial_exit(void)
168{
169 platform_driver_unregister(&s3c2440_serial_driver);
170}
171
172module_init(s3c2440_serial_init);
173module_exit(s3c2440_serial_exit);
174
175MODULE_DESCRIPTION("Samsung S3C2440,S3C2442 SoC Serial port driver");
176MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
177MODULE_LICENSE("GPL v2");
178MODULE_ALIAS("platform:s3c2440-uart");
diff --git a/drivers/tty/serial/s3c6400.c b/drivers/tty/serial/s3c6400.c
deleted file mode 100644
index e2f6913d84d5..000000000000
--- a/drivers/tty/serial/s3c6400.c
+++ /dev/null
@@ -1,149 +0,0 @@
1/*
2 * Driver for Samsung S3C6400 and S3C6410 SoC onboard UARTs.
3 *
4 * Copyright 2008 Openmoko, Inc.
5 * Copyright 2008 Simtec Electronics
6 * Ben Dooks <ben@simtec.co.uk>
7 * http://armlinux.simtec.co.uk/
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12*/
13
14#include <linux/module.h>
15#include <linux/ioport.h>
16#include <linux/io.h>
17#include <linux/platform_device.h>
18#include <linux/init.h>
19#include <linux/serial_core.h>
20#include <linux/serial.h>
21
22#include <asm/irq.h>
23#include <mach/hardware.h>
24
25#include <plat/regs-serial.h>
26
27#include "samsung.h"
28
29static int s3c6400_serial_setsource(struct uart_port *port,
30 struct s3c24xx_uart_clksrc *clk)
31{
32 unsigned long ucon = rd_regl(port, S3C2410_UCON);
33
34 if (strcmp(clk->name, "uclk0") == 0) {
35 ucon &= ~S3C6400_UCON_CLKMASK;
36 ucon |= S3C6400_UCON_UCLK0;
37 } else if (strcmp(clk->name, "uclk1") == 0)
38 ucon |= S3C6400_UCON_UCLK1;
39 else if (strcmp(clk->name, "pclk") == 0) {
40 /* See notes about transitioning from UCLK to PCLK */
41 ucon &= ~S3C6400_UCON_UCLK0;
42 } else {
43 printk(KERN_ERR "unknown clock source %s\n", clk->name);
44 return -EINVAL;
45 }
46
47 wr_regl(port, S3C2410_UCON, ucon);
48 return 0;
49}
50
51
52static int s3c6400_serial_getsource(struct uart_port *port,
53 struct s3c24xx_uart_clksrc *clk)
54{
55 u32 ucon = rd_regl(port, S3C2410_UCON);
56
57 clk->divisor = 1;
58
59 switch (ucon & S3C6400_UCON_CLKMASK) {
60 case S3C6400_UCON_UCLK0:
61 clk->name = "uclk0";
62 break;
63
64 case S3C6400_UCON_UCLK1:
65 clk->name = "uclk1";
66 break;
67
68 case S3C6400_UCON_PCLK:
69 case S3C6400_UCON_PCLK2:
70 clk->name = "pclk";
71 break;
72 }
73
74 return 0;
75}
76
77static int s3c6400_serial_resetport(struct uart_port *port,
78 struct s3c2410_uartcfg *cfg)
79{
80 unsigned long ucon = rd_regl(port, S3C2410_UCON);
81
82 dbg("s3c6400_serial_resetport: port=%p (%08lx), cfg=%p\n",
83 port, port->mapbase, cfg);
84
85 /* ensure we don't change the clock settings... */
86
87 ucon &= S3C6400_UCON_CLKMASK;
88
89 wr_regl(port, S3C2410_UCON, ucon | cfg->ucon);
90 wr_regl(port, S3C2410_ULCON, cfg->ulcon);
91
92 /* reset both fifos */
93
94 wr_regl(port, S3C2410_UFCON, cfg->ufcon | S3C2410_UFCON_RESETBOTH);
95 wr_regl(port, S3C2410_UFCON, cfg->ufcon);
96
97 return 0;
98}
99
100static struct s3c24xx_uart_info s3c6400_uart_inf = {
101 .name = "Samsung S3C6400 UART",
102 .type = PORT_S3C6400,
103 .fifosize = 64,
104 .has_divslot = 1,
105 .rx_fifomask = S3C2440_UFSTAT_RXMASK,
106 .rx_fifoshift = S3C2440_UFSTAT_RXSHIFT,
107 .rx_fifofull = S3C2440_UFSTAT_RXFULL,
108 .tx_fifofull = S3C2440_UFSTAT_TXFULL,
109 .tx_fifomask = S3C2440_UFSTAT_TXMASK,
110 .tx_fifoshift = S3C2440_UFSTAT_TXSHIFT,
111 .get_clksrc = s3c6400_serial_getsource,
112 .set_clksrc = s3c6400_serial_setsource,
113 .reset_port = s3c6400_serial_resetport,
114};
115
116/* device management */
117
118static int s3c6400_serial_probe(struct platform_device *dev)
119{
120 dbg("s3c6400_serial_probe: dev=%p\n", dev);
121 return s3c24xx_serial_probe(dev, &s3c6400_uart_inf);
122}
123
124static struct platform_driver s3c6400_serial_driver = {
125 .probe = s3c6400_serial_probe,
126 .remove = __devexit_p(s3c24xx_serial_remove),
127 .driver = {
128 .name = "s3c6400-uart",
129 .owner = THIS_MODULE,
130 },
131};
132
133static int __init s3c6400_serial_init(void)
134{
135 return s3c24xx_serial_init(&s3c6400_serial_driver, &s3c6400_uart_inf);
136}
137
138static void __exit s3c6400_serial_exit(void)
139{
140 platform_driver_unregister(&s3c6400_serial_driver);
141}
142
143module_init(s3c6400_serial_init);
144module_exit(s3c6400_serial_exit);
145
146MODULE_DESCRIPTION("Samsung S3C6400,S3C6410 SoC Serial port driver");
147MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
148MODULE_LICENSE("GPL v2");
149MODULE_ALIAS("platform:s3c6400-uart");
diff --git a/drivers/tty/serial/s5pv210.c b/drivers/tty/serial/s5pv210.c
deleted file mode 100644
index 8b0b888a1b76..000000000000
--- a/drivers/tty/serial/s5pv210.c
+++ /dev/null
@@ -1,158 +0,0 @@
1/*
2 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
3 * http://www.samsung.com/
4 *
5 * Based on drivers/serial/s3c6400.c
6 *
7 * Driver for Samsung S5PV210 SoC UARTs.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12*/
13
14#include <linux/module.h>
15#include <linux/ioport.h>
16#include <linux/io.h>
17#include <linux/platform_device.h>
18#include <linux/init.h>
19#include <linux/serial_core.h>
20#include <linux/serial.h>
21#include <linux/delay.h>
22
23#include <asm/irq.h>
24#include <mach/hardware.h>
25#include <plat/regs-serial.h>
26#include "samsung.h"
27
28static int s5pv210_serial_setsource(struct uart_port *port,
29 struct s3c24xx_uart_clksrc *clk)
30{
31 struct s3c2410_uartcfg *cfg = port->dev->platform_data;
32 unsigned long ucon = rd_regl(port, S3C2410_UCON);
33
34 if (cfg->flags & NO_NEED_CHECK_CLKSRC)
35 return 0;
36
37 if (strcmp(clk->name, "pclk") == 0)
38 ucon &= ~S5PV210_UCON_CLKMASK;
39 else if (strcmp(clk->name, "uclk1") == 0)
40 ucon |= S5PV210_UCON_CLKMASK;
41 else {
42 printk(KERN_ERR "unknown clock source %s\n", clk->name);
43 return -EINVAL;
44 }
45
46 wr_regl(port, S3C2410_UCON, ucon);
47 return 0;
48}
49
50
51static int s5pv210_serial_getsource(struct uart_port *port,
52 struct s3c24xx_uart_clksrc *clk)
53{
54 struct s3c2410_uartcfg *cfg = port->dev->platform_data;
55 u32 ucon = rd_regl(port, S3C2410_UCON);
56
57 clk->divisor = 1;
58
59 if (cfg->flags & NO_NEED_CHECK_CLKSRC)
60 return 0;
61
62 switch (ucon & S5PV210_UCON_CLKMASK) {
63 case S5PV210_UCON_PCLK:
64 clk->name = "pclk";
65 break;
66 case S5PV210_UCON_UCLK:
67 clk->name = "uclk1";
68 break;
69 }
70
71 return 0;
72}
73
74static int s5pv210_serial_resetport(struct uart_port *port,
75 struct s3c2410_uartcfg *cfg)
76{
77 unsigned long ucon = rd_regl(port, S3C2410_UCON);
78
79 ucon &= S5PV210_UCON_CLKMASK;
80 wr_regl(port, S3C2410_UCON, ucon | cfg->ucon);
81 wr_regl(port, S3C2410_ULCON, cfg->ulcon);
82
83 /* reset both fifos */
84 wr_regl(port, S3C2410_UFCON, cfg->ufcon | S3C2410_UFCON_RESETBOTH);
85 wr_regl(port, S3C2410_UFCON, cfg->ufcon);
86
87 /* It is need to delay When reset FIFO register */
88 udelay(1);
89
90 return 0;
91}
92
93#define S5PV210_UART_DEFAULT_INFO(fifo_size) \
94 .name = "Samsung S5PV210 UART0", \
95 .type = PORT_S3C6400, \
96 .fifosize = fifo_size, \
97 .has_divslot = 1, \
98 .rx_fifomask = S5PV210_UFSTAT_RXMASK, \
99 .rx_fifoshift = S5PV210_UFSTAT_RXSHIFT, \
100 .rx_fifofull = S5PV210_UFSTAT_RXFULL, \
101 .tx_fifofull = S5PV210_UFSTAT_TXFULL, \
102 .tx_fifomask = S5PV210_UFSTAT_TXMASK, \
103 .tx_fifoshift = S5PV210_UFSTAT_TXSHIFT, \
104 .get_clksrc = s5pv210_serial_getsource, \
105 .set_clksrc = s5pv210_serial_setsource, \
106 .reset_port = s5pv210_serial_resetport
107
108static struct s3c24xx_uart_info s5p_port_fifo256 = {
109 S5PV210_UART_DEFAULT_INFO(256),
110};
111
112static struct s3c24xx_uart_info s5p_port_fifo64 = {
113 S5PV210_UART_DEFAULT_INFO(64),
114};
115
116static struct s3c24xx_uart_info s5p_port_fifo16 = {
117 S5PV210_UART_DEFAULT_INFO(16),
118};
119
120static struct s3c24xx_uart_info *s5p_uart_inf[] = {
121 [0] = &s5p_port_fifo256,
122 [1] = &s5p_port_fifo64,
123 [2] = &s5p_port_fifo16,
124 [3] = &s5p_port_fifo16,
125};
126
127/* device management */
128static int s5p_serial_probe(struct platform_device *pdev)
129{
130 return s3c24xx_serial_probe(pdev, s5p_uart_inf[pdev->id]);
131}
132
133static struct platform_driver s5p_serial_driver = {
134 .probe = s5p_serial_probe,
135 .remove = __devexit_p(s3c24xx_serial_remove),
136 .driver = {
137 .name = "s5pv210-uart",
138 .owner = THIS_MODULE,
139 },
140};
141
142static int __init s5p_serial_init(void)
143{
144 return s3c24xx_serial_init(&s5p_serial_driver, *s5p_uart_inf);
145}
146
147static void __exit s5p_serial_exit(void)
148{
149 platform_driver_unregister(&s5p_serial_driver);
150}
151
152module_init(s5p_serial_init);
153module_exit(s5p_serial_exit);
154
155MODULE_LICENSE("GPL");
156MODULE_ALIAS("platform:s5pv210-uart");
157MODULE_DESCRIPTION("Samsung S5PV210 UART Driver support");
158MODULE_AUTHOR("Thomas Abraham <thomas.ab@samsung.com>");
diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c
index b31f1c3a2c4c..f96f37b5fec6 100644
--- a/drivers/tty/serial/samsung.c
+++ b/drivers/tty/serial/samsung.c
@@ -42,6 +42,7 @@
42#include <linux/delay.h> 42#include <linux/delay.h>
43#include <linux/clk.h> 43#include <linux/clk.h>
44#include <linux/cpufreq.h> 44#include <linux/cpufreq.h>
45#include <linux/of.h>
45 46
46#include <asm/irq.h> 47#include <asm/irq.h>
47 48
@@ -49,6 +50,7 @@
49#include <mach/map.h> 50#include <mach/map.h>
50 51
51#include <plat/regs-serial.h> 52#include <plat/regs-serial.h>
53#include <plat/clock.h>
52 54
53#include "samsung.h" 55#include "samsung.h"
54 56
@@ -190,10 +192,13 @@ static inline struct s3c24xx_uart_info *s3c24xx_port_to_info(struct uart_port *p
190 192
191static inline struct s3c2410_uartcfg *s3c24xx_port_to_cfg(struct uart_port *port) 193static inline struct s3c2410_uartcfg *s3c24xx_port_to_cfg(struct uart_port *port)
192{ 194{
195 struct s3c24xx_uart_port *ourport;
196
193 if (port->dev == NULL) 197 if (port->dev == NULL)
194 return NULL; 198 return NULL;
195 199
196 return (struct s3c2410_uartcfg *)port->dev->platform_data; 200 ourport = container_of(port, struct s3c24xx_uart_port, port);
201 return ourport->cfg;
197} 202}
198 203
199static int s3c24xx_serial_rx_fifocnt(struct s3c24xx_uart_port *ourport, 204static int s3c24xx_serial_rx_fifocnt(struct s3c24xx_uart_port *ourport,
@@ -202,7 +207,7 @@ static int s3c24xx_serial_rx_fifocnt(struct s3c24xx_uart_port *ourport,
202 struct s3c24xx_uart_info *info = ourport->info; 207 struct s3c24xx_uart_info *info = ourport->info;
203 208
204 if (ufstat & info->rx_fifofull) 209 if (ufstat & info->rx_fifofull)
205 return info->fifosize; 210 return ourport->port.fifosize;
206 211
207 return (ufstat & info->rx_fifomask) >> info->rx_fifoshift; 212 return (ufstat & info->rx_fifomask) >> info->rx_fifoshift;
208} 213}
@@ -555,154 +560,98 @@ static void s3c24xx_serial_pm(struct uart_port *port, unsigned int level,
555 * 560 *
556*/ 561*/
557 562
563#define MAX_CLK_NAME_LENGTH 15
558 564
559#define MAX_CLKS (8) 565static inline int s3c24xx_serial_getsource(struct uart_port *port)
560
561static struct s3c24xx_uart_clksrc tmp_clksrc = {
562 .name = "pclk",
563 .min_baud = 0,
564 .max_baud = 0,
565 .divisor = 1,
566};
567
568static inline int
569s3c24xx_serial_getsource(struct uart_port *port, struct s3c24xx_uart_clksrc *c)
570{ 566{
571 struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port); 567 struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
568 unsigned int ucon;
572 569
573 return (info->get_clksrc)(port, c); 570 if (info->num_clks == 1)
574} 571 return 0;
575
576static inline int
577s3c24xx_serial_setsource(struct uart_port *port, struct s3c24xx_uart_clksrc *c)
578{
579 struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
580 572
581 return (info->set_clksrc)(port, c); 573 ucon = rd_regl(port, S3C2410_UCON);
574 ucon &= info->clksel_mask;
575 return ucon >> info->clksel_shift;
582} 576}
583 577
584struct baud_calc { 578static void s3c24xx_serial_setsource(struct uart_port *port,
585 struct s3c24xx_uart_clksrc *clksrc; 579 unsigned int clk_sel)
586 unsigned int calc;
587 unsigned int divslot;
588 unsigned int quot;
589 struct clk *src;
590};
591
592static int s3c24xx_serial_calcbaud(struct baud_calc *calc,
593 struct uart_port *port,
594 struct s3c24xx_uart_clksrc *clksrc,
595 unsigned int baud)
596{ 580{
597 struct s3c24xx_uart_port *ourport = to_ourport(port); 581 struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
598 unsigned long rate; 582 unsigned int ucon;
599
600 calc->src = clk_get(port->dev, clksrc->name);
601 if (calc->src == NULL || IS_ERR(calc->src))
602 return 0;
603
604 rate = clk_get_rate(calc->src);
605 rate /= clksrc->divisor;
606 583
607 calc->clksrc = clksrc; 584 if (info->num_clks == 1)
585 return;
608 586
609 if (ourport->info->has_divslot) { 587 ucon = rd_regl(port, S3C2410_UCON);
610 unsigned long div = rate / baud; 588 if ((ucon & info->clksel_mask) >> info->clksel_shift == clk_sel)
611 589 return;
612 /* The UDIVSLOT register on the newer UARTs allows us to
613 * get a divisor adjustment of 1/16th on the baud clock.
614 *
615 * We don't keep the UDIVSLOT value (the 16ths we calculated
616 * by not multiplying the baud by 16) as it is easy enough
617 * to recalculate.
618 */
619
620 calc->quot = div / 16;
621 calc->calc = rate / div;
622 } else {
623 calc->quot = (rate + (8 * baud)) / (16 * baud);
624 calc->calc = (rate / (calc->quot * 16));
625 }
626 590
627 calc->quot--; 591 ucon &= ~info->clksel_mask;
628 return 1; 592 ucon |= clk_sel << info->clksel_shift;
593 wr_regl(port, S3C2410_UCON, ucon);
629} 594}
630 595
631static unsigned int s3c24xx_serial_getclk(struct uart_port *port, 596static unsigned int s3c24xx_serial_getclk(struct s3c24xx_uart_port *ourport,
632 struct s3c24xx_uart_clksrc **clksrc, 597 unsigned int req_baud, struct clk **best_clk,
633 struct clk **clk, 598 unsigned int *clk_num)
634 unsigned int baud)
635{ 599{
636 struct s3c2410_uartcfg *cfg = s3c24xx_port_to_cfg(port); 600 struct s3c24xx_uart_info *info = ourport->info;
637 struct s3c24xx_uart_clksrc *clkp; 601 struct clk *clk;
638 struct baud_calc res[MAX_CLKS]; 602 unsigned long rate;
639 struct baud_calc *resptr, *best, *sptr; 603 unsigned int cnt, baud, quot, clk_sel, best_quot = 0;
640 int i; 604 char clkname[MAX_CLK_NAME_LENGTH];
641 605 int calc_deviation, deviation = (1 << 30) - 1;
642 clkp = cfg->clocks; 606
643 best = NULL; 607 *best_clk = NULL;
644 608 clk_sel = (ourport->cfg->clk_sel) ? ourport->cfg->clk_sel :
645 if (cfg->clocks_size < 2) { 609 ourport->info->def_clk_sel;
646 if (cfg->clocks_size == 0) 610 for (cnt = 0; cnt < info->num_clks; cnt++) {
647 clkp = &tmp_clksrc; 611 if (!(clk_sel & (1 << cnt)))
648 612 continue;
649 /* check to see if we're sourcing fclk, and if so we're 613
650 * going to have to update the clock source 614 sprintf(clkname, "clk_uart_baud%d", cnt);
651 */ 615 clk = clk_get(ourport->port.dev, clkname);
652 616 if (IS_ERR_OR_NULL(clk))
653 if (strcmp(clkp->name, "fclk") == 0) { 617 continue;
654 struct s3c24xx_uart_clksrc src; 618
655 619 rate = clk_get_rate(clk);
656 s3c24xx_serial_getsource(port, &src); 620 if (!rate)
657 621 continue;
658 /* check that the port already using fclk, and if 622
659 * not, then re-select fclk 623 if (ourport->info->has_divslot) {
624 unsigned long div = rate / req_baud;
625
626 /* The UDIVSLOT register on the newer UARTs allows us to
627 * get a divisor adjustment of 1/16th on the baud clock.
628 *
629 * We don't keep the UDIVSLOT value (the 16ths we
630 * calculated by not multiplying the baud by 16) as it
631 * is easy enough to recalculate.
660 */ 632 */
661 633
662 if (strcmp(src.name, clkp->name) == 0) { 634 quot = div / 16;
663 s3c24xx_serial_setsource(port, clkp); 635 baud = rate / div;
664 s3c24xx_serial_getsource(port, &src); 636 } else {
665 } 637 quot = (rate + (8 * req_baud)) / (16 * req_baud);
666 638 baud = rate / (quot * 16);
667 clkp->divisor = src.divisor;
668 }
669
670 s3c24xx_serial_calcbaud(res, port, clkp, baud);
671 best = res;
672 resptr = best + 1;
673 } else {
674 resptr = res;
675
676 for (i = 0; i < cfg->clocks_size; i++, clkp++) {
677 if (s3c24xx_serial_calcbaud(resptr, port, clkp, baud))
678 resptr++;
679 } 639 }
680 } 640 quot--;
681
682 /* ok, we now need to select the best clock we found */
683
684 if (!best) {
685 unsigned int deviation = (1<<30)|((1<<30)-1);
686 int calc_deviation;
687 641
688 for (sptr = res; sptr < resptr; sptr++) { 642 calc_deviation = req_baud - baud;
689 calc_deviation = baud - sptr->calc; 643 if (calc_deviation < 0)
690 if (calc_deviation < 0) 644 calc_deviation = -calc_deviation;
691 calc_deviation = -calc_deviation;
692 645
693 if (calc_deviation < deviation) { 646 if (calc_deviation < deviation) {
694 best = sptr; 647 *best_clk = clk;
695 deviation = calc_deviation; 648 best_quot = quot;
696 } 649 *clk_num = cnt;
650 deviation = calc_deviation;
697 } 651 }
698 } 652 }
699 653
700 /* store results to pass back */ 654 return best_quot;
701
702 *clksrc = best->clksrc;
703 *clk = best->src;
704
705 return best->quot;
706} 655}
707 656
708/* udivslot_table[] 657/* udivslot_table[]
@@ -735,10 +684,9 @@ static void s3c24xx_serial_set_termios(struct uart_port *port,
735{ 684{
736 struct s3c2410_uartcfg *cfg = s3c24xx_port_to_cfg(port); 685 struct s3c2410_uartcfg *cfg = s3c24xx_port_to_cfg(port);
737 struct s3c24xx_uart_port *ourport = to_ourport(port); 686 struct s3c24xx_uart_port *ourport = to_ourport(port);
738 struct s3c24xx_uart_clksrc *clksrc = NULL;
739 struct clk *clk = NULL; 687 struct clk *clk = NULL;
740 unsigned long flags; 688 unsigned long flags;
741 unsigned int baud, quot; 689 unsigned int baud, quot, clk_sel = 0;
742 unsigned int ulcon; 690 unsigned int ulcon;
743 unsigned int umcon; 691 unsigned int umcon;
744 unsigned int udivslot = 0; 692 unsigned int udivslot = 0;
@@ -754,17 +702,16 @@ static void s3c24xx_serial_set_termios(struct uart_port *port,
754 */ 702 */
755 703
756 baud = uart_get_baud_rate(port, termios, old, 0, 115200*8); 704 baud = uart_get_baud_rate(port, termios, old, 0, 115200*8);
757 705 quot = s3c24xx_serial_getclk(ourport, baud, &clk, &clk_sel);
758 if (baud == 38400 && (port->flags & UPF_SPD_MASK) == UPF_SPD_CUST) 706 if (baud == 38400 && (port->flags & UPF_SPD_MASK) == UPF_SPD_CUST)
759 quot = port->custom_divisor; 707 quot = port->custom_divisor;
760 else 708 if (!clk)
761 quot = s3c24xx_serial_getclk(port, &clksrc, &clk, baud); 709 return;
762 710
763 /* check to see if we need to change clock source */ 711 /* check to see if we need to change clock source */
764 712
765 if (ourport->clksrc != clksrc || ourport->baudclk != clk) { 713 if (ourport->baudclk != clk) {
766 dbg("selecting clock %p\n", clk); 714 s3c24xx_serial_setsource(port, clk_sel);
767 s3c24xx_serial_setsource(port, clksrc);
768 715
769 if (ourport->baudclk != NULL && !IS_ERR(ourport->baudclk)) { 716 if (ourport->baudclk != NULL && !IS_ERR(ourport->baudclk)) {
770 clk_disable(ourport->baudclk); 717 clk_disable(ourport->baudclk);
@@ -773,7 +720,6 @@ static void s3c24xx_serial_set_termios(struct uart_port *port,
773 720
774 clk_enable(clk); 721 clk_enable(clk);
775 722
776 ourport->clksrc = clksrc;
777 ourport->baudclk = clk; 723 ourport->baudclk = clk;
778 ourport->baudclk_rate = clk ? clk_get_rate(clk) : 0; 724 ourport->baudclk_rate = clk ? clk_get_rate(clk) : 0;
779 } 725 }
@@ -1020,16 +966,29 @@ static struct s3c24xx_uart_port s3c24xx_serial_ports[CONFIG_SERIAL_SAMSUNG_UARTS
1020 966
1021/* s3c24xx_serial_resetport 967/* s3c24xx_serial_resetport
1022 * 968 *
1023 * wrapper to call the specific reset for this port (reset the fifos 969 * reset the fifos and other the settings.
1024 * and the settings)
1025*/ 970*/
1026 971
1027static inline int s3c24xx_serial_resetport(struct uart_port *port, 972static void s3c24xx_serial_resetport(struct uart_port *port,
1028 struct s3c2410_uartcfg *cfg) 973 struct s3c2410_uartcfg *cfg)
1029{ 974{
1030 struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port); 975 struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
976 unsigned long ucon = rd_regl(port, S3C2410_UCON);
977 unsigned int ucon_mask;
978
979 ucon_mask = info->clksel_mask;
980 if (info->type == PORT_S3C2440)
981 ucon_mask |= S3C2440_UCON0_DIVMASK;
1031 982
1032 return (info->reset_port)(port, cfg); 983 ucon &= ucon_mask;
984 wr_regl(port, S3C2410_UCON, ucon | cfg->ucon);
985
986 /* reset both fifos */
987 wr_regl(port, S3C2410_UFCON, cfg->ufcon | S3C2410_UFCON_RESETBOTH);
988 wr_regl(port, S3C2410_UFCON, cfg->ufcon);
989
990 /* some delay is required after fifo reset */
991 udelay(1);
1033} 992}
1034 993
1035 994
@@ -1121,11 +1080,10 @@ static inline void s3c24xx_serial_cpufreq_deregister(struct s3c24xx_uart_port *p
1121 */ 1080 */
1122 1081
1123static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport, 1082static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport,
1124 struct s3c24xx_uart_info *info,
1125 struct platform_device *platdev) 1083 struct platform_device *platdev)
1126{ 1084{
1127 struct uart_port *port = &ourport->port; 1085 struct uart_port *port = &ourport->port;
1128 struct s3c2410_uartcfg *cfg; 1086 struct s3c2410_uartcfg *cfg = ourport->cfg;
1129 struct resource *res; 1087 struct resource *res;
1130 int ret; 1088 int ret;
1131 1089
@@ -1134,30 +1092,16 @@ static int s3c24xx_serial_init_port(struct s3c24xx_uart_port *ourport,
1134 if (platdev == NULL) 1092 if (platdev == NULL)
1135 return -ENODEV; 1093 return -ENODEV;
1136 1094
1137 cfg = s3c24xx_dev_to_cfg(&platdev->dev);
1138
1139 if (port->mapbase != 0) 1095 if (port->mapbase != 0)
1140 return 0; 1096 return 0;
1141 1097
1142 if (cfg->hwport > CONFIG_SERIAL_SAMSUNG_UARTS) {
1143 printk(KERN_ERR "%s: port %d bigger than %d\n", __func__,
1144 cfg->hwport, CONFIG_SERIAL_SAMSUNG_UARTS);
1145 return -ERANGE;
1146 }
1147
1148 /* setup info for port */ 1098 /* setup info for port */
1149 port->dev = &platdev->dev; 1099 port->dev = &platdev->dev;
1150 ourport->info = info;
1151 1100
1152 /* Startup sequence is different for s3c64xx and higher SoC's */ 1101 /* Startup sequence is different for s3c64xx and higher SoC's */
1153 if (s3c24xx_serial_has_interrupt_mask(port)) 1102 if (s3c24xx_serial_has_interrupt_mask(port))
1154 s3c24xx_serial_ops.startup = s3c64xx_serial_startup; 1103 s3c24xx_serial_ops.startup = s3c64xx_serial_startup;
1155 1104
1156 /* copy the info in from provided structure */
1157 ourport->port.fifosize = info->fifosize;
1158
1159 dbg("s3c24xx_serial_init_port: %p (hw %d)...\n", port, cfg->hwport);
1160
1161 port->uartclk = 1; 1105 port->uartclk = 1;
1162 1106
1163 if (cfg->uart_flags & UPF_CONS_FLOW) { 1107 if (cfg->uart_flags & UPF_CONS_FLOW) {
@@ -1215,43 +1159,74 @@ static ssize_t s3c24xx_serial_show_clksrc(struct device *dev,
1215 struct uart_port *port = s3c24xx_dev_to_port(dev); 1159 struct uart_port *port = s3c24xx_dev_to_port(dev);
1216 struct s3c24xx_uart_port *ourport = to_ourport(port); 1160 struct s3c24xx_uart_port *ourport = to_ourport(port);
1217 1161
1218 return snprintf(buf, PAGE_SIZE, "* %s\n", ourport->clksrc->name); 1162 return snprintf(buf, PAGE_SIZE, "* %s\n", ourport->baudclk->name);
1219} 1163}
1220 1164
1221static DEVICE_ATTR(clock_source, S_IRUGO, s3c24xx_serial_show_clksrc, NULL); 1165static DEVICE_ATTR(clock_source, S_IRUGO, s3c24xx_serial_show_clksrc, NULL);
1222 1166
1167
1223/* Device driver serial port probe */ 1168/* Device driver serial port probe */
1224 1169
1170static const struct of_device_id s3c24xx_uart_dt_match[];
1225static int probe_index; 1171static int probe_index;
1226 1172
1227int s3c24xx_serial_probe(struct platform_device *dev, 1173static inline struct s3c24xx_serial_drv_data *s3c24xx_get_driver_data(
1228 struct s3c24xx_uart_info *info) 1174 struct platform_device *pdev)
1175{
1176#ifdef CONFIG_OF
1177 if (pdev->dev.of_node) {
1178 const struct of_device_id *match;
1179 match = of_match_node(s3c24xx_uart_dt_match, pdev->dev.of_node);
1180 return (struct s3c24xx_serial_drv_data *)match->data;
1181 }
1182#endif
1183 return (struct s3c24xx_serial_drv_data *)
1184 platform_get_device_id(pdev)->driver_data;
1185}
1186
1187static int s3c24xx_serial_probe(struct platform_device *pdev)
1229{ 1188{
1230 struct s3c24xx_uart_port *ourport; 1189 struct s3c24xx_uart_port *ourport;
1231 int ret; 1190 int ret;
1232 1191
1233 dbg("s3c24xx_serial_probe(%p, %p) %d\n", dev, info, probe_index); 1192 dbg("s3c24xx_serial_probe(%p) %d\n", pdev, probe_index);
1234 1193
1235 ourport = &s3c24xx_serial_ports[probe_index]; 1194 ourport = &s3c24xx_serial_ports[probe_index];
1195
1196 ourport->drv_data = s3c24xx_get_driver_data(pdev);
1197 if (!ourport->drv_data) {
1198 dev_err(&pdev->dev, "could not find driver data\n");
1199 return -ENODEV;
1200 }
1201
1202 ourport->info = ourport->drv_data->info;
1203 ourport->cfg = (pdev->dev.platform_data) ?
1204 (struct s3c2410_uartcfg *)pdev->dev.platform_data :
1205 ourport->drv_data->def_cfg;
1206
1207 ourport->port.fifosize = (ourport->info->fifosize) ?
1208 ourport->info->fifosize :
1209 ourport->drv_data->fifosize[probe_index];
1210
1236 probe_index++; 1211 probe_index++;
1237 1212
1238 dbg("%s: initialising port %p...\n", __func__, ourport); 1213 dbg("%s: initialising port %p...\n", __func__, ourport);
1239 1214
1240 ret = s3c24xx_serial_init_port(ourport, info, dev); 1215 ret = s3c24xx_serial_init_port(ourport, pdev);
1241 if (ret < 0) 1216 if (ret < 0)
1242 goto probe_err; 1217 goto probe_err;
1243 1218
1244 dbg("%s: adding port\n", __func__); 1219 dbg("%s: adding port\n", __func__);
1245 uart_add_one_port(&s3c24xx_uart_drv, &ourport->port); 1220 uart_add_one_port(&s3c24xx_uart_drv, &ourport->port);
1246 platform_set_drvdata(dev, &ourport->port); 1221 platform_set_drvdata(pdev, &ourport->port);
1247 1222
1248 ret = device_create_file(&dev->dev, &dev_attr_clock_source); 1223 ret = device_create_file(&pdev->dev, &dev_attr_clock_source);
1249 if (ret < 0) 1224 if (ret < 0)
1250 printk(KERN_ERR "%s: failed to add clksrc attr.\n", __func__); 1225 dev_err(&pdev->dev, "failed to add clock source attr.\n");
1251 1226
1252 ret = s3c24xx_serial_cpufreq_register(ourport); 1227 ret = s3c24xx_serial_cpufreq_register(ourport);
1253 if (ret < 0) 1228 if (ret < 0)
1254 dev_err(&dev->dev, "failed to add cpufreq notifier\n"); 1229 dev_err(&pdev->dev, "failed to add cpufreq notifier\n");
1255 1230
1256 return 0; 1231 return 0;
1257 1232
@@ -1259,9 +1234,7 @@ int s3c24xx_serial_probe(struct platform_device *dev,
1259 return ret; 1234 return ret;
1260} 1235}
1261 1236
1262EXPORT_SYMBOL_GPL(s3c24xx_serial_probe); 1237static int __devexit s3c24xx_serial_remove(struct platform_device *dev)
1263
1264int __devexit s3c24xx_serial_remove(struct platform_device *dev)
1265{ 1238{
1266 struct uart_port *port = s3c24xx_dev_to_port(&dev->dev); 1239 struct uart_port *port = s3c24xx_dev_to_port(&dev->dev);
1267 1240
@@ -1274,8 +1247,6 @@ int __devexit s3c24xx_serial_remove(struct platform_device *dev)
1274 return 0; 1247 return 0;
1275} 1248}
1276 1249
1277EXPORT_SYMBOL_GPL(s3c24xx_serial_remove);
1278
1279/* UART power management code */ 1250/* UART power management code */
1280#ifdef CONFIG_PM_SLEEP 1251#ifdef CONFIG_PM_SLEEP
1281static int s3c24xx_serial_suspend(struct device *dev) 1252static int s3c24xx_serial_suspend(struct device *dev)
@@ -1315,41 +1286,6 @@ static const struct dev_pm_ops s3c24xx_serial_pm_ops = {
1315#define SERIAL_SAMSUNG_PM_OPS NULL 1286#define SERIAL_SAMSUNG_PM_OPS NULL
1316#endif /* CONFIG_PM_SLEEP */ 1287#endif /* CONFIG_PM_SLEEP */
1317 1288
1318int s3c24xx_serial_init(struct platform_driver *drv,
1319 struct s3c24xx_uart_info *info)
1320{
1321 dbg("s3c24xx_serial_init(%p,%p)\n", drv, info);
1322
1323 drv->driver.pm = SERIAL_SAMSUNG_PM_OPS;
1324
1325 return platform_driver_register(drv);
1326}
1327
1328EXPORT_SYMBOL_GPL(s3c24xx_serial_init);
1329
1330/* module initialisation code */
1331
1332static int __init s3c24xx_serial_modinit(void)
1333{
1334 int ret;
1335
1336 ret = uart_register_driver(&s3c24xx_uart_drv);
1337 if (ret < 0) {
1338 printk(KERN_ERR "failed to register UART driver\n");
1339 return -1;
1340 }
1341
1342 return 0;
1343}
1344
1345static void __exit s3c24xx_serial_modexit(void)
1346{
1347 uart_unregister_driver(&s3c24xx_uart_drv);
1348}
1349
1350module_init(s3c24xx_serial_modinit);
1351module_exit(s3c24xx_serial_modexit);
1352
1353/* Console code */ 1289/* Console code */
1354 1290
1355#ifdef CONFIG_SERIAL_SAMSUNG_CONSOLE 1291#ifdef CONFIG_SERIAL_SAMSUNG_CONSOLE
@@ -1395,12 +1331,13 @@ static void __init
1395s3c24xx_serial_get_options(struct uart_port *port, int *baud, 1331s3c24xx_serial_get_options(struct uart_port *port, int *baud,
1396 int *parity, int *bits) 1332 int *parity, int *bits)
1397{ 1333{
1398 struct s3c24xx_uart_clksrc clksrc;
1399 struct clk *clk; 1334 struct clk *clk;
1400 unsigned int ulcon; 1335 unsigned int ulcon;
1401 unsigned int ucon; 1336 unsigned int ucon;
1402 unsigned int ubrdiv; 1337 unsigned int ubrdiv;
1403 unsigned long rate; 1338 unsigned long rate;
1339 unsigned int clk_sel;
1340 char clk_name[MAX_CLK_NAME_LENGTH];
1404 1341
1405 ulcon = rd_regl(port, S3C2410_ULCON); 1342 ulcon = rd_regl(port, S3C2410_ULCON);
1406 ucon = rd_regl(port, S3C2410_UCON); 1343 ucon = rd_regl(port, S3C2410_UCON);
@@ -1445,44 +1382,21 @@ s3c24xx_serial_get_options(struct uart_port *port, int *baud,
1445 1382
1446 /* now calculate the baud rate */ 1383 /* now calculate the baud rate */
1447 1384
1448 s3c24xx_serial_getsource(port, &clksrc); 1385 clk_sel = s3c24xx_serial_getsource(port);
1386 sprintf(clk_name, "clk_uart_baud%d", clk_sel);
1449 1387
1450 clk = clk_get(port->dev, clksrc.name); 1388 clk = clk_get(port->dev, clk_name);
1451 if (!IS_ERR(clk) && clk != NULL) 1389 if (!IS_ERR(clk) && clk != NULL)
1452 rate = clk_get_rate(clk) / clksrc.divisor; 1390 rate = clk_get_rate(clk);
1453 else 1391 else
1454 rate = 1; 1392 rate = 1;
1455 1393
1456
1457 *baud = rate / (16 * (ubrdiv + 1)); 1394 *baud = rate / (16 * (ubrdiv + 1));
1458 dbg("calculated baud %d\n", *baud); 1395 dbg("calculated baud %d\n", *baud);
1459 } 1396 }
1460 1397
1461} 1398}
1462 1399
1463/* s3c24xx_serial_init_ports
1464 *
1465 * initialise the serial ports from the machine provided initialisation
1466 * data.
1467*/
1468
1469static int s3c24xx_serial_init_ports(struct s3c24xx_uart_info **info)
1470{
1471 struct s3c24xx_uart_port *ptr = s3c24xx_serial_ports;
1472 struct platform_device **platdev_ptr;
1473 int i;
1474
1475 dbg("s3c24xx_serial_init_ports: initialising ports...\n");
1476
1477 platdev_ptr = s3c24xx_uart_devs;
1478
1479 for (i = 0; i < CONFIG_SERIAL_SAMSUNG_UARTS; i++, ptr++, platdev_ptr++) {
1480 s3c24xx_serial_init_port(ptr, info[i], *platdev_ptr);
1481 }
1482
1483 return 0;
1484}
1485
1486static int __init 1400static int __init
1487s3c24xx_serial_console_setup(struct console *co, char *options) 1401s3c24xx_serial_console_setup(struct console *co, char *options)
1488{ 1402{
@@ -1526,11 +1440,6 @@ s3c24xx_serial_console_setup(struct console *co, char *options)
1526 return uart_set_options(port, co, baud, parity, bits, flow); 1440 return uart_set_options(port, co, baud, parity, bits, flow);
1527} 1441}
1528 1442
1529/* s3c24xx_serial_initconsole
1530 *
1531 * initialise the console from one of the uart drivers
1532*/
1533
1534static struct console s3c24xx_serial_console = { 1443static struct console s3c24xx_serial_console = {
1535 .name = S3C24XX_SERIAL_NAME, 1444 .name = S3C24XX_SERIAL_NAME,
1536 .device = uart_console_device, 1445 .device = uart_console_device,
@@ -1540,34 +1449,250 @@ static struct console s3c24xx_serial_console = {
1540 .setup = s3c24xx_serial_console_setup, 1449 .setup = s3c24xx_serial_console_setup,
1541 .data = &s3c24xx_uart_drv, 1450 .data = &s3c24xx_uart_drv,
1542}; 1451};
1452#endif /* CONFIG_SERIAL_SAMSUNG_CONSOLE */
1543 1453
1544int s3c24xx_serial_initconsole(struct platform_driver *drv, 1454#ifdef CONFIG_CPU_S3C2410
1545 struct s3c24xx_uart_info **info) 1455static struct s3c24xx_serial_drv_data s3c2410_serial_drv_data = {
1456 .info = &(struct s3c24xx_uart_info) {
1457 .name = "Samsung S3C2410 UART",
1458 .type = PORT_S3C2410,
1459 .fifosize = 16,
1460 .rx_fifomask = S3C2410_UFSTAT_RXMASK,
1461 .rx_fifoshift = S3C2410_UFSTAT_RXSHIFT,
1462 .rx_fifofull = S3C2410_UFSTAT_RXFULL,
1463 .tx_fifofull = S3C2410_UFSTAT_TXFULL,
1464 .tx_fifomask = S3C2410_UFSTAT_TXMASK,
1465 .tx_fifoshift = S3C2410_UFSTAT_TXSHIFT,
1466 .def_clk_sel = S3C2410_UCON_CLKSEL0,
1467 .num_clks = 2,
1468 .clksel_mask = S3C2410_UCON_CLKMASK,
1469 .clksel_shift = S3C2410_UCON_CLKSHIFT,
1470 },
1471 .def_cfg = &(struct s3c2410_uartcfg) {
1472 .ucon = S3C2410_UCON_DEFAULT,
1473 .ufcon = S3C2410_UFCON_DEFAULT,
1474 },
1475};
1476#define S3C2410_SERIAL_DRV_DATA ((kernel_ulong_t)&s3c2410_serial_drv_data)
1477#else
1478#define S3C2410_SERIAL_DRV_DATA (kernel_ulong_t)NULL
1479#endif
1546 1480
1547{ 1481#ifdef CONFIG_CPU_S3C2412
1548 struct platform_device *dev = s3c24xx_uart_devs[0]; 1482static struct s3c24xx_serial_drv_data s3c2412_serial_drv_data = {
1483 .info = &(struct s3c24xx_uart_info) {
1484 .name = "Samsung S3C2412 UART",
1485 .type = PORT_S3C2412,
1486 .fifosize = 64,
1487 .has_divslot = 1,
1488 .rx_fifomask = S3C2440_UFSTAT_RXMASK,
1489 .rx_fifoshift = S3C2440_UFSTAT_RXSHIFT,
1490 .rx_fifofull = S3C2440_UFSTAT_RXFULL,
1491 .tx_fifofull = S3C2440_UFSTAT_TXFULL,
1492 .tx_fifomask = S3C2440_UFSTAT_TXMASK,
1493 .tx_fifoshift = S3C2440_UFSTAT_TXSHIFT,
1494 .def_clk_sel = S3C2410_UCON_CLKSEL2,
1495 .num_clks = 4,
1496 .clksel_mask = S3C2412_UCON_CLKMASK,
1497 .clksel_shift = S3C2412_UCON_CLKSHIFT,
1498 },
1499 .def_cfg = &(struct s3c2410_uartcfg) {
1500 .ucon = S3C2410_UCON_DEFAULT,
1501 .ufcon = S3C2410_UFCON_DEFAULT,
1502 },
1503};
1504#define S3C2412_SERIAL_DRV_DATA ((kernel_ulong_t)&s3c2412_serial_drv_data)
1505#else
1506#define S3C2412_SERIAL_DRV_DATA (kernel_ulong_t)NULL
1507#endif
1549 1508
1550 dbg("s3c24xx_serial_initconsole\n"); 1509#if defined(CONFIG_CPU_S3C2440) || defined(CONFIG_CPU_S3C2416) || \
1510 defined(CONFIG_CPU_S3C2443)
1511static struct s3c24xx_serial_drv_data s3c2440_serial_drv_data = {
1512 .info = &(struct s3c24xx_uart_info) {
1513 .name = "Samsung S3C2440 UART",
1514 .type = PORT_S3C2440,
1515 .fifosize = 64,
1516 .has_divslot = 1,
1517 .rx_fifomask = S3C2440_UFSTAT_RXMASK,
1518 .rx_fifoshift = S3C2440_UFSTAT_RXSHIFT,
1519 .rx_fifofull = S3C2440_UFSTAT_RXFULL,
1520 .tx_fifofull = S3C2440_UFSTAT_TXFULL,
1521 .tx_fifomask = S3C2440_UFSTAT_TXMASK,
1522 .tx_fifoshift = S3C2440_UFSTAT_TXSHIFT,
1523 .def_clk_sel = S3C2410_UCON_CLKSEL2,
1524 .num_clks = 4,
1525 .clksel_mask = S3C2412_UCON_CLKMASK,
1526 .clksel_shift = S3C2412_UCON_CLKSHIFT,
1527 },
1528 .def_cfg = &(struct s3c2410_uartcfg) {
1529 .ucon = S3C2410_UCON_DEFAULT,
1530 .ufcon = S3C2410_UFCON_DEFAULT,
1531 },
1532};
1533#define S3C2440_SERIAL_DRV_DATA ((kernel_ulong_t)&s3c2440_serial_drv_data)
1534#else
1535#define S3C2440_SERIAL_DRV_DATA (kernel_ulong_t)NULL
1536#endif
1551 1537
1552 /* select driver based on the cpu */ 1538#if defined(CONFIG_CPU_S3C6400) || defined(CONFIG_CPU_S3C6410) || \
1539 defined(CONFIG_CPU_S5P6440) || defined(CONFIG_CPU_S5P6450) || \
1540 defined(CONFIG_CPU_S5PC100)
1541static struct s3c24xx_serial_drv_data s3c6400_serial_drv_data = {
1542 .info = &(struct s3c24xx_uart_info) {
1543 .name = "Samsung S3C6400 UART",
1544 .type = PORT_S3C6400,
1545 .fifosize = 64,
1546 .has_divslot = 1,
1547 .rx_fifomask = S3C2440_UFSTAT_RXMASK,
1548 .rx_fifoshift = S3C2440_UFSTAT_RXSHIFT,
1549 .rx_fifofull = S3C2440_UFSTAT_RXFULL,
1550 .tx_fifofull = S3C2440_UFSTAT_TXFULL,
1551 .tx_fifomask = S3C2440_UFSTAT_TXMASK,
1552 .tx_fifoshift = S3C2440_UFSTAT_TXSHIFT,
1553 .def_clk_sel = S3C2410_UCON_CLKSEL2,
1554 .num_clks = 4,
1555 .clksel_mask = S3C6400_UCON_CLKMASK,
1556 .clksel_shift = S3C6400_UCON_CLKSHIFT,
1557 },
1558 .def_cfg = &(struct s3c2410_uartcfg) {
1559 .ucon = S3C2410_UCON_DEFAULT,
1560 .ufcon = S3C2410_UFCON_DEFAULT,
1561 },
1562};
1563#define S3C6400_SERIAL_DRV_DATA ((kernel_ulong_t)&s3c6400_serial_drv_data)
1564#else
1565#define S3C6400_SERIAL_DRV_DATA (kernel_ulong_t)NULL
1566#endif
1553 1567
1554 if (dev == NULL) { 1568#ifdef CONFIG_CPU_S5PV210
1555 printk(KERN_ERR "s3c24xx: no devices for console init\n"); 1569static struct s3c24xx_serial_drv_data s5pv210_serial_drv_data = {
1556 return 0; 1570 .info = &(struct s3c24xx_uart_info) {
1557 } 1571 .name = "Samsung S5PV210 UART",
1572 .type = PORT_S3C6400,
1573 .has_divslot = 1,
1574 .rx_fifomask = S5PV210_UFSTAT_RXMASK,
1575 .rx_fifoshift = S5PV210_UFSTAT_RXSHIFT,
1576 .rx_fifofull = S5PV210_UFSTAT_RXFULL,
1577 .tx_fifofull = S5PV210_UFSTAT_TXFULL,
1578 .tx_fifomask = S5PV210_UFSTAT_TXMASK,
1579 .tx_fifoshift = S5PV210_UFSTAT_TXSHIFT,
1580 .def_clk_sel = S3C2410_UCON_CLKSEL0,
1581 .num_clks = 2,
1582 .clksel_mask = S5PV210_UCON_CLKMASK,
1583 .clksel_shift = S5PV210_UCON_CLKSHIFT,
1584 },
1585 .def_cfg = &(struct s3c2410_uartcfg) {
1586 .ucon = S5PV210_UCON_DEFAULT,
1587 .ufcon = S5PV210_UFCON_DEFAULT,
1588 },
1589 .fifosize = { 256, 64, 16, 16 },
1590};
1591#define S5PV210_SERIAL_DRV_DATA ((kernel_ulong_t)&s5pv210_serial_drv_data)
1592#else
1593#define S5PV210_SERIAL_DRV_DATA (kernel_ulong_t)NULL
1594#endif
1558 1595
1559 if (strcmp(dev->name, drv->driver.name) != 0) 1596#ifdef CONFIG_CPU_EXYNOS4210
1560 return 0; 1597static struct s3c24xx_serial_drv_data exynos4210_serial_drv_data = {
1598 .info = &(struct s3c24xx_uart_info) {
1599 .name = "Samsung Exynos4 UART",
1600 .type = PORT_S3C6400,
1601 .has_divslot = 1,
1602 .rx_fifomask = S5PV210_UFSTAT_RXMASK,
1603 .rx_fifoshift = S5PV210_UFSTAT_RXSHIFT,
1604 .rx_fifofull = S5PV210_UFSTAT_RXFULL,
1605 .tx_fifofull = S5PV210_UFSTAT_TXFULL,
1606 .tx_fifomask = S5PV210_UFSTAT_TXMASK,
1607 .tx_fifoshift = S5PV210_UFSTAT_TXSHIFT,
1608 .def_clk_sel = S3C2410_UCON_CLKSEL0,
1609 .num_clks = 1,
1610 .clksel_mask = 0,
1611 .clksel_shift = 0,
1612 },
1613 .def_cfg = &(struct s3c2410_uartcfg) {
1614 .ucon = S5PV210_UCON_DEFAULT,
1615 .ufcon = S5PV210_UFCON_DEFAULT,
1616 .has_fracval = 1,
1617 },
1618 .fifosize = { 256, 64, 16, 16 },
1619};
1620#define EXYNOS4210_SERIAL_DRV_DATA ((kernel_ulong_t)&exynos4210_serial_drv_data)
1621#else
1622#define EXYNOS4210_SERIAL_DRV_DATA (kernel_ulong_t)NULL
1623#endif
1561 1624
1562 s3c24xx_serial_console.data = &s3c24xx_uart_drv; 1625static struct platform_device_id s3c24xx_serial_driver_ids[] = {
1563 s3c24xx_serial_init_ports(info); 1626 {
1627 .name = "s3c2410-uart",
1628 .driver_data = S3C2410_SERIAL_DRV_DATA,
1629 }, {
1630 .name = "s3c2412-uart",
1631 .driver_data = S3C2412_SERIAL_DRV_DATA,
1632 }, {
1633 .name = "s3c2440-uart",
1634 .driver_data = S3C2440_SERIAL_DRV_DATA,
1635 }, {
1636 .name = "s3c6400-uart",
1637 .driver_data = S3C6400_SERIAL_DRV_DATA,
1638 }, {
1639 .name = "s5pv210-uart",
1640 .driver_data = S5PV210_SERIAL_DRV_DATA,
1641 }, {
1642 .name = "exynos4210-uart",
1643 .driver_data = EXYNOS4210_SERIAL_DRV_DATA,
1644 },
1645 { },
1646};
1647MODULE_DEVICE_TABLE(platform, s3c24xx_serial_driver_ids);
1564 1648
1565 register_console(&s3c24xx_serial_console); 1649#ifdef CONFIG_OF
1566 return 0; 1650static const struct of_device_id s3c24xx_uart_dt_match[] = {
1651 { .compatible = "samsung,exynos4210-uart",
1652 .data = (void *)EXYNOS4210_SERIAL_DRV_DATA },
1653 {},
1654};
1655MODULE_DEVICE_TABLE(of, s3c24xx_uart_dt_match);
1656#else
1657#define s3c24xx_uart_dt_match NULL
1658#endif
1659
1660static struct platform_driver samsung_serial_driver = {
1661 .probe = s3c24xx_serial_probe,
1662 .remove = __devexit_p(s3c24xx_serial_remove),
1663 .id_table = s3c24xx_serial_driver_ids,
1664 .driver = {
1665 .name = "samsung-uart",
1666 .owner = THIS_MODULE,
1667 .pm = SERIAL_SAMSUNG_PM_OPS,
1668 .of_match_table = s3c24xx_uart_dt_match,
1669 },
1670};
1671
1672/* module initialisation code */
1673
1674static int __init s3c24xx_serial_modinit(void)
1675{
1676 int ret;
1677
1678 ret = uart_register_driver(&s3c24xx_uart_drv);
1679 if (ret < 0) {
1680 printk(KERN_ERR "failed to register UART driver\n");
1681 return -1;
1682 }
1683
1684 return platform_driver_register(&samsung_serial_driver);
1567} 1685}
1568 1686
1569#endif /* CONFIG_SERIAL_SAMSUNG_CONSOLE */ 1687static void __exit s3c24xx_serial_modexit(void)
1688{
1689 uart_unregister_driver(&s3c24xx_uart_drv);
1690}
1691
1692module_init(s3c24xx_serial_modinit);
1693module_exit(s3c24xx_serial_modexit);
1570 1694
1695MODULE_ALIAS("platform:samsung-uart");
1571MODULE_DESCRIPTION("Samsung SoC Serial port driver"); 1696MODULE_DESCRIPTION("Samsung SoC Serial port driver");
1572MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>"); 1697MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
1573MODULE_LICENSE("GPL v2"); 1698MODULE_LICENSE("GPL v2");
diff --git a/drivers/tty/serial/samsung.h b/drivers/tty/serial/samsung.h
index 8e87b788e5c6..1a4bca3e4179 100644
--- a/drivers/tty/serial/samsung.h
+++ b/drivers/tty/serial/samsung.h
@@ -19,20 +19,25 @@ struct s3c24xx_uart_info {
19 unsigned long tx_fifomask; 19 unsigned long tx_fifomask;
20 unsigned long tx_fifoshift; 20 unsigned long tx_fifoshift;
21 unsigned long tx_fifofull; 21 unsigned long tx_fifofull;
22 unsigned int def_clk_sel;
23 unsigned long num_clks;
24 unsigned long clksel_mask;
25 unsigned long clksel_shift;
22 26
23 /* uart port features */ 27 /* uart port features */
24 28
25 unsigned int has_divslot:1; 29 unsigned int has_divslot:1;
26 30
27 /* clock source control */
28
29 int (*get_clksrc)(struct uart_port *, struct s3c24xx_uart_clksrc *clk);
30 int (*set_clksrc)(struct uart_port *, struct s3c24xx_uart_clksrc *clk);
31
32 /* uart controls */ 31 /* uart controls */
33 int (*reset_port)(struct uart_port *, struct s3c2410_uartcfg *); 32 int (*reset_port)(struct uart_port *, struct s3c2410_uartcfg *);
34}; 33};
35 34
35struct s3c24xx_serial_drv_data {
36 struct s3c24xx_uart_info *info;
37 struct s3c2410_uartcfg *def_cfg;
38 unsigned int fifosize[CONFIG_SERIAL_SAMSUNG_UARTS];
39};
40
36struct s3c24xx_uart_port { 41struct s3c24xx_uart_port {
37 unsigned char rx_claimed; 42 unsigned char rx_claimed;
38 unsigned char tx_claimed; 43 unsigned char tx_claimed;
@@ -43,10 +48,13 @@ struct s3c24xx_uart_port {
43 unsigned int tx_irq; 48 unsigned int tx_irq;
44 49
45 struct s3c24xx_uart_info *info; 50 struct s3c24xx_uart_info *info;
46 struct s3c24xx_uart_clksrc *clksrc;
47 struct clk *clk; 51 struct clk *clk;
48 struct clk *baudclk; 52 struct clk *baudclk;
49 struct uart_port port; 53 struct uart_port port;
54 struct s3c24xx_serial_drv_data *drv_data;
55
56 /* reference to platform data */
57 struct s3c2410_uartcfg *cfg;
50 58
51#ifdef CONFIG_CPU_FREQ 59#ifdef CONFIG_CPU_FREQ
52 struct notifier_block freq_transition; 60 struct notifier_block freq_transition;
@@ -56,7 +64,6 @@ struct s3c24xx_uart_port {
56/* conversion functions */ 64/* conversion functions */
57 65
58#define s3c24xx_dev_to_port(__dev) (struct uart_port *)dev_get_drvdata(__dev) 66#define s3c24xx_dev_to_port(__dev) (struct uart_port *)dev_get_drvdata(__dev)
59#define s3c24xx_dev_to_cfg(__dev) (struct s3c2410_uartcfg *)((__dev)->platform_data)
60 67
61/* register access controls */ 68/* register access controls */
62 69
@@ -69,17 +76,6 @@ struct s3c24xx_uart_port {
69#define wr_regb(port, reg, val) __raw_writeb(val, portaddr(port, reg)) 76#define wr_regb(port, reg, val) __raw_writeb(val, portaddr(port, reg))
70#define wr_regl(port, reg, val) __raw_writel(val, portaddr(port, reg)) 77#define wr_regl(port, reg, val) __raw_writel(val, portaddr(port, reg))
71 78
72extern int s3c24xx_serial_probe(struct platform_device *dev,
73 struct s3c24xx_uart_info *uart);
74
75extern int __devexit s3c24xx_serial_remove(struct platform_device *dev);
76
77extern int s3c24xx_serial_initconsole(struct platform_driver *drv,
78 struct s3c24xx_uart_info **uart);
79
80extern int s3c24xx_serial_init(struct platform_driver *drv,
81 struct s3c24xx_uart_info *info);
82
83#ifdef CONFIG_SERIAL_SAMSUNG_DEBUG 79#ifdef CONFIG_SERIAL_SAMSUNG_DEBUG
84 80
85extern void printascii(const char *); 81extern void printascii(const char *);
diff --git a/include/linux/amba/pl330.h b/include/linux/amba/pl330.h
index d12f077a6daf..12e023c19ac1 100644
--- a/include/linux/amba/pl330.h
+++ b/include/linux/amba/pl330.h
@@ -12,17 +12,9 @@
12#ifndef __AMBA_PL330_H_ 12#ifndef __AMBA_PL330_H_
13#define __AMBA_PL330_H_ 13#define __AMBA_PL330_H_
14 14
15#include <linux/dmaengine.h>
15#include <asm/hardware/pl330.h> 16#include <asm/hardware/pl330.h>
16 17
17struct dma_pl330_peri {
18 /*
19 * Peri_Req i/f of the DMAC that is
20 * peripheral could be reached from.
21 */
22 u8 peri_id; /* specific dma id */
23 enum pl330_reqtype rqtype;
24};
25
26struct dma_pl330_platdata { 18struct dma_pl330_platdata {
27 /* 19 /*
28 * Number of valid peripherals connected to DMAC. 20 * Number of valid peripherals connected to DMAC.
@@ -33,9 +25,12 @@ struct dma_pl330_platdata {
33 */ 25 */
34 u8 nr_valid_peri; 26 u8 nr_valid_peri;
35 /* Array of valid peripherals */ 27 /* Array of valid peripherals */
36 struct dma_pl330_peri *peri; 28 u8 *peri_id;
29 /* Operational capabilities */
30 dma_cap_mask_t cap_mask;
37 /* Bytes to allocate for MC buffer */ 31 /* Bytes to allocate for MC buffer */
38 unsigned mcbuf_sz; 32 unsigned mcbuf_sz;
39}; 33};
40 34
35extern bool pl330_filter(struct dma_chan *chan, void *param);
41#endif /* __AMBA_PL330_H_ */ 36#endif /* __AMBA_PL330_H_ */