diff options
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 | ||
214 | Berlin 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 | |||
214 | Long-term plans | 238 | Long-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 @@ | |||
1 | Marvell Berlin SoC Family Device Tree Bindings | ||
2 | --------------------------------------------------------------- | ||
3 | |||
4 | Boards with a SoC of the Marvell Berlin family, e.g. Armada 1500 | ||
5 | shall have the following properties: | ||
6 | |||
7 | * Required root node properties: | ||
8 | compatible: must contain "marvell,berlin" | ||
9 | |||
10 | In addition, the above compatible shall be extended with the specific | ||
11 | SoC 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 @@ | |||
1 | Synopsys DesignWare APB interrupt controller (dw_apb_ictl) | ||
2 | |||
3 | Synopsys DesignWare provides interrupt controller IP for APB known as | ||
4 | dw_apb_ictl. The IP is used as secondary interrupt controller in some SoCs with | ||
5 | APB bus, e.g. Marvell Armada 1500. | ||
6 | |||
7 | Required 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 | |||
16 | The interrupt sources map to the corresponding bits in the interrupt | ||
17 | registers, 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 | |||
24 | Example: | ||
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) | |||
1027 | S: Maintained | 1027 | S: Maintained |
1028 | F: arch/arm/mach-mvebu/ | 1028 | F: arch/arm/mach-mvebu/ |
1029 | 1029 | ||
1030 | ARM/Marvell Berlin SoC support | ||
1031 | M: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> | ||
1032 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | ||
1033 | S: Maintained | ||
1034 | F: arch/arm/mach-berlin/ | ||
1035 | |||
1030 | ARM/Marvell Dove/Kirkwood/MV78xx0/Orion SOC support | 1036 | ARM/Marvell Dove/Kirkwood/MV78xx0/Orion SOC support |
1031 | M: Jason Cooper <jason@lakedaemon.net> | 1037 | M: Jason Cooper <jason@lakedaemon.net> |
1032 | M: Andrew Lunn <andrew@lunn.ch> | 1038 | M: 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 | ||
932 | source "arch/arm/mach-bcm2835/Kconfig" | 932 | source "arch/arm/mach-bcm2835/Kconfig" |
933 | 933 | ||
934 | source "arch/arm/mach-berlin/Kconfig" | ||
935 | |||
934 | source "arch/arm/mach-clps711x/Kconfig" | 936 | source "arch/arm/mach-clps711x/Kconfig" |
935 | 937 | ||
936 | source "arch/arm/mach-cns3xxx/Kconfig" | 938 | source "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 | |||
148 | machine-$(CONFIG_ARCH_AT91) += at91 | 148 | machine-$(CONFIG_ARCH_AT91) += at91 |
149 | machine-$(CONFIG_ARCH_BCM) += bcm | 149 | machine-$(CONFIG_ARCH_BCM) += bcm |
150 | machine-$(CONFIG_ARCH_BCM2835) += bcm2835 | 150 | machine-$(CONFIG_ARCH_BCM2835) += bcm2835 |
151 | machine-$(CONFIG_ARCH_BERLIN) += berlin | ||
151 | machine-$(CONFIG_ARCH_CLPS711X) += clps711x | 152 | machine-$(CONFIG_ARCH_CLPS711X) += clps711x |
152 | machine-$(CONFIG_ARCH_CNS3XXX) += cns3xxx | 153 | machine-$(CONFIG_ARCH_CNS3XXX) += cns3xxx |
153 | machine-$(CONFIG_ARCH_DAVINCI) += davinci | 154 | machine-$(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 | |||
45 | dtb-$(CONFIG_ARCH_BCM_MOBILE) += bcm11351-brt.dtb \ | 45 | dtb-$(CONFIG_ARCH_BCM_MOBILE) += bcm11351-brt.dtb \ |
46 | bcm28155-ap.dtb | 46 | bcm28155-ap.dtb |
47 | dtb-$(CONFIG_ARCH_BCM2835) += bcm2835-rpi-b.dtb | 47 | dtb-$(CONFIG_ARCH_BCM2835) += bcm2835-rpi-b.dtb |
48 | dtb-$(CONFIG_ARCH_BERLIN) += \ | ||
49 | berlin2-sony-nsz-gs7.dtb \ | ||
50 | berlin2cd-google-chromecast.dtb | ||
48 | dtb-$(CONFIG_ARCH_DAVINCI) += da850-enbw-cmc.dtb \ | 51 | dtb-$(CONFIG_ARCH_DAVINCI) += da850-enbw-cmc.dtb \ |
49 | da850-evm.dtb | 52 | da850-evm.dtb |
50 | dtb-$(CONFIG_ARCH_DOVE) += dove-cm-a510.dtb \ | 53 | dtb-$(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 | ||
67 | static void __iomem *sched_clock_base; | 67 | static void __iomem *sched_clock_base; |
68 | 68 | ||
69 | static u32 sp804_read(void) | 69 | static 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 | |||
7 | CONFIG_MACH_ARMADA_XP=y | 7 | CONFIG_MACH_ARMADA_XP=y |
8 | CONFIG_ARCH_BCM=y | 8 | CONFIG_ARCH_BCM=y |
9 | CONFIG_ARCH_BCM_MOBILE=y | 9 | CONFIG_ARCH_BCM_MOBILE=y |
10 | CONFIG_ARCH_BERLIN=y | ||
11 | CONFIG_MACH_BERLIN_BG2=y | ||
12 | CONFIG_MACH_BERLIN_BG2CD=y | ||
10 | CONFIG_GPIO_PCA953X=y | 13 | CONFIG_GPIO_PCA953X=y |
11 | CONFIG_ARCH_HIGHBANK=y | 14 | CONFIG_ARCH_HIGHBANK=y |
12 | CONFIG_ARCH_KEYSTONE=y | 15 | CONFIG_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. |
71 | endif | 71 | endif |
72 | 72 | ||
73 | if SOC_SAM_V4_V5 | 73 | if 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 @@ | |||
1 | config 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 | |||
10 | if ARCH_BERLIN | ||
11 | |||
12 | menu "Marvell Berlin SoC variants" | ||
13 | |||
14 | config 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 | |||
21 | config 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 | |||
27 | endmenu | ||
28 | |||
29 | endif | ||
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 | |||
21 | static 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 | |||
31 | static const char * const berlin_dt_compat[] = { | ||
32 | "marvell,berlin", | ||
33 | NULL, | ||
34 | }; | ||
35 | |||
36 | DT_MACHINE_START(BERLIN_DT, "Marvell Berlin") | ||
37 | .dt_compat = berlin_dt_compat, | ||
38 | .init_machine = berlin_init_machine, | ||
39 | MACHINE_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 | ||
262 | static u32 notrace clps711x_sched_clock_read(void) | 262 | static 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 | */ |
288 | static u32 notrace davinci_read_sched_clock(void) | 288 | static 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" | |||
5 | config EP93XX_SOC_COMMON | 5 | config 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 | ||
10 | config CRUNCH | 11 | config 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 | ||
138 | static struct irqaction ep93xx_timer_irq = { | 140 | static 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 | } |
926 | EXPORT_SYMBOL(ep93xx_ide_release_gpio); | 928 | EXPORT_SYMBOL(ep93xx_ide_release_gpio); |
927 | 929 | ||
928 | void __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 | |||
955 | static char ep93xx_soc_id[33]; | ||
956 | |||
957 | static 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 | |||
979 | static 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 | |||
999 | static const char __init *ep93xx_get_machine_name(void) | ||
1000 | { | ||
1001 | return kasprintf(GFP_KERNEL,"%s", machine_desc->name); | ||
1002 | } | ||
1003 | |||
1004 | static 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 | |||
1028 | struct 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 | ||
954 | void ep93xx_restart(enum reboot_mode mode, const char *cmd) | 1060 | void 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 | ||
9 | struct device; | ||
9 | struct i2c_gpio_platform_data; | 10 | struct i2c_gpio_platform_data; |
10 | struct i2c_board_info; | 11 | struct i2c_board_info; |
11 | struct spi_board_info; | 12 | struct spi_board_info; |
@@ -54,7 +55,7 @@ void ep93xx_register_ide(void); | |||
54 | int ep93xx_ide_acquire_gpio(struct platform_device *pdev); | 55 | int ep93xx_ide_acquire_gpio(struct platform_device *pdev); |
55 | void ep93xx_ide_release_gpio(struct platform_device *pdev); | 56 | void ep93xx_ide_release_gpio(struct platform_device *pdev); |
56 | 57 | ||
57 | void ep93xx_init_devices(void); | 58 | struct device *ep93xx_init_devices(void); |
58 | extern void ep93xx_timer_init(void); | 59 | extern void ep93xx_timer_init(void); |
59 | 60 | ||
60 | void ep93xx_restart(enum reboot_mode, const char *); | 61 | void 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 | ||
112 | static void __iomem *sched_clock_reg; | 112 | static void __iomem *sched_clock_reg; |
113 | 113 | ||
114 | static u32 notrace mxc_read_sched_clock(void) | 114 | static 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 | ||
278 | static unsigned long timer_reload; | 278 | static unsigned long timer_reload; |
279 | 279 | ||
280 | static u32 notrace integrator_read_sched_clock(void) | 280 | static 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 | ||
304 | static void __iomem * clkevt_base; | 304 | static 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 | */ |
478 | static u32 notrace ixp4xx_read_sched_clock(void) | 478 | static 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; | |||
493 | EXPORT_SYMBOL(ixp4xx_timer_freq); | 493 | EXPORT_SYMBOL(ixp4xx_timer_freq); |
494 | static void __init ixp4xx_clocksource_init(void) | 494 | static 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 | ||
64 | static u32 notrace mmp_read_sched_clock(void) | 64 | static 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 | ||
190 | static notrace u32 msm_sched_clock_read(void) | 190 | static 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 | ||
184 | static u32 notrace omap_mpu_read_sched_clock(void) | 184 | static 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 | ||
382 | static u32 notrace dmtimer_read_sched_clock(void) | 382 | static 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 | ||
36 | static u32 notrace pxa_read_sched_clock(void) | 36 | static 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 | ||
23 | static u32 notrace sa1100_read_sched_clock(void) | 23 | static 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 | ||
344 | static u32 notrace u300_read_sched_clock(void) | 344 | static 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 | */ |
57 | static u32 notrace iop_read_sched_clock(void) | 57 | static 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 | */ |
39 | static void __iomem *sync32k_cnt_reg; | 39 | static void __iomem *sync32k_cnt_reg; |
40 | 40 | ||
41 | static u32 notrace omap_32k_read_sched_clock(void) | 41 | static 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 | ||
63 | static u32 notrace orion_read_sched_clock(void) | 63 | static 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 | ||
27 | static void __iomem *ctr; | 27 | static void __iomem *ctr; |
28 | 28 | ||
29 | static u32 notrace versatile_read_sched_clock(void) | 29 | static 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) | |||
37 | void __init versatile_sched_clock_init(void __iomem *reg, unsigned long rate) | 37 | void __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 | ||
33 | config DW_APB_ICTL | ||
34 | bool | ||
35 | select IRQ_DOMAIN | ||
36 | |||
33 | config IMGPDC_IRQ | 37 | config 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 | |||
6 | obj-$(CONFIG_ARCH_MVEBU) += irq-armada-370-xp.o | 6 | obj-$(CONFIG_ARCH_MVEBU) += irq-armada-370-xp.o |
7 | obj-$(CONFIG_ARCH_MXS) += irq-mxs.o | 7 | obj-$(CONFIG_ARCH_MXS) += irq-mxs.o |
8 | obj-$(CONFIG_ARCH_S3C24XX) += irq-s3c24xx.o | 8 | obj-$(CONFIG_ARCH_S3C24XX) += irq-s3c24xx.o |
9 | obj-$(CONFIG_DW_APB_ICTL) += irq-dw-apb-ictl.o | ||
9 | obj-$(CONFIG_METAG) += irq-metag-ext.o | 10 | obj-$(CONFIG_METAG) += irq-metag-ext.o |
10 | obj-$(CONFIG_METAG_PERFCOUNTER_IRQS) += irq-metag.o | 11 | obj-$(CONFIG_METAG_PERFCOUNTER_IRQS) += irq-metag.o |
11 | obj-$(CONFIG_ARCH_MOXART) += irq-moxart.o | 12 | obj-$(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 | |||
29 | static 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 | |||
53 | static 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 | |||
143 | err_unmap: | ||
144 | iounmap(iobase); | ||
145 | err_release: | ||
146 | release_mem_region(r.start, resource_size(&r)); | ||
147 | return ret; | ||
148 | } | ||
149 | IRQCHIP_DECLARE(dw_apb_ictl, | ||
150 | "snps,dw-apb-ictl", dw_apb_ictl_init); | ||