aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/arm/Marvell/README24
-rw-r--r--Documentation/devicetree/bindings/arm/marvell,berlin.txt24
-rw-r--r--Documentation/devicetree/bindings/interrupt-controller/snps,dw-apb-ictl.txt32
-rw-r--r--MAINTAINERS6
-rw-r--r--arch/arm/Kconfig2
-rw-r--r--arch/arm/Kconfig.debug10
-rw-r--r--arch/arm/Makefile1
-rw-r--r--arch/arm/boot/dts/Makefile3
-rw-r--r--arch/arm/boot/dts/berlin2-sony-nsz-gs7.dts29
-rw-r--r--arch/arm/boot/dts/berlin2.dtsi227
-rw-r--r--arch/arm/boot/dts/berlin2cd-google-chromecast.dts29
-rw-r--r--arch/arm/boot/dts/berlin2cd.dtsi210
-rw-r--r--arch/arm/common/timer-sp.c4
-rw-r--r--arch/arm/configs/multi_v7_defconfig3
-rw-r--r--arch/arm/mach-at91/Kconfig2
-rw-r--r--arch/arm/mach-at91/include/mach/cpu.h3
-rw-r--r--arch/arm/mach-at91/setup.c4
-rw-r--r--arch/arm/mach-berlin/Kconfig29
-rw-r--r--arch/arm/mach-berlin/Makefile1
-rw-r--r--arch/arm/mach-berlin/berlin.c39
-rw-r--r--arch/arm/mach-clps711x/common.c4
-rw-r--r--arch/arm/mach-davinci/time.c4
-rw-r--r--arch/arm/mach-ep93xx/Kconfig1
-rw-r--r--arch/arm/mach-ep93xx/core.c110
-rw-r--r--arch/arm/mach-ep93xx/include/mach/platform.h3
-rw-r--r--arch/arm/mach-imx/time.c4
-rw-r--r--arch/arm/mach-integrator/integrator_ap.c4
-rw-r--r--arch/arm/mach-ixp4xx/common.c4
-rw-r--r--arch/arm/mach-mmp/time.c4
-rw-r--r--arch/arm/mach-msm/timer.c4
-rw-r--r--arch/arm/mach-omap1/time.c4
-rw-r--r--arch/arm/mach-omap2/timer.c4
-rw-r--r--arch/arm/mach-pxa/time.c4
-rw-r--r--arch/arm/mach-sa1100/time.c4
-rw-r--r--arch/arm/mach-u300/timer.c4
-rw-r--r--arch/arm/plat-iop/time.c4
-rw-r--r--arch/arm/plat-omap/counter_32k.c4
-rw-r--r--arch/arm/plat-orion/time.c4
-rw-r--r--arch/arm/plat-versatile/sched-clock.c4
-rw-r--r--drivers/irqchip/Kconfig4
-rw-r--r--drivers/irqchip/Makefile1
-rw-r--r--drivers/irqchip/irq-dw-apb-ictl.c150
42 files changed, 976 insertions, 39 deletions
diff --git a/Documentation/arm/Marvell/README b/Documentation/arm/Marvell/README
index da0151db9964..5a930c1528ad 100644
--- a/Documentation/arm/Marvell/README
+++ b/Documentation/arm/Marvell/README
@@ -211,6 +211,30 @@ MMP/MMP2 family (communication processor)
211 Linux kernel mach directory: arch/arm/mach-mmp 211 Linux kernel mach directory: arch/arm/mach-mmp
212 Linux kernel plat directory: arch/arm/plat-pxa 212 Linux kernel plat directory: arch/arm/plat-pxa
213 213
214Berlin family (Digital Entertainment)
215-------------------------------------
216
217 Flavors:
218 88DE3005, Armada 1500-mini
219 Design name: BG2CD
220 Core: ARM Cortex-A9, PL310 L2CC
221 Homepage: http://www.marvell.com/digital-entertainment/armada-1500-mini/
222 88DE3100, Armada 1500
223 Design name: BG2
224 Core: Marvell PJ4B (ARMv7), Tauros3 L2CC
225 Homepage: http://www.marvell.com/digital-entertainment/armada-1500/
226 Product Brief: http://www.marvell.com/digital-entertainment/armada-1500/assets/Marvell-ARMADA-1500-Product-Brief.pdf
227 88DE????
228 Design name: BG3
229 Core: ARM Cortex-A15, CA15 integrated L2CC
230
231 Homepage: http://www.marvell.com/digital-entertainment/
232 Directory: arch/arm/mach-berlin
233
234 Comments:
235 * This line of SoCs is based on Marvell Sheeva or ARM Cortex CPUs
236 with Synopsys DesignWare (IRQ, GPIO, Timers, ...) and PXA IP (SDHCI, USB, ETH, ...).
237
214Long-term plans 238Long-term plans
215--------------- 239---------------
216 240
diff --git a/Documentation/devicetree/bindings/arm/marvell,berlin.txt b/Documentation/devicetree/bindings/arm/marvell,berlin.txt
new file mode 100644
index 000000000000..737afa5f8148
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/marvell,berlin.txt
@@ -0,0 +1,24 @@
1Marvell Berlin SoC Family Device Tree Bindings
2---------------------------------------------------------------
3
4Boards with a SoC of the Marvell Berlin family, e.g. Armada 1500
5shall have the following properties:
6
7* Required root node properties:
8compatible: must contain "marvell,berlin"
9
10In addition, the above compatible shall be extended with the specific
11SoC and board used. Currently known SoC compatibles are:
12 "marvell,berlin2" for Marvell Armada 1500 (BG2, 88DE3100),
13 "marvell,berlin2cd" for Marvell Armada 1500-mini (BG2CD, 88DE3005)
14 "marvell,berlin2ct" for Marvell Armada ? (BG2CT, 88DE????)
15 "marvell,berlin3" for Marvell Armada ? (BG3, 88DE????)
16
17* Example:
18
19/ {
20 model = "Sony NSZ-GS7";
21 compatible = "sony,nsz-gs7", "marvell,berlin2", "marvell,berlin";
22
23 ...
24}
diff --git a/Documentation/devicetree/bindings/interrupt-controller/snps,dw-apb-ictl.txt b/Documentation/devicetree/bindings/interrupt-controller/snps,dw-apb-ictl.txt
new file mode 100644
index 000000000000..492911744ca3
--- /dev/null
+++ b/Documentation/devicetree/bindings/interrupt-controller/snps,dw-apb-ictl.txt
@@ -0,0 +1,32 @@
1Synopsys DesignWare APB interrupt controller (dw_apb_ictl)
2
3Synopsys DesignWare provides interrupt controller IP for APB known as
4dw_apb_ictl. The IP is used as secondary interrupt controller in some SoCs with
5APB bus, e.g. Marvell Armada 1500.
6
7Required properties:
8- compatible: shall be "snps,dw-apb-ictl"
9- reg: physical base address of the controller and length of memory mapped
10 region starting with ENABLE_LOW register
11- interrupt-controller: identifies the node as an interrupt controller
12- #interrupt-cells: number of cells to encode an interrupt-specifier, shall be 1
13- interrupts: interrupt reference to primary interrupt controller
14- interrupt-parent: (optional) reference specific primary interrupt controller
15
16The interrupt sources map to the corresponding bits in the interrupt
17registers, i.e.
18- 0 maps to bit 0 of low interrupts,
19- 1 maps to bit 1 of low interrupts,
20- 32 maps to bit 0 of high interrupts,
21- 33 maps to bit 1 of high interrupts,
22- (optional) fast interrupts start at 64.
23
24Example:
25 aic: interrupt-controller@3000 {
26 compatible = "snps,dw-apb-ictl";
27 reg = <0x3000 0xc00>;
28 interrupt-controller;
29 #interrupt-cells = <1>;
30 interrupt-parent = <&gic>;
31 interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
32 };
diff --git a/MAINTAINERS b/MAINTAINERS
index 1344816c4c06..95648eb610b3 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1027,6 +1027,12 @@ L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
1027S: Maintained 1027S: Maintained
1028F: arch/arm/mach-mvebu/ 1028F: arch/arm/mach-mvebu/
1029 1029
1030ARM/Marvell Berlin SoC support
1031M: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
1032L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
1033S: Maintained
1034F: arch/arm/mach-berlin/
1035
1030ARM/Marvell Dove/Kirkwood/MV78xx0/Orion SOC support 1036ARM/Marvell Dove/Kirkwood/MV78xx0/Orion SOC support
1031M: Jason Cooper <jason@lakedaemon.net> 1037M: Jason Cooper <jason@lakedaemon.net>
1032M: Andrew Lunn <andrew@lunn.ch> 1038M: Andrew Lunn <andrew@lunn.ch>
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 6808460a48ba..6a8d80be1c4c 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -931,6 +931,8 @@ source "arch/arm/mach-bcm/Kconfig"
931 931
932source "arch/arm/mach-bcm2835/Kconfig" 932source "arch/arm/mach-bcm2835/Kconfig"
933 933
934source "arch/arm/mach-berlin/Kconfig"
935
934source "arch/arm/mach-clps711x/Kconfig" 936source "arch/arm/mach-clps711x/Kconfig"
935 937
936source "arch/arm/mach-cns3xxx/Kconfig" 938source "arch/arm/mach-cns3xxx/Kconfig"
diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index 5765abf5ce84..257155874bce 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -94,6 +94,14 @@ choice
94 depends on ARCH_BCM2835 94 depends on ARCH_BCM2835
95 select DEBUG_UART_PL01X 95 select DEBUG_UART_PL01X
96 96
97 config DEBUG_BERLIN_UART
98 bool "Marvell Berlin SoC Debug UART"
99 depends on ARCH_BERLIN
100 select DEBUG_UART_8250
101 help
102 Say Y here if you want kernel low-level debugging support
103 on Marvell Berlin SoC based platforms.
104
97 config DEBUG_CLPS711X_UART1 105 config DEBUG_CLPS711X_UART1
98 bool "Kernel low-level debugging messages via UART1" 106 bool "Kernel low-level debugging messages via UART1"
99 depends on ARCH_CLPS711X 107 depends on ARCH_CLPS711X
@@ -1011,6 +1019,7 @@ config DEBUG_UART_PHYS
1011 default 0xf1012000 if DEBUG_MVEBU_UART_ALTERNATE 1019 default 0xf1012000 if DEBUG_MVEBU_UART_ALTERNATE
1012 default 0xf1012000 if ARCH_DOVE || ARCH_KIRKWOOD || ARCH_MV78XX0 || \ 1020 default 0xf1012000 if ARCH_DOVE || ARCH_KIRKWOOD || ARCH_MV78XX0 || \
1013 ARCH_ORION5X 1021 ARCH_ORION5X
1022 default 0xf7fc9000 if DEBUG_BERLIN_UART
1014 default 0xf8b00000 if DEBUG_HI3716_UART 1023 default 0xf8b00000 if DEBUG_HI3716_UART
1015 default 0xfcb00000 if DEBUG_HI3620_UART 1024 default 0xfcb00000 if DEBUG_HI3620_UART
1016 default 0xfe800000 if ARCH_IOP32X 1025 default 0xfe800000 if ARCH_IOP32X
@@ -1036,6 +1045,7 @@ config DEBUG_UART_VIRT
1036 default 0xf2100000 if DEBUG_PXA_UART1 1045 default 0xf2100000 if DEBUG_PXA_UART1
1037 default 0xf4090000 if ARCH_LPC32XX 1046 default 0xf4090000 if ARCH_LPC32XX
1038 default 0xf4200000 if ARCH_GEMINI 1047 default 0xf4200000 if ARCH_GEMINI
1048 default 0xf7fc9000 if DEBUG_BERLIN_UART
1039 default 0xf8009000 if DEBUG_VEXPRESS_UART0_CA9 1049 default 0xf8009000 if DEBUG_VEXPRESS_UART0_CA9
1040 default 0xf8090000 if DEBUG_VEXPRESS_UART0_RS1 1050 default 0xf8090000 if DEBUG_VEXPRESS_UART0_RS1
1041 default 0xfb009000 if DEBUG_REALVIEW_STD_PORT 1051 default 0xfb009000 if DEBUG_REALVIEW_STD_PORT
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 6da9abb30460..b2f8222bb6c4 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -148,6 +148,7 @@ textofs-$(CONFIG_ARCH_MSM8960) := 0x00208000
148machine-$(CONFIG_ARCH_AT91) += at91 148machine-$(CONFIG_ARCH_AT91) += at91
149machine-$(CONFIG_ARCH_BCM) += bcm 149machine-$(CONFIG_ARCH_BCM) += bcm
150machine-$(CONFIG_ARCH_BCM2835) += bcm2835 150machine-$(CONFIG_ARCH_BCM2835) += bcm2835
151machine-$(CONFIG_ARCH_BERLIN) += berlin
151machine-$(CONFIG_ARCH_CLPS711X) += clps711x 152machine-$(CONFIG_ARCH_CLPS711X) += clps711x
152machine-$(CONFIG_ARCH_CNS3XXX) += cns3xxx 153machine-$(CONFIG_ARCH_CNS3XXX) += cns3xxx
153machine-$(CONFIG_ARCH_DAVINCI) += davinci 154machine-$(CONFIG_ARCH_DAVINCI) += davinci
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index e4a0bea3c767..e1bf28743b98 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -45,6 +45,9 @@ dtb-$(CONFIG_ARCH_BCM2835) += bcm2835-rpi-b.dtb
45dtb-$(CONFIG_ARCH_BCM_MOBILE) += bcm11351-brt.dtb \ 45dtb-$(CONFIG_ARCH_BCM_MOBILE) += bcm11351-brt.dtb \
46 bcm28155-ap.dtb 46 bcm28155-ap.dtb
47dtb-$(CONFIG_ARCH_BCM2835) += bcm2835-rpi-b.dtb 47dtb-$(CONFIG_ARCH_BCM2835) += bcm2835-rpi-b.dtb
48dtb-$(CONFIG_ARCH_BERLIN) += \
49 berlin2-sony-nsz-gs7.dtb \
50 berlin2cd-google-chromecast.dtb
48dtb-$(CONFIG_ARCH_DAVINCI) += da850-enbw-cmc.dtb \ 51dtb-$(CONFIG_ARCH_DAVINCI) += da850-enbw-cmc.dtb \
49 da850-evm.dtb 52 da850-evm.dtb
50dtb-$(CONFIG_ARCH_DOVE) += dove-cm-a510.dtb \ 53dtb-$(CONFIG_ARCH_DOVE) += dove-cm-a510.dtb \
diff --git a/arch/arm/boot/dts/berlin2-sony-nsz-gs7.dts b/arch/arm/boot/dts/berlin2-sony-nsz-gs7.dts
new file mode 100644
index 000000000000..c72bfd468d10
--- /dev/null
+++ b/arch/arm/boot/dts/berlin2-sony-nsz-gs7.dts
@@ -0,0 +1,29 @@
1/*
2 * Device Tree file for Sony NSZ-GS7
3 *
4 * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
5 *
6 * This file is licensed under the terms of the GNU General Public
7 * License version 2. This program is licensed "as is" without any
8 * warranty of any kind, whether express or implied.
9 */
10
11/dts-v1/;
12
13#include "berlin2.dtsi"
14
15/ {
16 model = "Sony NSZ-GS7";
17 compatible = "sony,nsz-gs7", "marvell,berlin2", "marvell,berlin";
18
19 chosen {
20 bootargs = "console=ttyS0,115200 earlyprintk";
21 };
22
23 memory {
24 device_type = "memory";
25 reg = <0x00000000 0x40000000>; /* 1 GB */
26 };
27};
28
29&uart0 { status = "okay"; };
diff --git a/arch/arm/boot/dts/berlin2.dtsi b/arch/arm/boot/dts/berlin2.dtsi
new file mode 100644
index 000000000000..56a1af2f1052
--- /dev/null
+++ b/arch/arm/boot/dts/berlin2.dtsi
@@ -0,0 +1,227 @@
1/*
2 * Device Tree Include file for Marvell Armada 1500 (Berlin BG2) SoC
3 *
4 * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
5 *
6 * based on GPL'ed 2.6 kernel sources
7 * (c) Marvell International Ltd.
8 *
9 * This file is licensed under the terms of the GNU General Public
10 * License version 2. This program is licensed "as is" without any
11 * warranty of any kind, whether express or implied.
12 */
13
14#include "skeleton.dtsi"
15#include <dt-bindings/interrupt-controller/arm-gic.h>
16
17/ {
18 model = "Marvell Armada 1500 (BG2) SoC";
19 compatible = "marvell,berlin2", "marvell,berlin";
20
21 cpus {
22 #address-cells = <1>;
23 #size-cells = <0>;
24
25 cpu@0 {
26 compatible = "marvell,pj4b";
27 device_type = "cpu";
28 next-level-cache = <&l2>;
29 reg = <0>;
30 };
31
32 cpu@1 {
33 compatible = "marvell,pj4b";
34 device_type = "cpu";
35 next-level-cache = <&l2>;
36 reg = <1>;
37 };
38 };
39
40 clocks {
41 smclk: sysmgr-clock {
42 compatible = "fixed-clock";
43 #clock-cells = <0>;
44 clock-frequency = <25000000>;
45 };
46
47 cfgclk: cfg-clock {
48 compatible = "fixed-clock";
49 #clock-cells = <0>;
50 clock-frequency = <100000000>;
51 };
52
53 sysclk: system-clock {
54 compatible = "fixed-clock";
55 #clock-cells = <0>;
56 clock-frequency = <400000000>;
57 };
58 };
59
60 soc {
61 compatible = "simple-bus";
62 #address-cells = <1>;
63 #size-cells = <1>;
64 interrupt-parent = <&gic>;
65
66 ranges = <0 0xf7000000 0x1000000>;
67
68 l2: l2-cache-controller@ac0000 {
69 compatible = "marvell,tauros3-cache", "arm,pl310-cache";
70 reg = <0xac0000 0x1000>;
71 cache-unified;
72 cache-level = <2>;
73 };
74
75 gic: interrupt-controller@ad1000 {
76 compatible = "arm,cortex-a9-gic";
77 reg = <0xad1000 0x1000>, <0xad0100 0x0100>;
78 interrupt-controller;
79 #interrupt-cells = <3>;
80 };
81
82 local-timer@ad0600 {
83 compatible = "arm,cortex-a9-twd-timer";
84 reg = <0xad0600 0x20>;
85 interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_HIGH>;
86 clocks = <&sysclk>;
87 };
88
89 apb@e80000 {
90 compatible = "simple-bus";
91 #address-cells = <1>;
92 #size-cells = <1>;
93
94 ranges = <0 0xe80000 0x10000>;
95 interrupt-parent = <&aic>;
96
97 timer0: timer@2c00 {
98 compatible = "snps,dw-apb-timer";
99 reg = <0x2c00 0x14>;
100 interrupts = <8>;
101 clocks = <&cfgclk>;
102 clock-names = "timer";
103 status = "okay";
104 };
105
106 timer1: timer@2c14 {
107 compatible = "snps,dw-apb-timer";
108 reg = <0x2c14 0x14>;
109 interrupts = <9>;
110 clocks = <&cfgclk>;
111 clock-names = "timer";
112 status = "okay";
113 };
114
115 timer2: timer@2c28 {
116 compatible = "snps,dw-apb-timer";
117 reg = <0x2c28 0x14>;
118 interrupts = <10>;
119 clocks = <&cfgclk>;
120 clock-names = "timer";
121 status = "disabled";
122 };
123
124 timer3: timer@2c3c {
125 compatible = "snps,dw-apb-timer";
126 reg = <0x2c3c 0x14>;
127 interrupts = <11>;
128 clocks = <&cfgclk>;
129 clock-names = "timer";
130 status = "disabled";
131 };
132
133 timer4: timer@2c50 {
134 compatible = "snps,dw-apb-timer";
135 reg = <0x2c50 0x14>;
136 interrupts = <12>;
137 clocks = <&cfgclk>;
138 clock-names = "timer";
139 status = "disabled";
140 };
141
142 timer5: timer@2c64 {
143 compatible = "snps,dw-apb-timer";
144 reg = <0x2c64 0x14>;
145 interrupts = <13>;
146 clocks = <&cfgclk>;
147 clock-names = "timer";
148 status = "disabled";
149 };
150
151 timer6: timer@2c78 {
152 compatible = "snps,dw-apb-timer";
153 reg = <0x2c78 0x14>;
154 interrupts = <14>;
155 clocks = <&cfgclk>;
156 clock-names = "timer";
157 status = "disabled";
158 };
159
160 timer7: timer@2c8c {
161 compatible = "snps,dw-apb-timer";
162 reg = <0x2c8c 0x14>;
163 interrupts = <15>;
164 clocks = <&cfgclk>;
165 clock-names = "timer";
166 status = "disabled";
167 };
168
169 aic: interrupt-controller@3000 {
170 compatible = "snps,dw-apb-ictl";
171 reg = <0x3000 0xc00>;
172 interrupt-controller;
173 #interrupt-cells = <1>;
174 interrupt-parent = <&gic>;
175 interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
176 };
177 };
178
179 apb@fc0000 {
180 compatible = "simple-bus";
181 #address-cells = <1>;
182 #size-cells = <1>;
183
184 ranges = <0 0xfc0000 0x10000>;
185 interrupt-parent = <&sic>;
186
187 uart0: serial@9000 {
188 compatible = "snps,dw-apb-uart";
189 reg = <0x9000 0x100>;
190 reg-shift = <2>;
191 reg-io-width = <1>;
192 interrupts = <8>;
193 clocks = <&smclk>;
194 status = "disabled";
195 };
196
197 uart1: serial@a000 {
198 compatible = "snps,dw-apb-uart";
199 reg = <0xa000 0x100>;
200 reg-shift = <2>;
201 reg-io-width = <1>;
202 interrupts = <9>;
203 clocks = <&smclk>;
204 status = "disabled";
205 };
206
207 uart2: serial@b000 {
208 compatible = "snps,dw-apb-uart";
209 reg = <0xb000 0x100>;
210 reg-shift = <2>;
211 reg-io-width = <1>;
212 interrupts = <10>;
213 clocks = <&smclk>;
214 status = "disabled";
215 };
216
217 sic: interrupt-controller@e000 {
218 compatible = "snps,dw-apb-ictl";
219 reg = <0xe000 0x400>;
220 interrupt-controller;
221 #interrupt-cells = <1>;
222 interrupt-parent = <&gic>;
223 interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
224 };
225 };
226 };
227};
diff --git a/arch/arm/boot/dts/berlin2cd-google-chromecast.dts b/arch/arm/boot/dts/berlin2cd-google-chromecast.dts
new file mode 100644
index 000000000000..bcd81ffc495d
--- /dev/null
+++ b/arch/arm/boot/dts/berlin2cd-google-chromecast.dts
@@ -0,0 +1,29 @@
1/*
2 * Device Tree file for Google Chromecast
3 *
4 * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
5 *
6 * This file is licensed under the terms of the GNU General Public
7 * License version 2. This program is licensed "as is" without any
8 * warranty of any kind, whether express or implied.
9 */
10
11/dts-v1/;
12
13#include "berlin2cd.dtsi"
14
15/ {
16 model = "Google Chromecast";
17 compatible = "google,chromecast", "marvell,berlin2cd", "marvell,berlin";
18
19 chosen {
20 bootargs = "console=ttyS0,115200 earlyprintk";
21 };
22
23 memory {
24 device_type = "memory";
25 reg = <0x00000000 0x20000000>; /* 512 MB */
26 };
27};
28
29&uart0 { status = "okay"; };
diff --git a/arch/arm/boot/dts/berlin2cd.dtsi b/arch/arm/boot/dts/berlin2cd.dtsi
new file mode 100644
index 000000000000..094968c27533
--- /dev/null
+++ b/arch/arm/boot/dts/berlin2cd.dtsi
@@ -0,0 +1,210 @@
1/*
2 * Device Tree Include file for Marvell Armada 1500-mini (Berlin BG2CD) SoC
3 *
4 * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
5 *
6 * based on GPL'ed 2.6 kernel sources
7 * (c) Marvell International Ltd.
8 *
9 * This file is licensed under the terms of the GNU General Public
10 * License version 2. This program is licensed "as is" without any
11 * warranty of any kind, whether express or implied.
12 */
13
14#include "skeleton.dtsi"
15#include <dt-bindings/interrupt-controller/arm-gic.h>
16
17/ {
18 model = "Marvell Armada 1500-mini (BG2CD) SoC";
19 compatible = "marvell,berlin2cd", "marvell,berlin";
20
21 cpus {
22 #address-cells = <1>;
23 #size-cells = <0>;
24
25 cpu@0 {
26 compatible = "arm,cortex-a9";
27 device_type = "cpu";
28 next-level-cache = <&l2>;
29 reg = <0>;
30 };
31 };
32
33 clocks {
34 smclk: sysmgr-clock {
35 compatible = "fixed-clock";
36 #clock-cells = <0>;
37 clock-frequency = <25000000>;
38 };
39
40 cfgclk: cfg-clock {
41 compatible = "fixed-clock";
42 #clock-cells = <0>;
43 clock-frequency = <75000000>;
44 };
45
46 sysclk: system-clock {
47 compatible = "fixed-clock";
48 #clock-cells = <0>;
49 clock-frequency = <300000000>;
50 };
51 };
52
53 soc {
54 compatible = "simple-bus";
55 #address-cells = <1>;
56 #size-cells = <1>;
57 interrupt-parent = <&gic>;
58
59 ranges = <0 0xf7000000 0x1000000>;
60
61 l2: l2-cache-controller@ac0000 {
62 compatible = "arm,pl310-cache";
63 reg = <0xac0000 0x1000>;
64 cache-unified;
65 cache-level = <2>;
66 };
67
68 gic: interrupt-controller@ad1000 {
69 compatible = "arm,cortex-a9-gic";
70 reg = <0xad1000 0x1000>, <0xad0100 0x0100>;
71 interrupt-controller;
72 #interrupt-cells = <3>;
73 };
74
75 local-timer@ad0600 {
76 compatible = "arm,cortex-a9-twd-timer";
77 reg = <0xad0600 0x20>;
78 interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_HIGH>;
79 clocks = <&sysclk>;
80 };
81
82 apb@e80000 {
83 compatible = "simple-bus";
84 #address-cells = <1>;
85 #size-cells = <1>;
86
87 ranges = <0 0xe80000 0x10000>;
88 interrupt-parent = <&aic>;
89
90 timer0: timer@2c00 {
91 compatible = "snps,dw-apb-timer";
92 reg = <0x2c00 0x14>;
93 interrupts = <8>;
94 clocks = <&cfgclk>;
95 clock-names = "timer";
96 status = "okay";
97 };
98
99 timer1: timer@2c14 {
100 compatible = "snps,dw-apb-timer";
101 reg = <0x2c14 0x14>;
102 interrupts = <9>;
103 clocks = <&cfgclk>;
104 clock-names = "timer";
105 status = "okay";
106 };
107
108 timer2: timer@2c28 {
109 compatible = "snps,dw-apb-timer";
110 reg = <0x2c28 0x14>;
111 interrupts = <10>;
112 clocks = <&cfgclk>;
113 clock-names = "timer";
114 status = "disabled";
115 };
116
117 timer3: timer@2c3c {
118 compatible = "snps,dw-apb-timer";
119 reg = <0x2c3c 0x14>;
120 interrupts = <11>;
121 clocks = <&cfgclk>;
122 clock-names = "timer";
123 status = "disabled";
124 };
125
126 timer4: timer@2c50 {
127 compatible = "snps,dw-apb-timer";
128 reg = <0x2c50 0x14>;
129 interrupts = <12>;
130 clocks = <&cfgclk>;
131 clock-names = "timer";
132 status = "disabled";
133 };
134
135 timer5: timer@2c64 {
136 compatible = "snps,dw-apb-timer";
137 reg = <0x2c64 0x14>;
138 interrupts = <13>;
139 clocks = <&cfgclk>;
140 clock-names = "timer";
141 status = "disabled";
142 };
143
144 timer6: timer@2c78 {
145 compatible = "snps,dw-apb-timer";
146 reg = <0x2c78 0x14>;
147 interrupts = <14>;
148 clocks = <&cfgclk>;
149 clock-names = "timer";
150 status = "disabled";
151 };
152
153 timer7: timer@2c8c {
154 compatible = "snps,dw-apb-timer";
155 reg = <0x2c8c 0x14>;
156 interrupts = <15>;
157 clocks = <&cfgclk>;
158 clock-names = "timer";
159 status = "disabled";
160 };
161
162 aic: interrupt-controller@3000 {
163 compatible = "snps,dw-apb-ictl";
164 reg = <0x3000 0xc00>;
165 interrupt-controller;
166 #interrupt-cells = <1>;
167 interrupt-parent = <&gic>;
168 interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
169 };
170 };
171
172 apb@fc0000 {
173 compatible = "simple-bus";
174 #address-cells = <1>;
175 #size-cells = <1>;
176
177 ranges = <0 0xfc0000 0x10000>;
178 interrupt-parent = <&sic>;
179
180 uart0: serial@9000 {
181 compatible = "snps,dw-apb-uart";
182 reg = <0x9000 0x100>;
183 reg-shift = <2>;
184 reg-io-width = <1>;
185 interrupts = <8>;
186 clocks = <&smclk>;
187 status = "disabled";
188 };
189
190 uart1: serial@a000 {
191 compatible = "snps,dw-apb-uart";
192 reg = <0xa000 0x100>;
193 reg-shift = <2>;
194 reg-io-width = <1>;
195 interrupts = <9>;
196 clocks = <&smclk>;
197 status = "disabled";
198 };
199
200 sic: interrupt-controller@e000 {
201 compatible = "snps,dw-apb-ictl";
202 reg = <0xe000 0x400>;
203 interrupt-controller;
204 #interrupt-cells = <1>;
205 interrupt-parent = <&gic>;
206 interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
207 };
208 };
209 };
210};
diff --git a/arch/arm/common/timer-sp.c b/arch/arm/common/timer-sp.c
index ce922d0ea7aa..53c6a26b633d 100644
--- a/arch/arm/common/timer-sp.c
+++ b/arch/arm/common/timer-sp.c
@@ -66,7 +66,7 @@ static long __init sp804_get_clock_rate(struct clk *clk)
66 66
67static void __iomem *sched_clock_base; 67static void __iomem *sched_clock_base;
68 68
69static u32 sp804_read(void) 69static u64 notrace sp804_read(void)
70{ 70{
71 return ~readl_relaxed(sched_clock_base + TIMER_VALUE); 71 return ~readl_relaxed(sched_clock_base + TIMER_VALUE);
72} 72}
@@ -104,7 +104,7 @@ void __init __sp804_clocksource_and_sched_clock_init(void __iomem *base,
104 104
105 if (use_sched_clock) { 105 if (use_sched_clock) {
106 sched_clock_base = base; 106 sched_clock_base = base;
107 setup_sched_clock(sp804_read, 32, rate); 107 sched_clock_register(sp804_read, 32, rate);
108 } 108 }
109} 109}
110 110
diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
index c1df4e9db140..7e3f5cba7cfd 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -7,6 +7,9 @@ CONFIG_MACH_ARMADA_370=y
7CONFIG_MACH_ARMADA_XP=y 7CONFIG_MACH_ARMADA_XP=y
8CONFIG_ARCH_BCM=y 8CONFIG_ARCH_BCM=y
9CONFIG_ARCH_BCM_MOBILE=y 9CONFIG_ARCH_BCM_MOBILE=y
10CONFIG_ARCH_BERLIN=y
11CONFIG_MACH_BERLIN_BG2=y
12CONFIG_MACH_BERLIN_BG2CD=y
10CONFIG_GPIO_PCA953X=y 13CONFIG_GPIO_PCA953X=y
11CONFIG_ARCH_HIGHBANK=y 14CONFIG_ARCH_HIGHBANK=y
12CONFIG_ARCH_KEYSTONE=y 15CONFIG_ARCH_KEYSTONE=y
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index 699b71e7f7ec..44eacdd7468b 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -67,7 +67,7 @@ config SOC_SAMA5D3
67 select HAVE_AT91_DBGU1 67 select HAVE_AT91_DBGU1
68 help 68 help
69 Select this if you are using one of Atmel's SAMA5D3 family SoC. 69 Select this if you are using one of Atmel's SAMA5D3 family SoC.
70 This support covers SAMA5D31, SAMA5D33, SAMA5D34, SAMA5D35. 70 This support covers SAMA5D31, SAMA5D33, SAMA5D34, SAMA5D35, SAMA5D36.
71endif 71endif
72 72
73if SOC_SAM_V4_V5 73if SOC_SAM_V4_V5
diff --git a/arch/arm/mach-at91/include/mach/cpu.h b/arch/arm/mach-at91/include/mach/cpu.h
index d3d7b993846b..86c71debab5b 100644
--- a/arch/arm/mach-at91/include/mach/cpu.h
+++ b/arch/arm/mach-at91/include/mach/cpu.h
@@ -53,6 +53,7 @@
53#define ARCH_EXID_SAMA5D33 0x00414300 53#define ARCH_EXID_SAMA5D33 0x00414300
54#define ARCH_EXID_SAMA5D34 0x00414301 54#define ARCH_EXID_SAMA5D34 0x00414301
55#define ARCH_EXID_SAMA5D35 0x00584300 55#define ARCH_EXID_SAMA5D35 0x00584300
56#define ARCH_EXID_SAMA5D36 0x00004301
56 57
57#define ARCH_FAMILY_AT91X92 0x09200000 58#define ARCH_FAMILY_AT91X92 0x09200000
58#define ARCH_FAMILY_AT91SAM9 0x01900000 59#define ARCH_FAMILY_AT91SAM9 0x01900000
@@ -105,7 +106,7 @@ enum at91_soc_subtype {
105 106
106 /* SAMA5D3 */ 107 /* SAMA5D3 */
107 AT91_SOC_SAMA5D31, AT91_SOC_SAMA5D33, AT91_SOC_SAMA5D34, 108 AT91_SOC_SAMA5D31, AT91_SOC_SAMA5D33, AT91_SOC_SAMA5D34,
108 AT91_SOC_SAMA5D35, 109 AT91_SOC_SAMA5D35, AT91_SOC_SAMA5D36,
109 110
110 /* No subtype for this SoC */ 111 /* No subtype for this SoC */
111 AT91_SOC_SUBTYPE_NONE, 112 AT91_SOC_SUBTYPE_NONE,
diff --git a/arch/arm/mach-at91/setup.c b/arch/arm/mach-at91/setup.c
index 094b3459c288..eb6468dc60d5 100644
--- a/arch/arm/mach-at91/setup.c
+++ b/arch/arm/mach-at91/setup.c
@@ -233,6 +233,9 @@ static void __init soc_detect(u32 dbgu_base)
233 case ARCH_EXID_SAMA5D35: 233 case ARCH_EXID_SAMA5D35:
234 at91_soc_initdata.subtype = AT91_SOC_SAMA5D35; 234 at91_soc_initdata.subtype = AT91_SOC_SAMA5D35;
235 break; 235 break;
236 case ARCH_EXID_SAMA5D36:
237 at91_soc_initdata.subtype = AT91_SOC_SAMA5D36;
238 break;
236 } 239 }
237 } 240 }
238} 241}
@@ -275,6 +278,7 @@ static const char *soc_subtype_name[] = {
275 [AT91_SOC_SAMA5D33] = "sama5d33", 278 [AT91_SOC_SAMA5D33] = "sama5d33",
276 [AT91_SOC_SAMA5D34] = "sama5d34", 279 [AT91_SOC_SAMA5D34] = "sama5d34",
277 [AT91_SOC_SAMA5D35] = "sama5d35", 280 [AT91_SOC_SAMA5D35] = "sama5d35",
281 [AT91_SOC_SAMA5D36] = "sama5d36",
278 [AT91_SOC_SUBTYPE_NONE] = "None", 282 [AT91_SOC_SUBTYPE_NONE] = "None",
279 [AT91_SOC_SUBTYPE_UNKNOWN] = "Unknown", 283 [AT91_SOC_SUBTYPE_UNKNOWN] = "Unknown",
280}; 284};
diff --git a/arch/arm/mach-berlin/Kconfig b/arch/arm/mach-berlin/Kconfig
new file mode 100644
index 000000000000..7a02d222c378
--- /dev/null
+++ b/arch/arm/mach-berlin/Kconfig
@@ -0,0 +1,29 @@
1config ARCH_BERLIN
2 bool "Marvell Berlin SoCs" if ARCH_MULTI_V7
3 select ARM_GIC
4 select GENERIC_CLOCKEVENTS
5 select GENERIC_IRQ_CHIP
6 select COMMON_CLK
7 select DW_APB_ICTL
8 select DW_APB_TIMER_OF
9
10if ARCH_BERLIN
11
12menu "Marvell Berlin SoC variants"
13
14config MACH_BERLIN_BG2
15 bool "Marvell Armada 1500 (BG2)"
16 select CACHE_L2X0
17 select CPU_PJ4B
18 select HAVE_ARM_TWD if SMP
19 select HAVE_SMP
20
21config MACH_BERLIN_BG2CD
22 bool "Marvell Armada 1500-mini (BG2CD)"
23 select CACHE_L2X0
24 select CPU_V7
25 select HAVE_ARM_TWD if SMP
26
27endmenu
28
29endif
diff --git a/arch/arm/mach-berlin/Makefile b/arch/arm/mach-berlin/Makefile
new file mode 100644
index 000000000000..ab69fe956f49
--- /dev/null
+++ b/arch/arm/mach-berlin/Makefile
@@ -0,0 +1 @@
obj-y += berlin.o
diff --git a/arch/arm/mach-berlin/berlin.c b/arch/arm/mach-berlin/berlin.c
new file mode 100644
index 000000000000..025bcb5473eb
--- /dev/null
+++ b/arch/arm/mach-berlin/berlin.c
@@ -0,0 +1,39 @@
1/*
2 * Device Tree support for Marvell Berlin SoCs.
3 *
4 * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
5 *
6 * based on GPL'ed 2.6 kernel sources
7 * (c) Marvell International Ltd.
8 *
9 * This file is licensed under the terms of the GNU General Public
10 * License version 2. This program is licensed "as is" without any
11 * warranty of any kind, whether express or implied.
12 */
13
14#include <linux/init.h>
15#include <linux/io.h>
16#include <linux/kernel.h>
17#include <linux/of_platform.h>
18#include <asm/hardware/cache-l2x0.h>
19#include <asm/mach/arch.h>
20
21static void __init berlin_init_machine(void)
22{
23 /*
24 * with DT probing for L2CCs, berlin_init_machine can be removed.
25 * Note: 88DE3005 (Armada 1500-mini) uses pl310 l2cc
26 */
27 l2x0_of_init(0x70c00000, 0xfeffffff);
28 of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
29}
30
31static const char * const berlin_dt_compat[] = {
32 "marvell,berlin",
33 NULL,
34};
35
36DT_MACHINE_START(BERLIN_DT, "Marvell Berlin")
37 .dt_compat = berlin_dt_compat,
38 .init_machine = berlin_init_machine,
39MACHINE_END
diff --git a/arch/arm/mach-clps711x/common.c b/arch/arm/mach-clps711x/common.c
index 134641d688bb..a1935911e4f1 100644
--- a/arch/arm/mach-clps711x/common.c
+++ b/arch/arm/mach-clps711x/common.c
@@ -259,7 +259,7 @@ asmlinkage void __exception_irq_entry clps711x_handle_irq(struct pt_regs *regs)
259 } while (1); 259 } while (1);
260} 260}
261 261
262static u32 notrace clps711x_sched_clock_read(void) 262static u64 notrace clps711x_sched_clock_read(void)
263{ 263{
264 return ~readw_relaxed(CLPS711X_VIRT_BASE + TC1D); 264 return ~readw_relaxed(CLPS711X_VIRT_BASE + TC1D);
265} 265}
@@ -366,7 +366,7 @@ void __init clps711x_timer_init(void)
366 tmp = clps_readl(SYSCON1) & ~(SYSCON1_TC1S | SYSCON1_TC1M); 366 tmp = clps_readl(SYSCON1) & ~(SYSCON1_TC1S | SYSCON1_TC1M);
367 clps_writel(tmp, SYSCON1); 367 clps_writel(tmp, SYSCON1);
368 368
369 setup_sched_clock(clps711x_sched_clock_read, 16, timl); 369 sched_clock_register(clps711x_sched_clock_read, 16, timl);
370 370
371 clocksource_mmio_init(CLPS711X_VIRT_BASE + TC1D, 371 clocksource_mmio_init(CLPS711X_VIRT_BASE + TC1D,
372 "clps711x_clocksource", timl, 300, 16, 372 "clps711x_clocksource", timl, 300, 16,
diff --git a/arch/arm/mach-davinci/time.c b/arch/arm/mach-davinci/time.c
index 56c6eb5266ad..24ad30f32ae3 100644
--- a/arch/arm/mach-davinci/time.c
+++ b/arch/arm/mach-davinci/time.c
@@ -285,7 +285,7 @@ static struct clocksource clocksource_davinci = {
285/* 285/*
286 * Overwrite weak default sched_clock with something more precise 286 * Overwrite weak default sched_clock with something more precise
287 */ 287 */
288static u32 notrace davinci_read_sched_clock(void) 288static u64 notrace davinci_read_sched_clock(void)
289{ 289{
290 return timer32_read(&timers[TID_CLOCKSOURCE]); 290 return timer32_read(&timers[TID_CLOCKSOURCE]);
291} 291}
@@ -391,7 +391,7 @@ void __init davinci_timer_init(void)
391 davinci_clock_tick_rate)) 391 davinci_clock_tick_rate))
392 printk(err, clocksource_davinci.name); 392 printk(err, clocksource_davinci.name);
393 393
394 setup_sched_clock(davinci_read_sched_clock, 32, 394 sched_clock_register(davinci_read_sched_clock, 32,
395 davinci_clock_tick_rate); 395 davinci_clock_tick_rate);
396 396
397 /* setup clockevent */ 397 /* setup clockevent */
diff --git a/arch/arm/mach-ep93xx/Kconfig b/arch/arm/mach-ep93xx/Kconfig
index 93e54fd4e3d5..bec570ae6494 100644
--- a/arch/arm/mach-ep93xx/Kconfig
+++ b/arch/arm/mach-ep93xx/Kconfig
@@ -5,6 +5,7 @@ menu "Cirrus EP93xx Implementation Options"
5config EP93XX_SOC_COMMON 5config EP93XX_SOC_COMMON
6 bool 6 bool
7 default y 7 default y
8 select SOC_BUS
8 select LEDS_GPIO_REGISTER 9 select LEDS_GPIO_REGISTER
9 10
10config CRUNCH 11config CRUNCH
diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c
index d95ee28a616a..157ba88433c9 100644
--- a/arch/arm/mach-ep93xx/core.c
+++ b/arch/arm/mach-ep93xx/core.c
@@ -21,6 +21,7 @@
21#include <linux/platform_device.h> 21#include <linux/platform_device.h>
22#include <linux/interrupt.h> 22#include <linux/interrupt.h>
23#include <linux/dma-mapping.h> 23#include <linux/dma-mapping.h>
24#include <linux/sys_soc.h>
24#include <linux/timex.h> 25#include <linux/timex.h>
25#include <linux/irq.h> 26#include <linux/irq.h>
26#include <linux/io.h> 27#include <linux/io.h>
@@ -44,6 +45,7 @@
44#include <linux/platform_data/spi-ep93xx.h> 45#include <linux/platform_data/spi-ep93xx.h>
45#include <mach/gpio-ep93xx.h> 46#include <mach/gpio-ep93xx.h>
46 47
48#include <asm/mach/arch.h>
47#include <asm/mach/map.h> 49#include <asm/mach/map.h>
48#include <asm/mach/time.h> 50#include <asm/mach/time.h>
49 51
@@ -137,7 +139,7 @@ static irqreturn_t ep93xx_timer_interrupt(int irq, void *dev_id)
137 139
138static struct irqaction ep93xx_timer_irq = { 140static struct irqaction ep93xx_timer_irq = {
139 .name = "ep93xx timer", 141 .name = "ep93xx timer",
140 .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, 142 .flags = IRQF_TIMER | IRQF_IRQPOLL,
141 .handler = ep93xx_timer_interrupt, 143 .handler = ep93xx_timer_interrupt,
142}; 144};
143 145
@@ -925,8 +927,108 @@ void ep93xx_ide_release_gpio(struct platform_device *pdev)
925} 927}
926EXPORT_SYMBOL(ep93xx_ide_release_gpio); 928EXPORT_SYMBOL(ep93xx_ide_release_gpio);
927 929
928void __init ep93xx_init_devices(void) 930/*************************************************************************
931 * EP93xx Security peripheral
932 *************************************************************************/
933
934/*
935 * The Maverick Key is 256 bits of micro fuses blown at the factory during
936 * manufacturing to uniquely identify a part.
937 *
938 * See: http://arm.cirrus.com/forum/viewtopic.php?t=486&highlight=maverick+key
939 */
940#define EP93XX_SECURITY_REG(x) (EP93XX_SECURITY_BASE + (x))
941#define EP93XX_SECURITY_SECFLG EP93XX_SECURITY_REG(0x2400)
942#define EP93XX_SECURITY_FUSEFLG EP93XX_SECURITY_REG(0x2410)
943#define EP93XX_SECURITY_UNIQID EP93XX_SECURITY_REG(0x2440)
944#define EP93XX_SECURITY_UNIQCHK EP93XX_SECURITY_REG(0x2450)
945#define EP93XX_SECURITY_UNIQVAL EP93XX_SECURITY_REG(0x2460)
946#define EP93XX_SECURITY_SECID1 EP93XX_SECURITY_REG(0x2500)
947#define EP93XX_SECURITY_SECID2 EP93XX_SECURITY_REG(0x2504)
948#define EP93XX_SECURITY_SECCHK1 EP93XX_SECURITY_REG(0x2520)
949#define EP93XX_SECURITY_SECCHK2 EP93XX_SECURITY_REG(0x2524)
950#define EP93XX_SECURITY_UNIQID2 EP93XX_SECURITY_REG(0x2700)
951#define EP93XX_SECURITY_UNIQID3 EP93XX_SECURITY_REG(0x2704)
952#define EP93XX_SECURITY_UNIQID4 EP93XX_SECURITY_REG(0x2708)
953#define EP93XX_SECURITY_UNIQID5 EP93XX_SECURITY_REG(0x270c)
954
955static char ep93xx_soc_id[33];
956
957static const char __init *ep93xx_get_soc_id(void)
929{ 958{
959 unsigned int id, id2, id3, id4, id5;
960
961 if (__raw_readl(EP93XX_SECURITY_UNIQVAL) != 1)
962 return "bad Hamming code";
963
964 id = __raw_readl(EP93XX_SECURITY_UNIQID);
965 id2 = __raw_readl(EP93XX_SECURITY_UNIQID2);
966 id3 = __raw_readl(EP93XX_SECURITY_UNIQID3);
967 id4 = __raw_readl(EP93XX_SECURITY_UNIQID4);
968 id5 = __raw_readl(EP93XX_SECURITY_UNIQID5);
969
970 if (id != id2)
971 return "invalid";
972
973 snprintf(ep93xx_soc_id, sizeof(ep93xx_soc_id),
974 "%08x%08x%08x%08x", id2, id3, id4, id5);
975
976 return ep93xx_soc_id;
977}
978
979static const char __init *ep93xx_get_soc_rev(void)
980{
981 int rev = ep93xx_chip_revision();
982
983 switch (rev) {
984 case EP93XX_CHIP_REV_D0:
985 return "D0";
986 case EP93XX_CHIP_REV_D1:
987 return "D1";
988 case EP93XX_CHIP_REV_E0:
989 return "E0";
990 case EP93XX_CHIP_REV_E1:
991 return "E1";
992 case EP93XX_CHIP_REV_E2:
993 return "E2";
994 default:
995 return "unknown";
996 }
997}
998
999static const char __init *ep93xx_get_machine_name(void)
1000{
1001 return kasprintf(GFP_KERNEL,"%s", machine_desc->name);
1002}
1003
1004static struct device __init *ep93xx_init_soc(void)
1005{
1006 struct soc_device_attribute *soc_dev_attr;
1007 struct soc_device *soc_dev;
1008
1009 soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
1010 if (!soc_dev_attr)
1011 return NULL;
1012
1013 soc_dev_attr->machine = ep93xx_get_machine_name();
1014 soc_dev_attr->family = "Cirrus Logic EP93xx";
1015 soc_dev_attr->revision = ep93xx_get_soc_rev();
1016 soc_dev_attr->soc_id = ep93xx_get_soc_id();
1017
1018 soc_dev = soc_device_register(soc_dev_attr);
1019 if (IS_ERR(soc_dev)) {
1020 kfree(soc_dev_attr->machine);
1021 kfree(soc_dev_attr);
1022 return NULL;
1023 }
1024
1025 return soc_device_to_device(soc_dev);
1026}
1027
1028struct device __init *ep93xx_init_devices(void)
1029{
1030 struct device *parent;
1031
930 /* Disallow access to MaverickCrunch initially */ 1032 /* Disallow access to MaverickCrunch initially */
931 ep93xx_devcfg_clear_bits(EP93XX_SYSCON_DEVCFG_CPENA); 1033 ep93xx_devcfg_clear_bits(EP93XX_SYSCON_DEVCFG_CPENA);
932 1034
@@ -937,6 +1039,8 @@ void __init ep93xx_init_devices(void)
937 EP93XX_SYSCON_DEVCFG_GONIDE | 1039 EP93XX_SYSCON_DEVCFG_GONIDE |
938 EP93XX_SYSCON_DEVCFG_HONIDE); 1040 EP93XX_SYSCON_DEVCFG_HONIDE);
939 1041
1042 parent = ep93xx_init_soc();
1043
940 /* Get the GPIO working early, other devices need it */ 1044 /* Get the GPIO working early, other devices need it */
941 platform_device_register(&ep93xx_gpio_device); 1045 platform_device_register(&ep93xx_gpio_device);
942 1046
@@ -949,6 +1053,8 @@ void __init ep93xx_init_devices(void)
949 platform_device_register(&ep93xx_wdt_device); 1053 platform_device_register(&ep93xx_wdt_device);
950 1054
951 gpio_led_register_device(-1, &ep93xx_led_data); 1055 gpio_led_register_device(-1, &ep93xx_led_data);
1056
1057 return parent;
952} 1058}
953 1059
954void ep93xx_restart(enum reboot_mode mode, const char *cmd) 1060void ep93xx_restart(enum reboot_mode mode, const char *cmd)
diff --git a/arch/arm/mach-ep93xx/include/mach/platform.h b/arch/arm/mach-ep93xx/include/mach/platform.h
index e256e0baec2e..4c0bbd97f741 100644
--- a/arch/arm/mach-ep93xx/include/mach/platform.h
+++ b/arch/arm/mach-ep93xx/include/mach/platform.h
@@ -6,6 +6,7 @@
6 6
7#include <linux/reboot.h> 7#include <linux/reboot.h>
8 8
9struct device;
9struct i2c_gpio_platform_data; 10struct i2c_gpio_platform_data;
10struct i2c_board_info; 11struct i2c_board_info;
11struct spi_board_info; 12struct spi_board_info;
@@ -54,7 +55,7 @@ void ep93xx_register_ide(void);
54int ep93xx_ide_acquire_gpio(struct platform_device *pdev); 55int ep93xx_ide_acquire_gpio(struct platform_device *pdev);
55void ep93xx_ide_release_gpio(struct platform_device *pdev); 56void ep93xx_ide_release_gpio(struct platform_device *pdev);
56 57
57void ep93xx_init_devices(void); 58struct device *ep93xx_init_devices(void);
58extern void ep93xx_timer_init(void); 59extern void ep93xx_timer_init(void);
59 60
60void ep93xx_restart(enum reboot_mode, const char *); 61void ep93xx_restart(enum reboot_mode, const char *);
diff --git a/arch/arm/mach-imx/time.c b/arch/arm/mach-imx/time.c
index 9b6638aadeaa..1a3a5f615770 100644
--- a/arch/arm/mach-imx/time.c
+++ b/arch/arm/mach-imx/time.c
@@ -111,7 +111,7 @@ static void gpt_irq_acknowledge(void)
111 111
112static void __iomem *sched_clock_reg; 112static void __iomem *sched_clock_reg;
113 113
114static u32 notrace mxc_read_sched_clock(void) 114static u64 notrace mxc_read_sched_clock(void)
115{ 115{
116 return sched_clock_reg ? __raw_readl(sched_clock_reg) : 0; 116 return sched_clock_reg ? __raw_readl(sched_clock_reg) : 0;
117} 117}
@@ -123,7 +123,7 @@ static int __init mxc_clocksource_init(struct clk *timer_clk)
123 123
124 sched_clock_reg = reg; 124 sched_clock_reg = reg;
125 125
126 setup_sched_clock(mxc_read_sched_clock, 32, c); 126 sched_clock_register(mxc_read_sched_clock, 32, c);
127 return clocksource_mmio_init(reg, "mxc_timer1", c, 200, 32, 127 return clocksource_mmio_init(reg, "mxc_timer1", c, 200, 32,
128 clocksource_mmio_readl_up); 128 clocksource_mmio_readl_up);
129} 129}
diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c
index d50dc2dbfd89..473e21b87364 100644
--- a/arch/arm/mach-integrator/integrator_ap.c
+++ b/arch/arm/mach-integrator/integrator_ap.c
@@ -277,7 +277,7 @@ struct amba_pl010_data ap_uart_data = {
277 277
278static unsigned long timer_reload; 278static unsigned long timer_reload;
279 279
280static u32 notrace integrator_read_sched_clock(void) 280static u64 notrace integrator_read_sched_clock(void)
281{ 281{
282 return -readl((void __iomem *) TIMER2_VA_BASE + TIMER_VALUE); 282 return -readl((void __iomem *) TIMER2_VA_BASE + TIMER_VALUE);
283} 283}
@@ -298,7 +298,7 @@ static void integrator_clocksource_init(unsigned long inrate,
298 298
299 clocksource_mmio_init(base + TIMER_VALUE, "timer2", 299 clocksource_mmio_init(base + TIMER_VALUE, "timer2",
300 rate, 200, 16, clocksource_mmio_readl_down); 300 rate, 200, 16, clocksource_mmio_readl_down);
301 setup_sched_clock(integrator_read_sched_clock, 16, rate); 301 sched_clock_register(integrator_read_sched_clock, 16, rate);
302} 302}
303 303
304static void __iomem * clkevt_base; 304static void __iomem * clkevt_base;
diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c
index 9edaf4734fa8..bc9d8ec2918e 100644
--- a/arch/arm/mach-ixp4xx/common.c
+++ b/arch/arm/mach-ixp4xx/common.c
@@ -475,7 +475,7 @@ void __init ixp4xx_sys_init(void)
475/* 475/*
476 * sched_clock() 476 * sched_clock()
477 */ 477 */
478static u32 notrace ixp4xx_read_sched_clock(void) 478static u64 notrace ixp4xx_read_sched_clock(void)
479{ 479{
480 return *IXP4XX_OSTS; 480 return *IXP4XX_OSTS;
481} 481}
@@ -493,7 +493,7 @@ unsigned long ixp4xx_timer_freq = IXP4XX_TIMER_FREQ;
493EXPORT_SYMBOL(ixp4xx_timer_freq); 493EXPORT_SYMBOL(ixp4xx_timer_freq);
494static void __init ixp4xx_clocksource_init(void) 494static void __init ixp4xx_clocksource_init(void)
495{ 495{
496 setup_sched_clock(ixp4xx_read_sched_clock, 32, ixp4xx_timer_freq); 496 sched_clock_register(ixp4xx_read_sched_clock, 32, ixp4xx_timer_freq);
497 497
498 clocksource_mmio_init(NULL, "OSTS", ixp4xx_timer_freq, 200, 32, 498 clocksource_mmio_init(NULL, "OSTS", ixp4xx_timer_freq, 200, 32,
499 ixp4xx_clocksource_read); 499 ixp4xx_clocksource_read);
diff --git a/arch/arm/mach-mmp/time.c b/arch/arm/mach-mmp/time.c
index 7ac41e83cfef..024022d91fe3 100644
--- a/arch/arm/mach-mmp/time.c
+++ b/arch/arm/mach-mmp/time.c
@@ -61,7 +61,7 @@ static inline uint32_t timer_read(void)
61 return __raw_readl(mmp_timer_base + TMR_CVWR(1)); 61 return __raw_readl(mmp_timer_base + TMR_CVWR(1));
62} 62}
63 63
64static u32 notrace mmp_read_sched_clock(void) 64static u64 notrace mmp_read_sched_clock(void)
65{ 65{
66 return timer_read(); 66 return timer_read();
67} 67}
@@ -195,7 +195,7 @@ void __init timer_init(int irq)
195{ 195{
196 timer_config(); 196 timer_config();
197 197
198 setup_sched_clock(mmp_read_sched_clock, 32, CLOCK_TICK_RATE); 198 sched_clock_register(mmp_read_sched_clock, 32, CLOCK_TICK_RATE);
199 199
200 ckevt.cpumask = cpumask_of(0); 200 ckevt.cpumask = cpumask_of(0);
201 201
diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c
index 1e9c3383daba..fd1644987534 100644
--- a/arch/arm/mach-msm/timer.c
+++ b/arch/arm/mach-msm/timer.c
@@ -187,7 +187,7 @@ static struct notifier_block msm_timer_cpu_nb = {
187 .notifier_call = msm_timer_cpu_notify, 187 .notifier_call = msm_timer_cpu_notify,
188}; 188};
189 189
190static notrace u32 msm_sched_clock_read(void) 190static u64 notrace msm_sched_clock_read(void)
191{ 191{
192 return msm_clocksource.read(&msm_clocksource); 192 return msm_clocksource.read(&msm_clocksource);
193} 193}
@@ -229,7 +229,7 @@ err:
229 res = clocksource_register_hz(cs, dgt_hz); 229 res = clocksource_register_hz(cs, dgt_hz);
230 if (res) 230 if (res)
231 pr_err("clocksource_register failed\n"); 231 pr_err("clocksource_register failed\n");
232 setup_sched_clock(msm_sched_clock_read, sched_bits, dgt_hz); 232 sched_clock_register(msm_sched_clock_read, sched_bits, dgt_hz);
233} 233}
234 234
235#ifdef CONFIG_OF 235#ifdef CONFIG_OF
diff --git a/arch/arm/mach-omap1/time.c b/arch/arm/mach-omap1/time.c
index 6b5f298d6638..a7588cfd0286 100644
--- a/arch/arm/mach-omap1/time.c
+++ b/arch/arm/mach-omap1/time.c
@@ -181,7 +181,7 @@ static __init void omap_init_mpu_timer(unsigned long rate)
181 * --------------------------------------------------------------------------- 181 * ---------------------------------------------------------------------------
182 */ 182 */
183 183
184static u32 notrace omap_mpu_read_sched_clock(void) 184static u64 notrace omap_mpu_read_sched_clock(void)
185{ 185{
186 return ~omap_mpu_timer_read(1); 186 return ~omap_mpu_timer_read(1);
187} 187}
@@ -193,7 +193,7 @@ static void __init omap_init_clocksource(unsigned long rate)
193 "%s: can't register clocksource!\n"; 193 "%s: can't register clocksource!\n";
194 194
195 omap_mpu_timer_start(1, ~0, 1); 195 omap_mpu_timer_start(1, ~0, 1);
196 setup_sched_clock(omap_mpu_read_sched_clock, 32, rate); 196 sched_clock_register(omap_mpu_read_sched_clock, 32, rate);
197 197
198 if (clocksource_mmio_init(&timer->read_tim, "mpu_timer2", rate, 198 if (clocksource_mmio_init(&timer->read_tim, "mpu_timer2", rate,
199 300, 32, clocksource_mmio_readl_down)) 199 300, 32, clocksource_mmio_readl_down))
diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
index 3ca81e0ada5e..ec084d158f64 100644
--- a/arch/arm/mach-omap2/timer.c
+++ b/arch/arm/mach-omap2/timer.c
@@ -379,7 +379,7 @@ static struct clocksource clocksource_gpt = {
379 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 379 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
380}; 380};
381 381
382static u32 notrace dmtimer_read_sched_clock(void) 382static u64 notrace dmtimer_read_sched_clock(void)
383{ 383{
384 if (clksrc.reserved) 384 if (clksrc.reserved)
385 return __omap_dm_timer_read_counter(&clksrc, 385 return __omap_dm_timer_read_counter(&clksrc,
@@ -471,7 +471,7 @@ static void __init omap2_gptimer_clocksource_init(int gptimer_id,
471 __omap_dm_timer_load_start(&clksrc, 471 __omap_dm_timer_load_start(&clksrc,
472 OMAP_TIMER_CTRL_ST | OMAP_TIMER_CTRL_AR, 0, 472 OMAP_TIMER_CTRL_ST | OMAP_TIMER_CTRL_AR, 0,
473 OMAP_TIMER_NONPOSTED); 473 OMAP_TIMER_NONPOSTED);
474 setup_sched_clock(dmtimer_read_sched_clock, 32, clksrc.rate); 474 sched_clock_register(dmtimer_read_sched_clock, 32, clksrc.rate);
475 475
476 if (clocksource_register_hz(&clocksource_gpt, clksrc.rate)) 476 if (clocksource_register_hz(&clocksource_gpt, clksrc.rate))
477 pr_err("Could not register clocksource %s\n", 477 pr_err("Could not register clocksource %s\n",
diff --git a/arch/arm/mach-pxa/time.c b/arch/arm/mach-pxa/time.c
index 9aa852a8fab9..d1bfaa73b1c9 100644
--- a/arch/arm/mach-pxa/time.c
+++ b/arch/arm/mach-pxa/time.c
@@ -33,7 +33,7 @@
33 * calls to sched_clock() which should always be the case in practice. 33 * calls to sched_clock() which should always be the case in practice.
34 */ 34 */
35 35
36static u32 notrace pxa_read_sched_clock(void) 36static u64 notrace pxa_read_sched_clock(void)
37{ 37{
38 return readl_relaxed(OSCR); 38 return readl_relaxed(OSCR);
39} 39}
@@ -149,7 +149,7 @@ void __init pxa_timer_init(void)
149 writel_relaxed(0, OIER); 149 writel_relaxed(0, OIER);
150 writel_relaxed(OSSR_M0 | OSSR_M1 | OSSR_M2 | OSSR_M3, OSSR); 150 writel_relaxed(OSSR_M0 | OSSR_M1 | OSSR_M2 | OSSR_M3, OSSR);
151 151
152 setup_sched_clock(pxa_read_sched_clock, 32, clock_tick_rate); 152 sched_clock_register(pxa_read_sched_clock, 32, clock_tick_rate);
153 153
154 ckevt_pxa_osmr0.cpumask = cpumask_of(0); 154 ckevt_pxa_osmr0.cpumask = cpumask_of(0);
155 155
diff --git a/arch/arm/mach-sa1100/time.c b/arch/arm/mach-sa1100/time.c
index 713c86cd3d64..6fd4acb8f187 100644
--- a/arch/arm/mach-sa1100/time.c
+++ b/arch/arm/mach-sa1100/time.c
@@ -20,7 +20,7 @@
20#include <mach/hardware.h> 20#include <mach/hardware.h>
21#include <mach/irqs.h> 21#include <mach/irqs.h>
22 22
23static u32 notrace sa1100_read_sched_clock(void) 23static u64 notrace sa1100_read_sched_clock(void)
24{ 24{
25 return readl_relaxed(OSCR); 25 return readl_relaxed(OSCR);
26} 26}
@@ -122,7 +122,7 @@ void __init sa1100_timer_init(void)
122 writel_relaxed(0, OIER); 122 writel_relaxed(0, OIER);
123 writel_relaxed(OSSR_M0 | OSSR_M1 | OSSR_M2 | OSSR_M3, OSSR); 123 writel_relaxed(OSSR_M0 | OSSR_M1 | OSSR_M2 | OSSR_M3, OSSR);
124 124
125 setup_sched_clock(sa1100_read_sched_clock, 32, 3686400); 125 sched_clock_register(sa1100_read_sched_clock, 32, 3686400);
126 126
127 ckevt_sa1100_osmr0.cpumask = cpumask_of(0); 127 ckevt_sa1100_osmr0.cpumask = cpumask_of(0);
128 128
diff --git a/arch/arm/mach-u300/timer.c b/arch/arm/mach-u300/timer.c
index 9a5f9fb352ce..9724e4e7cc93 100644
--- a/arch/arm/mach-u300/timer.c
+++ b/arch/arm/mach-u300/timer.c
@@ -341,7 +341,7 @@ static struct irqaction u300_timer_irq = {
341 * stamp. (Inspired by OMAP implementation.) 341 * stamp. (Inspired by OMAP implementation.)
342 */ 342 */
343 343
344static u32 notrace u300_read_sched_clock(void) 344static u64 notrace u300_read_sched_clock(void)
345{ 345{
346 return readl(u300_timer_base + U300_TIMER_APP_GPT2CC); 346 return readl(u300_timer_base + U300_TIMER_APP_GPT2CC);
347} 347}
@@ -379,7 +379,7 @@ static void __init u300_timer_init_of(struct device_node *np)
379 clk_prepare_enable(clk); 379 clk_prepare_enable(clk);
380 rate = clk_get_rate(clk); 380 rate = clk_get_rate(clk);
381 381
382 setup_sched_clock(u300_read_sched_clock, 32, rate); 382 sched_clock_register(u300_read_sched_clock, 32, rate);
383 383
384 u300_delay_timer.read_current_timer = &u300_read_current_timer; 384 u300_delay_timer.read_current_timer = &u300_read_current_timer;
385 u300_delay_timer.freq = rate; 385 u300_delay_timer.freq = rate;
diff --git a/arch/arm/plat-iop/time.c b/arch/arm/plat-iop/time.c
index 29606bd75f3f..d70b73364a3f 100644
--- a/arch/arm/plat-iop/time.c
+++ b/arch/arm/plat-iop/time.c
@@ -54,7 +54,7 @@ static struct clocksource iop_clocksource = {
54/* 54/*
55 * IOP sched_clock() implementation via its clocksource. 55 * IOP sched_clock() implementation via its clocksource.
56 */ 56 */
57static u32 notrace iop_read_sched_clock(void) 57static u64 notrace iop_read_sched_clock(void)
58{ 58{
59 return 0xffffffffu - read_tcr1(); 59 return 0xffffffffu - read_tcr1();
60} 60}
@@ -142,7 +142,7 @@ void __init iop_init_time(unsigned long tick_rate)
142{ 142{
143 u32 timer_ctl; 143 u32 timer_ctl;
144 144
145 setup_sched_clock(iop_read_sched_clock, 32, tick_rate); 145 sched_clock_register(iop_read_sched_clock, 32, tick_rate);
146 146
147 ticks_per_jiffy = DIV_ROUND_CLOSEST(tick_rate, HZ); 147 ticks_per_jiffy = DIV_ROUND_CLOSEST(tick_rate, HZ);
148 iop_tick_rate = tick_rate; 148 iop_tick_rate = tick_rate;
diff --git a/arch/arm/plat-omap/counter_32k.c b/arch/arm/plat-omap/counter_32k.c
index d9bc98eb2a6b..384a776d8eb2 100644
--- a/arch/arm/plat-omap/counter_32k.c
+++ b/arch/arm/plat-omap/counter_32k.c
@@ -38,7 +38,7 @@
38 */ 38 */
39static void __iomem *sync32k_cnt_reg; 39static void __iomem *sync32k_cnt_reg;
40 40
41static u32 notrace omap_32k_read_sched_clock(void) 41static u64 notrace omap_32k_read_sched_clock(void)
42{ 42{
43 return sync32k_cnt_reg ? __raw_readl(sync32k_cnt_reg) : 0; 43 return sync32k_cnt_reg ? __raw_readl(sync32k_cnt_reg) : 0;
44} 44}
@@ -115,7 +115,7 @@ int __init omap_init_clocksource_32k(void __iomem *vbase)
115 return ret; 115 return ret;
116 } 116 }
117 117
118 setup_sched_clock(omap_32k_read_sched_clock, 32, 32768); 118 sched_clock_register(omap_32k_read_sched_clock, 32, 32768);
119 register_persistent_clock(NULL, omap_read_persistent_clock); 119 register_persistent_clock(NULL, omap_read_persistent_clock);
120 pr_info("OMAP clocksource: 32k_counter at 32768 Hz\n"); 120 pr_info("OMAP clocksource: 32k_counter at 32768 Hz\n");
121 121
diff --git a/arch/arm/plat-orion/time.c b/arch/arm/plat-orion/time.c
index 9d2b2ac74938..dade2920e9a6 100644
--- a/arch/arm/plat-orion/time.c
+++ b/arch/arm/plat-orion/time.c
@@ -60,7 +60,7 @@ static u32 ticks_per_jiffy;
60 * at least 7.5ns (133MHz TCLK). 60 * at least 7.5ns (133MHz TCLK).
61 */ 61 */
62 62
63static u32 notrace orion_read_sched_clock(void) 63static u64 notrace orion_read_sched_clock(void)
64{ 64{
65 return ~readl(timer_base + TIMER0_VAL_OFF); 65 return ~readl(timer_base + TIMER0_VAL_OFF);
66} 66}
@@ -201,7 +201,7 @@ orion_time_init(void __iomem *_bridge_base, u32 _bridge_timer1_clr_mask,
201 /* 201 /*
202 * Set scale and timer for sched_clock. 202 * Set scale and timer for sched_clock.
203 */ 203 */
204 setup_sched_clock(orion_read_sched_clock, 32, tclk); 204 sched_clock_register(orion_read_sched_clock, 32, tclk);
205 205
206 /* 206 /*
207 * Setup free-running clocksource timer (interrupts 207 * Setup free-running clocksource timer (interrupts
diff --git a/arch/arm/plat-versatile/sched-clock.c b/arch/arm/plat-versatile/sched-clock.c
index 51b109e3b6c3..c966ae90f4a0 100644
--- a/arch/arm/plat-versatile/sched-clock.c
+++ b/arch/arm/plat-versatile/sched-clock.c
@@ -26,7 +26,7 @@
26 26
27static void __iomem *ctr; 27static void __iomem *ctr;
28 28
29static u32 notrace versatile_read_sched_clock(void) 29static u64 notrace versatile_read_sched_clock(void)
30{ 30{
31 if (ctr) 31 if (ctr)
32 return readl(ctr); 32 return readl(ctr);
@@ -37,5 +37,5 @@ static u32 notrace versatile_read_sched_clock(void)
37void __init versatile_sched_clock_init(void __iomem *reg, unsigned long rate) 37void __init versatile_sched_clock_init(void __iomem *reg, unsigned long rate)
38{ 38{
39 ctr = reg; 39 ctr = reg;
40 setup_sched_clock(versatile_read_sched_clock, 32, rate); 40 sched_clock_register(versatile_read_sched_clock, 32, rate);
41} 41}
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index 3792a1aa52b8..940638ddc982 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -30,6 +30,10 @@ config ARM_VIC_NR
30 The maximum number of VICs available in the system, for 30 The maximum number of VICs available in the system, for
31 power management. 31 power management.
32 32
33config DW_APB_ICTL
34 bool
35 select IRQ_DOMAIN
36
33config IMGPDC_IRQ 37config IMGPDC_IRQ
34 bool 38 bool
35 select GENERIC_IRQ_CHIP 39 select GENERIC_IRQ_CHIP
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index c60b9010b152..6427323af4c3 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -6,6 +6,7 @@ obj-$(CONFIG_ARCH_MMP) += irq-mmp.o
6obj-$(CONFIG_ARCH_MVEBU) += irq-armada-370-xp.o 6obj-$(CONFIG_ARCH_MVEBU) += irq-armada-370-xp.o
7obj-$(CONFIG_ARCH_MXS) += irq-mxs.o 7obj-$(CONFIG_ARCH_MXS) += irq-mxs.o
8obj-$(CONFIG_ARCH_S3C24XX) += irq-s3c24xx.o 8obj-$(CONFIG_ARCH_S3C24XX) += irq-s3c24xx.o
9obj-$(CONFIG_DW_APB_ICTL) += irq-dw-apb-ictl.o
9obj-$(CONFIG_METAG) += irq-metag-ext.o 10obj-$(CONFIG_METAG) += irq-metag-ext.o
10obj-$(CONFIG_METAG_PERFCOUNTER_IRQS) += irq-metag.o 11obj-$(CONFIG_METAG_PERFCOUNTER_IRQS) += irq-metag.o
11obj-$(CONFIG_ARCH_MOXART) += irq-moxart.o 12obj-$(CONFIG_ARCH_MOXART) += irq-moxart.o
diff --git a/drivers/irqchip/irq-dw-apb-ictl.c b/drivers/irqchip/irq-dw-apb-ictl.c
new file mode 100644
index 000000000000..31e231e1f566
--- /dev/null
+++ b/drivers/irqchip/irq-dw-apb-ictl.c
@@ -0,0 +1,150 @@
1/*
2 * Synopsys DW APB ICTL irqchip driver.
3 *
4 * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
5 *
6 * based on GPL'ed 2.6 kernel sources
7 * (c) Marvell International Ltd.
8 *
9 * This file is licensed under the terms of the GNU General Public
10 * License version 2. This program is licensed "as is" without any
11 * warranty of any kind, whether express or implied.
12 */
13
14#include <linux/io.h>
15#include <linux/irq.h>
16#include <linux/irqchip/chained_irq.h>
17#include <linux/of_address.h>
18#include <linux/of_irq.h>
19
20#include "irqchip.h"
21
22#define APB_INT_ENABLE_L 0x00
23#define APB_INT_ENABLE_H 0x04
24#define APB_INT_MASK_L 0x08
25#define APB_INT_MASK_H 0x0c
26#define APB_INT_FINALSTATUS_L 0x30
27#define APB_INT_FINALSTATUS_H 0x34
28
29static void dw_apb_ictl_handler(unsigned int irq, struct irq_desc *desc)
30{
31 struct irq_chip *chip = irq_get_chip(irq);
32 struct irq_chip_generic *gc = irq_get_handler_data(irq);
33 struct irq_domain *d = gc->private;
34 u32 stat;
35 int n;
36
37 chained_irq_enter(chip, desc);
38
39 for (n = 0; n < gc->num_ct; n++) {
40 stat = readl_relaxed(gc->reg_base +
41 APB_INT_FINALSTATUS_L + 4 * n);
42 while (stat) {
43 u32 hwirq = ffs(stat) - 1;
44 generic_handle_irq(irq_find_mapping(d,
45 gc->irq_base + hwirq + 32 * n));
46 stat &= ~(1 << hwirq);
47 }
48 }
49
50 chained_irq_exit(chip, desc);
51}
52
53static int __init dw_apb_ictl_init(struct device_node *np,
54 struct device_node *parent)
55{
56 unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN;
57 struct resource r;
58 struct irq_domain *domain;
59 struct irq_chip_generic *gc;
60 void __iomem *iobase;
61 int ret, nrirqs, irq;
62 u32 reg;
63
64 /* Map the parent interrupt for the chained handler */
65 irq = irq_of_parse_and_map(np, 0);
66 if (irq <= 0) {
67 pr_err("%s: unable to parse irq\n", np->full_name);
68 return -EINVAL;
69 }
70
71 ret = of_address_to_resource(np, 0, &r);
72 if (ret) {
73 pr_err("%s: unable to get resource\n", np->full_name);
74 return ret;
75 }
76
77 if (!request_mem_region(r.start, resource_size(&r), np->full_name)) {
78 pr_err("%s: unable to request mem region\n", np->full_name);
79 return -ENOMEM;
80 }
81
82 iobase = ioremap(r.start, resource_size(&r));
83 if (!iobase) {
84 pr_err("%s: unable to map resource\n", np->full_name);
85 ret = -ENOMEM;
86 goto err_release;
87 }
88
89 /*
90 * DW IP can be configured to allow 2-64 irqs. We can determine
91 * the number of irqs supported by writing into enable register
92 * and look for bits not set, as corresponding flip-flops will
93 * have been removed by sythesis tool.
94 */
95
96 /* mask and enable all interrupts */
97 writel(~0, iobase + APB_INT_MASK_L);
98 writel(~0, iobase + APB_INT_MASK_H);
99 writel(~0, iobase + APB_INT_ENABLE_L);
100 writel(~0, iobase + APB_INT_ENABLE_H);
101
102 reg = readl(iobase + APB_INT_ENABLE_H);
103 if (reg)
104 nrirqs = 32 + fls(reg);
105 else
106 nrirqs = fls(readl(iobase + APB_INT_ENABLE_L));
107
108 domain = irq_domain_add_linear(np, nrirqs,
109 &irq_generic_chip_ops, NULL);
110 if (!domain) {
111 pr_err("%s: unable to add irq domain\n", np->full_name);
112 ret = -ENOMEM;
113 goto err_unmap;
114 }
115
116 ret = irq_alloc_domain_generic_chips(domain, 32, (nrirqs > 32) ? 2 : 1,
117 np->name, handle_level_irq, clr, 0,
118 IRQ_GC_INIT_MASK_CACHE);
119 if (ret) {
120 pr_err("%s: unable to alloc irq domain gc\n", np->full_name);
121 goto err_unmap;
122 }
123
124 gc = irq_get_domain_generic_chip(domain, 0);
125 gc->private = domain;
126 gc->reg_base = iobase;
127
128 gc->chip_types[0].regs.mask = APB_INT_MASK_L;
129 gc->chip_types[0].chip.irq_mask = irq_gc_mask_set_bit;
130 gc->chip_types[0].chip.irq_unmask = irq_gc_mask_clr_bit;
131
132 if (nrirqs > 32) {
133 gc->chip_types[1].regs.mask = APB_INT_MASK_H;
134 gc->chip_types[1].chip.irq_mask = irq_gc_mask_set_bit;
135 gc->chip_types[1].chip.irq_unmask = irq_gc_mask_clr_bit;
136 }
137
138 irq_set_handler_data(irq, gc);
139 irq_set_chained_handler(irq, dw_apb_ictl_handler);
140
141 return 0;
142
143err_unmap:
144 iounmap(iobase);
145err_release:
146 release_mem_region(r.start, resource_size(&r));
147 return ret;
148}
149IRQCHIP_DECLARE(dw_apb_ictl,
150 "snps,dw-apb-ictl", dw_apb_ictl_init);