diff options
author | Olof Johansson <olof@lixom.net> | 2013-01-28 02:03:42 -0500 |
---|---|---|
committer | Olof Johansson <olof@lixom.net> | 2013-01-28 02:03:42 -0500 |
commit | af70fdc947dbe835acc26c6ee9e8e930f38935f8 (patch) | |
tree | 9924e9f2732e3cf3c7a882cb11377247729891ab /arch | |
parent | 66eae035dc59755c51ad3b3c718a5ed7535322e3 (diff) | |
parent | 7f46a10724e0d31c83029436e54298be2cc558fa (diff) |
Merge branch 'marco-timer-cleanup-rebase' of git://gitorious.org/sirfprima2-kernel/sirfprima2-kernel into next/soc
From Barry Song, this adds support for a new SoC from CSR; marco. It's
SMP, uses GIC instead of VIC and in general needs a bit of rework of
the platform code for setup, which this branch contains.
* 'marco-timer-cleanup-rebase' of git://gitorious.org/sirfprima2-kernel/sirfprima2-kernel:
ARM: PRIMA2: provide two DEBUG_LL ports for prima2 and marco
ARM: PRIMA2: add new SiRFmarco SMP SoC infrastructures
ARM: PRIMA2: irq: make prima2 irq can work even we enable GIC for Marco
ARM: PRIMA2: rtciobg: it is also compatible with marco
ARM: PRIMA2: rstc: enable the support for Marco
ARM: PRIMA2: mv timer to timer-prima2 as we will add timer-marco
ARM: PRIMA2: initialize l2x0 according to mach from DT
ARM: PRIMA2: enable AUTO_ZRELADDR for SIRF in Kconfig
ARM: PRIMA2: add CSR SiRFmarco device tree .dts
Signed-off-by: Olof Johansson <olof@lixom.net>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/Kconfig | 1 | ||||
-rw-r--r-- | arch/arm/Kconfig.debug | 14 | ||||
-rw-r--r-- | arch/arm/boot/dts/Makefile | 1 | ||||
-rw-r--r-- | arch/arm/boot/dts/marco-evb.dts | 54 | ||||
-rw-r--r-- | arch/arm/boot/dts/marco.dtsi | 756 | ||||
-rw-r--r-- | arch/arm/configs/prima2_defconfig | 3 | ||||
-rw-r--r-- | arch/arm/mach-prima2/Kconfig | 10 | ||||
-rw-r--r-- | arch/arm/mach-prima2/Makefile | 5 | ||||
-rw-r--r-- | arch/arm/mach-prima2/common.c | 45 | ||||
-rw-r--r-- | arch/arm/mach-prima2/common.h | 15 | ||||
-rw-r--r-- | arch/arm/mach-prima2/headsmp.S | 79 | ||||
-rw-r--r-- | arch/arm/mach-prima2/hotplug.c | 41 | ||||
-rw-r--r-- | arch/arm/mach-prima2/include/mach/irqs.h | 4 | ||||
-rw-r--r-- | arch/arm/mach-prima2/include/mach/uart.h | 6 | ||||
-rw-r--r-- | arch/arm/mach-prima2/include/mach/uncompress.h | 3 | ||||
-rw-r--r-- | arch/arm/mach-prima2/irq.c | 16 | ||||
-rw-r--r-- | arch/arm/mach-prima2/l2x0.c | 29 | ||||
-rw-r--r-- | arch/arm/mach-prima2/platsmp.c | 163 | ||||
-rw-r--r-- | arch/arm/mach-prima2/rstc.c | 45 | ||||
-rw-r--r-- | arch/arm/mach-prima2/rtciobrg.c | 1 | ||||
-rw-r--r-- | arch/arm/mach-prima2/timer-marco.c | 316 | ||||
-rw-r--r-- | arch/arm/mach-prima2/timer-prima2.c (renamed from arch/arm/mach-prima2/timer.c) | 6 |
22 files changed, 1580 insertions, 33 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 31fe86d52608..a3ffd1a391a7 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
@@ -393,6 +393,7 @@ config ARCH_GEMINI | |||
393 | config ARCH_SIRF | 393 | config ARCH_SIRF |
394 | bool "CSR SiRF" | 394 | bool "CSR SiRF" |
395 | select ARCH_REQUIRE_GPIOLIB | 395 | select ARCH_REQUIRE_GPIOLIB |
396 | select AUTO_ZRELADDR | ||
396 | select COMMON_CLK | 397 | select COMMON_CLK |
397 | select GENERIC_CLOCKEVENTS | 398 | select GENERIC_CLOCKEVENTS |
398 | select GENERIC_IRQ_CHIP | 399 | select GENERIC_IRQ_CHIP |
diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug index bbb0a670cd1a..af3987cb9e4d 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug | |||
@@ -386,6 +386,20 @@ choice | |||
386 | Say Y here if you want kernel low-level debugging support | 386 | Say Y here if you want kernel low-level debugging support |
387 | on Tegra based platforms. | 387 | on Tegra based platforms. |
388 | 388 | ||
389 | config DEBUG_SIRFPRIMA2_UART1 | ||
390 | bool "Kernel low-level debugging messages via SiRFprimaII UART1" | ||
391 | depends on ARCH_PRIMA2 | ||
392 | help | ||
393 | Say Y here if you want the debug print routines to direct | ||
394 | their output to the uart1 port on SiRFprimaII devices. | ||
395 | |||
396 | config DEBUG_SIRFMARCO_UART1 | ||
397 | bool "Kernel low-level debugging messages via SiRFmarco UART1" | ||
398 | depends on ARCH_MARCO | ||
399 | help | ||
400 | Say Y here if you want the debug print routines to direct | ||
401 | their output to the uart1 port on SiRFmarco devices. | ||
402 | |||
389 | config DEBUG_VEXPRESS_UART0_DETECT | 403 | config DEBUG_VEXPRESS_UART0_DETECT |
390 | bool "Autodetect UART0 on Versatile Express Cortex-A core tiles" | 404 | bool "Autodetect UART0 on Versatile Express Cortex-A core tiles" |
391 | depends on ARCH_VEXPRESS && CPU_CP15_MMU | 405 | depends on ARCH_VEXPRESS && CPU_CP15_MMU |
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile index 3212573b94e7..b34479014f9e 100644 --- a/arch/arm/boot/dts/Makefile +++ b/arch/arm/boot/dts/Makefile | |||
@@ -73,6 +73,7 @@ dtb-$(CONFIG_ARCH_KIRKWOOD) += kirkwood-dns320.dtb \ | |||
73 | kirkwood-ts219-6281.dtb \ | 73 | kirkwood-ts219-6281.dtb \ |
74 | kirkwood-ts219-6282.dtb \ | 74 | kirkwood-ts219-6282.dtb \ |
75 | kirkwood-openblocks_a6.dtb | 75 | kirkwood-openblocks_a6.dtb |
76 | dtb-$(CONFIG_ARCH_MARCO) += marco-evb.dtb | ||
76 | dtb-$(CONFIG_ARCH_MSM) += msm8660-surf.dtb \ | 77 | dtb-$(CONFIG_ARCH_MSM) += msm8660-surf.dtb \ |
77 | msm8960-cdp.dtb | 78 | msm8960-cdp.dtb |
78 | dtb-$(CONFIG_ARCH_MVEBU) += armada-370-db.dtb \ | 79 | dtb-$(CONFIG_ARCH_MVEBU) += armada-370-db.dtb \ |
diff --git a/arch/arm/boot/dts/marco-evb.dts b/arch/arm/boot/dts/marco-evb.dts new file mode 100644 index 000000000000..5130aeacfca5 --- /dev/null +++ b/arch/arm/boot/dts/marco-evb.dts | |||
@@ -0,0 +1,54 @@ | |||
1 | /* | ||
2 | * DTS file for CSR SiRFmarco Evaluation Board | ||
3 | * | ||
4 | * Copyright (c) 2012 Cambridge Silicon Radio Limited, a CSR plc group company. | ||
5 | * | ||
6 | * Licensed under GPLv2 or later. | ||
7 | */ | ||
8 | |||
9 | /dts-v1/; | ||
10 | |||
11 | /include/ "marco.dtsi" | ||
12 | |||
13 | / { | ||
14 | model = "CSR SiRFmarco Evaluation Board"; | ||
15 | compatible = "sirf,marco-cb", "sirf,marco"; | ||
16 | |||
17 | memory { | ||
18 | reg = <0x40000000 0x60000000>; | ||
19 | }; | ||
20 | |||
21 | axi { | ||
22 | peri-iobg { | ||
23 | uart1: uart@cc060000 { | ||
24 | status = "okay"; | ||
25 | }; | ||
26 | uart2: uart@cc070000 { | ||
27 | status = "okay"; | ||
28 | }; | ||
29 | i2c0: i2c@cc0e0000 { | ||
30 | status = "okay"; | ||
31 | fpga-cpld@4d { | ||
32 | compatible = "sirf,fpga-cpld"; | ||
33 | reg = <0x4d>; | ||
34 | }; | ||
35 | }; | ||
36 | spi1: spi@cc170000 { | ||
37 | status = "okay"; | ||
38 | pinctrl-names = "default"; | ||
39 | pinctrl-0 = <&spi1_pins_a>; | ||
40 | spi@0 { | ||
41 | compatible = "spidev"; | ||
42 | reg = <0>; | ||
43 | spi-max-frequency = <1000000>; | ||
44 | }; | ||
45 | }; | ||
46 | pci-iobg { | ||
47 | sd0: sdhci@cd000000 { | ||
48 | bus-width = <8>; | ||
49 | status = "okay"; | ||
50 | }; | ||
51 | }; | ||
52 | }; | ||
53 | }; | ||
54 | }; | ||
diff --git a/arch/arm/boot/dts/marco.dtsi b/arch/arm/boot/dts/marco.dtsi new file mode 100644 index 000000000000..1579c3491ccd --- /dev/null +++ b/arch/arm/boot/dts/marco.dtsi | |||
@@ -0,0 +1,756 @@ | |||
1 | /* | ||
2 | * DTS file for CSR SiRFmarco SoC | ||
3 | * | ||
4 | * Copyright (c) 2012 Cambridge Silicon Radio Limited, a CSR plc group company. | ||
5 | * | ||
6 | * Licensed under GPLv2 or later. | ||
7 | */ | ||
8 | |||
9 | /include/ "skeleton.dtsi" | ||
10 | / { | ||
11 | compatible = "sirf,marco"; | ||
12 | #address-cells = <1>; | ||
13 | #size-cells = <1>; | ||
14 | interrupt-parent = <&gic>; | ||
15 | |||
16 | cpus { | ||
17 | #address-cells = <1>; | ||
18 | #size-cells = <0>; | ||
19 | |||
20 | cpu@0 { | ||
21 | device_type = "cpu"; | ||
22 | compatible = "arm,cortex-a9"; | ||
23 | reg = <0>; | ||
24 | }; | ||
25 | cpu@1 { | ||
26 | device_type = "cpu"; | ||
27 | compatible = "arm,cortex-a9"; | ||
28 | reg = <1>; | ||
29 | }; | ||
30 | }; | ||
31 | |||
32 | axi { | ||
33 | compatible = "simple-bus"; | ||
34 | #address-cells = <1>; | ||
35 | #size-cells = <1>; | ||
36 | ranges = <0x40000000 0x40000000 0xa0000000>; | ||
37 | |||
38 | l2-cache-controller@c0030000 { | ||
39 | compatible = "sirf,marco-pl310-cache", "arm,pl310-cache"; | ||
40 | reg = <0xc0030000 0x1000>; | ||
41 | interrupts = <0 59 0>; | ||
42 | arm,tag-latency = <1 1 1>; | ||
43 | arm,data-latency = <1 1 1>; | ||
44 | arm,filter-ranges = <0x40000000 0x80000000>; | ||
45 | }; | ||
46 | |||
47 | gic: interrupt-controller@c0011000 { | ||
48 | compatible = "arm,cortex-a9-gic"; | ||
49 | interrupt-controller; | ||
50 | #interrupt-cells = <3>; | ||
51 | reg = <0xc0011000 0x1000>, | ||
52 | <0xc0010100 0x0100>; | ||
53 | }; | ||
54 | |||
55 | rstc-iobg { | ||
56 | compatible = "simple-bus"; | ||
57 | #address-cells = <1>; | ||
58 | #size-cells = <1>; | ||
59 | ranges = <0xc2000000 0xc2000000 0x1000000>; | ||
60 | |||
61 | reset-controller@c2000000 { | ||
62 | compatible = "sirf,marco-rstc"; | ||
63 | reg = <0xc2000000 0x10000>; | ||
64 | }; | ||
65 | }; | ||
66 | |||
67 | sys-iobg { | ||
68 | compatible = "simple-bus"; | ||
69 | #address-cells = <1>; | ||
70 | #size-cells = <1>; | ||
71 | ranges = <0xc3000000 0xc3000000 0x1000000>; | ||
72 | |||
73 | clock-controller@c3000000 { | ||
74 | compatible = "sirf,marco-clkc"; | ||
75 | reg = <0xc3000000 0x1000>; | ||
76 | interrupts = <0 3 0>; | ||
77 | }; | ||
78 | |||
79 | rsc-controller@c3010000 { | ||
80 | compatible = "sirf,marco-rsc"; | ||
81 | reg = <0xc3010000 0x1000>; | ||
82 | }; | ||
83 | }; | ||
84 | |||
85 | mem-iobg { | ||
86 | compatible = "simple-bus"; | ||
87 | #address-cells = <1>; | ||
88 | #size-cells = <1>; | ||
89 | ranges = <0xc4000000 0xc4000000 0x1000000>; | ||
90 | |||
91 | memory-controller@c4000000 { | ||
92 | compatible = "sirf,marco-memc"; | ||
93 | reg = <0xc4000000 0x10000>; | ||
94 | interrupts = <0 27 0>; | ||
95 | }; | ||
96 | }; | ||
97 | |||
98 | disp-iobg0 { | ||
99 | compatible = "simple-bus"; | ||
100 | #address-cells = <1>; | ||
101 | #size-cells = <1>; | ||
102 | ranges = <0xc5000000 0xc5000000 0x1000000>; | ||
103 | |||
104 | display0@c5000000 { | ||
105 | compatible = "sirf,marco-lcd"; | ||
106 | reg = <0xc5000000 0x10000>; | ||
107 | interrupts = <0 30 0>; | ||
108 | }; | ||
109 | |||
110 | vpp0@c5010000 { | ||
111 | compatible = "sirf,marco-vpp"; | ||
112 | reg = <0xc5010000 0x10000>; | ||
113 | interrupts = <0 31 0>; | ||
114 | }; | ||
115 | }; | ||
116 | |||
117 | disp-iobg1 { | ||
118 | compatible = "simple-bus"; | ||
119 | #address-cells = <1>; | ||
120 | #size-cells = <1>; | ||
121 | ranges = <0xc6000000 0xc6000000 0x1000000>; | ||
122 | |||
123 | display1@c6000000 { | ||
124 | compatible = "sirf,marco-lcd"; | ||
125 | reg = <0xc6000000 0x10000>; | ||
126 | interrupts = <0 62 0>; | ||
127 | }; | ||
128 | |||
129 | vpp1@c6010000 { | ||
130 | compatible = "sirf,marco-vpp"; | ||
131 | reg = <0xc6010000 0x10000>; | ||
132 | interrupts = <0 63 0>; | ||
133 | }; | ||
134 | }; | ||
135 | |||
136 | graphics-iobg { | ||
137 | compatible = "simple-bus"; | ||
138 | #address-cells = <1>; | ||
139 | #size-cells = <1>; | ||
140 | ranges = <0xc8000000 0xc8000000 0x1000000>; | ||
141 | |||
142 | graphics@c8000000 { | ||
143 | compatible = "powervr,sgx540"; | ||
144 | reg = <0xc8000000 0x1000000>; | ||
145 | interrupts = <0 6 0>; | ||
146 | }; | ||
147 | }; | ||
148 | |||
149 | multimedia-iobg { | ||
150 | compatible = "simple-bus"; | ||
151 | #address-cells = <1>; | ||
152 | #size-cells = <1>; | ||
153 | ranges = <0xc9000000 0xc9000000 0x1000000>; | ||
154 | |||
155 | multimedia@a0000000 { | ||
156 | compatible = "sirf,marco-video-codec"; | ||
157 | reg = <0xc9000000 0x1000000>; | ||
158 | interrupts = <0 5 0>; | ||
159 | }; | ||
160 | }; | ||
161 | |||
162 | dsp-iobg { | ||
163 | compatible = "simple-bus"; | ||
164 | #address-cells = <1>; | ||
165 | #size-cells = <1>; | ||
166 | ranges = <0xca000000 0xca000000 0x2000000>; | ||
167 | |||
168 | dspif@ca000000 { | ||
169 | compatible = "sirf,marco-dspif"; | ||
170 | reg = <0xca000000 0x10000>; | ||
171 | interrupts = <0 9 0>; | ||
172 | }; | ||
173 | |||
174 | gps@ca010000 { | ||
175 | compatible = "sirf,marco-gps"; | ||
176 | reg = <0xca010000 0x10000>; | ||
177 | interrupts = <0 7 0>; | ||
178 | }; | ||
179 | |||
180 | dsp@cb000000 { | ||
181 | compatible = "sirf,marco-dsp"; | ||
182 | reg = <0xcb000000 0x1000000>; | ||
183 | interrupts = <0 8 0>; | ||
184 | }; | ||
185 | }; | ||
186 | |||
187 | peri-iobg { | ||
188 | compatible = "simple-bus"; | ||
189 | #address-cells = <1>; | ||
190 | #size-cells = <1>; | ||
191 | ranges = <0xcc000000 0xcc000000 0x2000000>; | ||
192 | |||
193 | timer@cc020000 { | ||
194 | compatible = "sirf,marco-tick"; | ||
195 | reg = <0xcc020000 0x1000>; | ||
196 | interrupts = <0 0 0>, | ||
197 | <0 1 0>, | ||
198 | <0 2 0>, | ||
199 | <0 49 0>, | ||
200 | <0 50 0>, | ||
201 | <0 51 0>; | ||
202 | }; | ||
203 | |||
204 | nand@cc030000 { | ||
205 | compatible = "sirf,marco-nand"; | ||
206 | reg = <0xcc030000 0x10000>; | ||
207 | interrupts = <0 41 0>; | ||
208 | }; | ||
209 | |||
210 | audio@cc040000 { | ||
211 | compatible = "sirf,marco-audio"; | ||
212 | reg = <0xcc040000 0x10000>; | ||
213 | interrupts = <0 35 0>; | ||
214 | }; | ||
215 | |||
216 | uart0: uart@cc050000 { | ||
217 | cell-index = <0>; | ||
218 | compatible = "sirf,marco-uart"; | ||
219 | reg = <0xcc050000 0x1000>; | ||
220 | interrupts = <0 17 0>; | ||
221 | fifosize = <128>; | ||
222 | status = "disabled"; | ||
223 | }; | ||
224 | |||
225 | uart1: uart@cc060000 { | ||
226 | cell-index = <1>; | ||
227 | compatible = "sirf,marco-uart"; | ||
228 | reg = <0xcc060000 0x1000>; | ||
229 | interrupts = <0 18 0>; | ||
230 | fifosize = <32>; | ||
231 | status = "disabled"; | ||
232 | }; | ||
233 | |||
234 | uart2: uart@cc070000 { | ||
235 | cell-index = <2>; | ||
236 | compatible = "sirf,marco-uart"; | ||
237 | reg = <0xcc070000 0x1000>; | ||
238 | interrupts = <0 19 0>; | ||
239 | fifosize = <128>; | ||
240 | status = "disabled"; | ||
241 | }; | ||
242 | |||
243 | uart3: uart@cc190000 { | ||
244 | cell-index = <3>; | ||
245 | compatible = "sirf,marco-uart"; | ||
246 | reg = <0xcc190000 0x1000>; | ||
247 | interrupts = <0 66 0>; | ||
248 | fifosize = <128>; | ||
249 | status = "disabled"; | ||
250 | }; | ||
251 | |||
252 | uart4: uart@cc1a0000 { | ||
253 | cell-index = <4>; | ||
254 | compatible = "sirf,marco-uart"; | ||
255 | reg = <0xcc1a0000 0x1000>; | ||
256 | interrupts = <0 69 0>; | ||
257 | fifosize = <128>; | ||
258 | status = "disabled"; | ||
259 | }; | ||
260 | |||
261 | usp0: usp@cc080000 { | ||
262 | cell-index = <0>; | ||
263 | compatible = "sirf,marco-usp"; | ||
264 | reg = <0xcc080000 0x10000>; | ||
265 | interrupts = <0 20 0>; | ||
266 | status = "disabled"; | ||
267 | }; | ||
268 | |||
269 | usp1: usp@cc090000 { | ||
270 | cell-index = <1>; | ||
271 | compatible = "sirf,marco-usp"; | ||
272 | reg = <0xcc090000 0x10000>; | ||
273 | interrupts = <0 21 0>; | ||
274 | status = "disabled"; | ||
275 | }; | ||
276 | |||
277 | usp2: usp@cc0a0000 { | ||
278 | cell-index = <2>; | ||
279 | compatible = "sirf,marco-usp"; | ||
280 | reg = <0xcc0a0000 0x10000>; | ||
281 | interrupts = <0 22 0>; | ||
282 | status = "disabled"; | ||
283 | }; | ||
284 | |||
285 | dmac0: dma-controller@cc0b0000 { | ||
286 | cell-index = <0>; | ||
287 | compatible = "sirf,marco-dmac"; | ||
288 | reg = <0xcc0b0000 0x10000>; | ||
289 | interrupts = <0 12 0>; | ||
290 | }; | ||
291 | |||
292 | dmac1: dma-controller@cc160000 { | ||
293 | cell-index = <1>; | ||
294 | compatible = "sirf,marco-dmac"; | ||
295 | reg = <0xcc160000 0x10000>; | ||
296 | interrupts = <0 13 0>; | ||
297 | }; | ||
298 | |||
299 | vip@cc0c0000 { | ||
300 | compatible = "sirf,marco-vip"; | ||
301 | reg = <0xcc0c0000 0x10000>; | ||
302 | }; | ||
303 | |||
304 | spi0: spi@cc0d0000 { | ||
305 | cell-index = <0>; | ||
306 | compatible = "sirf,marco-spi"; | ||
307 | reg = <0xcc0d0000 0x10000>; | ||
308 | interrupts = <0 15 0>; | ||
309 | sirf,spi-num-chipselects = <1>; | ||
310 | cs-gpios = <&gpio 0 0>; | ||
311 | sirf,spi-dma-rx-channel = <25>; | ||
312 | sirf,spi-dma-tx-channel = <20>; | ||
313 | #address-cells = <1>; | ||
314 | #size-cells = <0>; | ||
315 | status = "disabled"; | ||
316 | }; | ||
317 | |||
318 | spi1: spi@cc170000 { | ||
319 | cell-index = <1>; | ||
320 | compatible = "sirf,marco-spi"; | ||
321 | reg = <0xcc170000 0x10000>; | ||
322 | interrupts = <0 16 0>; | ||
323 | sirf,spi-num-chipselects = <1>; | ||
324 | cs-gpios = <&gpio 0 0>; | ||
325 | sirf,spi-dma-rx-channel = <12>; | ||
326 | sirf,spi-dma-tx-channel = <13>; | ||
327 | #address-cells = <1>; | ||
328 | #size-cells = <0>; | ||
329 | status = "disabled"; | ||
330 | }; | ||
331 | |||
332 | i2c0: i2c@cc0e0000 { | ||
333 | cell-index = <0>; | ||
334 | compatible = "sirf,marco-i2c"; | ||
335 | reg = <0xcc0e0000 0x10000>; | ||
336 | interrupts = <0 24 0>; | ||
337 | #address-cells = <1>; | ||
338 | #size-cells = <0>; | ||
339 | status = "disabled"; | ||
340 | }; | ||
341 | |||
342 | i2c1: i2c@cc0f0000 { | ||
343 | cell-index = <1>; | ||
344 | compatible = "sirf,marco-i2c"; | ||
345 | reg = <0xcc0f0000 0x10000>; | ||
346 | interrupts = <0 25 0>; | ||
347 | #address-cells = <1>; | ||
348 | #size-cells = <0>; | ||
349 | status = "disabled"; | ||
350 | }; | ||
351 | |||
352 | tsc@cc110000 { | ||
353 | compatible = "sirf,marco-tsc"; | ||
354 | reg = <0xcc110000 0x10000>; | ||
355 | interrupts = <0 33 0>; | ||
356 | }; | ||
357 | |||
358 | gpio: pinctrl@cc120000 { | ||
359 | #gpio-cells = <2>; | ||
360 | #interrupt-cells = <2>; | ||
361 | compatible = "sirf,marco-pinctrl"; | ||
362 | reg = <0xcc120000 0x10000>; | ||
363 | interrupts = <0 43 0>, | ||
364 | <0 44 0>, | ||
365 | <0 45 0>, | ||
366 | <0 46 0>, | ||
367 | <0 47 0>; | ||
368 | gpio-controller; | ||
369 | interrupt-controller; | ||
370 | |||
371 | lcd_16pins_a: lcd0_0 { | ||
372 | lcd { | ||
373 | sirf,pins = "lcd_16bitsgrp"; | ||
374 | sirf,function = "lcd_16bits"; | ||
375 | }; | ||
376 | }; | ||
377 | lcd_18pins_a: lcd0_1 { | ||
378 | lcd { | ||
379 | sirf,pins = "lcd_18bitsgrp"; | ||
380 | sirf,function = "lcd_18bits"; | ||
381 | }; | ||
382 | }; | ||
383 | lcd_24pins_a: lcd0_2 { | ||
384 | lcd { | ||
385 | sirf,pins = "lcd_24bitsgrp"; | ||
386 | sirf,function = "lcd_24bits"; | ||
387 | }; | ||
388 | }; | ||
389 | lcdrom_pins_a: lcdrom0_0 { | ||
390 | lcd { | ||
391 | sirf,pins = "lcdromgrp"; | ||
392 | sirf,function = "lcdrom"; | ||
393 | }; | ||
394 | }; | ||
395 | uart0_pins_a: uart0_0 { | ||
396 | uart { | ||
397 | sirf,pins = "uart0grp"; | ||
398 | sirf,function = "uart0"; | ||
399 | }; | ||
400 | }; | ||
401 | uart1_pins_a: uart1_0 { | ||
402 | uart { | ||
403 | sirf,pins = "uart1grp"; | ||
404 | sirf,function = "uart1"; | ||
405 | }; | ||
406 | }; | ||
407 | uart2_pins_a: uart2_0 { | ||
408 | uart { | ||
409 | sirf,pins = "uart2grp"; | ||
410 | sirf,function = "uart2"; | ||
411 | }; | ||
412 | }; | ||
413 | uart2_noflow_pins_a: uart2_1 { | ||
414 | uart { | ||
415 | sirf,pins = "uart2_nostreamctrlgrp"; | ||
416 | sirf,function = "uart2_nostreamctrl"; | ||
417 | }; | ||
418 | }; | ||
419 | spi0_pins_a: spi0_0 { | ||
420 | spi { | ||
421 | sirf,pins = "spi0grp"; | ||
422 | sirf,function = "spi0"; | ||
423 | }; | ||
424 | }; | ||
425 | spi1_pins_a: spi1_0 { | ||
426 | spi { | ||
427 | sirf,pins = "spi1grp"; | ||
428 | sirf,function = "spi1"; | ||
429 | }; | ||
430 | }; | ||
431 | i2c0_pins_a: i2c0_0 { | ||
432 | i2c { | ||
433 | sirf,pins = "i2c0grp"; | ||
434 | sirf,function = "i2c0"; | ||
435 | }; | ||
436 | }; | ||
437 | i2c1_pins_a: i2c1_0 { | ||
438 | i2c { | ||
439 | sirf,pins = "i2c1grp"; | ||
440 | sirf,function = "i2c1"; | ||
441 | }; | ||
442 | }; | ||
443 | pwm0_pins_a: pwm0_0 { | ||
444 | pwm { | ||
445 | sirf,pins = "pwm0grp"; | ||
446 | sirf,function = "pwm0"; | ||
447 | }; | ||
448 | }; | ||
449 | pwm1_pins_a: pwm1_0 { | ||
450 | pwm { | ||
451 | sirf,pins = "pwm1grp"; | ||
452 | sirf,function = "pwm1"; | ||
453 | }; | ||
454 | }; | ||
455 | pwm2_pins_a: pwm2_0 { | ||
456 | pwm { | ||
457 | sirf,pins = "pwm2grp"; | ||
458 | sirf,function = "pwm2"; | ||
459 | }; | ||
460 | }; | ||
461 | pwm3_pins_a: pwm3_0 { | ||
462 | pwm { | ||
463 | sirf,pins = "pwm3grp"; | ||
464 | sirf,function = "pwm3"; | ||
465 | }; | ||
466 | }; | ||
467 | gps_pins_a: gps_0 { | ||
468 | gps { | ||
469 | sirf,pins = "gpsgrp"; | ||
470 | sirf,function = "gps"; | ||
471 | }; | ||
472 | }; | ||
473 | vip_pins_a: vip_0 { | ||
474 | vip { | ||
475 | sirf,pins = "vipgrp"; | ||
476 | sirf,function = "vip"; | ||
477 | }; | ||
478 | }; | ||
479 | sdmmc0_pins_a: sdmmc0_0 { | ||
480 | sdmmc0 { | ||
481 | sirf,pins = "sdmmc0grp"; | ||
482 | sirf,function = "sdmmc0"; | ||
483 | }; | ||
484 | }; | ||
485 | sdmmc1_pins_a: sdmmc1_0 { | ||
486 | sdmmc1 { | ||
487 | sirf,pins = "sdmmc1grp"; | ||
488 | sirf,function = "sdmmc1"; | ||
489 | }; | ||
490 | }; | ||
491 | sdmmc2_pins_a: sdmmc2_0 { | ||
492 | sdmmc2 { | ||
493 | sirf,pins = "sdmmc2grp"; | ||
494 | sirf,function = "sdmmc2"; | ||
495 | }; | ||
496 | }; | ||
497 | sdmmc3_pins_a: sdmmc3_0 { | ||
498 | sdmmc3 { | ||
499 | sirf,pins = "sdmmc3grp"; | ||
500 | sirf,function = "sdmmc3"; | ||
501 | }; | ||
502 | }; | ||
503 | sdmmc4_pins_a: sdmmc4_0 { | ||
504 | sdmmc4 { | ||
505 | sirf,pins = "sdmmc4grp"; | ||
506 | sirf,function = "sdmmc4"; | ||
507 | }; | ||
508 | }; | ||
509 | sdmmc5_pins_a: sdmmc5_0 { | ||
510 | sdmmc5 { | ||
511 | sirf,pins = "sdmmc5grp"; | ||
512 | sirf,function = "sdmmc5"; | ||
513 | }; | ||
514 | }; | ||
515 | i2s_pins_a: i2s_0 { | ||
516 | i2s { | ||
517 | sirf,pins = "i2sgrp"; | ||
518 | sirf,function = "i2s"; | ||
519 | }; | ||
520 | }; | ||
521 | ac97_pins_a: ac97_0 { | ||
522 | ac97 { | ||
523 | sirf,pins = "ac97grp"; | ||
524 | sirf,function = "ac97"; | ||
525 | }; | ||
526 | }; | ||
527 | nand_pins_a: nand_0 { | ||
528 | nand { | ||
529 | sirf,pins = "nandgrp"; | ||
530 | sirf,function = "nand"; | ||
531 | }; | ||
532 | }; | ||
533 | usp0_pins_a: usp0_0 { | ||
534 | usp0 { | ||
535 | sirf,pins = "usp0grp"; | ||
536 | sirf,function = "usp0"; | ||
537 | }; | ||
538 | }; | ||
539 | usp1_pins_a: usp1_0 { | ||
540 | usp1 { | ||
541 | sirf,pins = "usp1grp"; | ||
542 | sirf,function = "usp1"; | ||
543 | }; | ||
544 | }; | ||
545 | usp2_pins_a: usp2_0 { | ||
546 | usp2 { | ||
547 | sirf,pins = "usp2grp"; | ||
548 | sirf,function = "usp2"; | ||
549 | }; | ||
550 | }; | ||
551 | usb0_utmi_drvbus_pins_a: usb0_utmi_drvbus_0 { | ||
552 | usb0_utmi_drvbus { | ||
553 | sirf,pins = "usb0_utmi_drvbusgrp"; | ||
554 | sirf,function = "usb0_utmi_drvbus"; | ||
555 | }; | ||
556 | }; | ||
557 | usb1_utmi_drvbus_pins_a: usb1_utmi_drvbus_0 { | ||
558 | usb1_utmi_drvbus { | ||
559 | sirf,pins = "usb1_utmi_drvbusgrp"; | ||
560 | sirf,function = "usb1_utmi_drvbus"; | ||
561 | }; | ||
562 | }; | ||
563 | warm_rst_pins_a: warm_rst_0 { | ||
564 | warm_rst { | ||
565 | sirf,pins = "warm_rstgrp"; | ||
566 | sirf,function = "warm_rst"; | ||
567 | }; | ||
568 | }; | ||
569 | pulse_count_pins_a: pulse_count_0 { | ||
570 | pulse_count { | ||
571 | sirf,pins = "pulse_countgrp"; | ||
572 | sirf,function = "pulse_count"; | ||
573 | }; | ||
574 | }; | ||
575 | cko0_rst_pins_a: cko0_rst_0 { | ||
576 | cko0_rst { | ||
577 | sirf,pins = "cko0_rstgrp"; | ||
578 | sirf,function = "cko0_rst"; | ||
579 | }; | ||
580 | }; | ||
581 | cko1_rst_pins_a: cko1_rst_0 { | ||
582 | cko1_rst { | ||
583 | sirf,pins = "cko1_rstgrp"; | ||
584 | sirf,function = "cko1_rst"; | ||
585 | }; | ||
586 | }; | ||
587 | }; | ||
588 | |||
589 | pwm@cc130000 { | ||
590 | compatible = "sirf,marco-pwm"; | ||
591 | reg = <0xcc130000 0x10000>; | ||
592 | }; | ||
593 | |||
594 | efusesys@cc140000 { | ||
595 | compatible = "sirf,marco-efuse"; | ||
596 | reg = <0xcc140000 0x10000>; | ||
597 | }; | ||
598 | |||
599 | pulsec@cc150000 { | ||
600 | compatible = "sirf,marco-pulsec"; | ||
601 | reg = <0xcc150000 0x10000>; | ||
602 | interrupts = <0 48 0>; | ||
603 | }; | ||
604 | |||
605 | pci-iobg { | ||
606 | compatible = "sirf,marco-pciiobg", "simple-bus"; | ||
607 | #address-cells = <1>; | ||
608 | #size-cells = <1>; | ||
609 | ranges = <0xcd000000 0xcd000000 0x1000000>; | ||
610 | |||
611 | sd0: sdhci@cd000000 { | ||
612 | cell-index = <0>; | ||
613 | compatible = "sirf,marco-sdhc"; | ||
614 | reg = <0xcd000000 0x100000>; | ||
615 | interrupts = <0 38 0>; | ||
616 | status = "disabled"; | ||
617 | }; | ||
618 | |||
619 | sd1: sdhci@cd100000 { | ||
620 | cell-index = <1>; | ||
621 | compatible = "sirf,marco-sdhc"; | ||
622 | reg = <0xcd100000 0x100000>; | ||
623 | interrupts = <0 38 0>; | ||
624 | status = "disabled"; | ||
625 | }; | ||
626 | |||
627 | sd2: sdhci@cd200000 { | ||
628 | cell-index = <2>; | ||
629 | compatible = "sirf,marco-sdhc"; | ||
630 | reg = <0xcd200000 0x100000>; | ||
631 | interrupts = <0 23 0>; | ||
632 | status = "disabled"; | ||
633 | }; | ||
634 | |||
635 | sd3: sdhci@cd300000 { | ||
636 | cell-index = <3>; | ||
637 | compatible = "sirf,marco-sdhc"; | ||
638 | reg = <0xcd300000 0x100000>; | ||
639 | interrupts = <0 23 0>; | ||
640 | status = "disabled"; | ||
641 | }; | ||
642 | |||
643 | sd4: sdhci@cd400000 { | ||
644 | cell-index = <4>; | ||
645 | compatible = "sirf,marco-sdhc"; | ||
646 | reg = <0xcd400000 0x100000>; | ||
647 | interrupts = <0 39 0>; | ||
648 | status = "disabled"; | ||
649 | }; | ||
650 | |||
651 | sd5: sdhci@cd500000 { | ||
652 | cell-index = <5>; | ||
653 | compatible = "sirf,marco-sdhc"; | ||
654 | reg = <0xcd500000 0x100000>; | ||
655 | interrupts = <0 39 0>; | ||
656 | status = "disabled"; | ||
657 | }; | ||
658 | |||
659 | pci-copy@cd900000 { | ||
660 | compatible = "sirf,marco-pcicp"; | ||
661 | reg = <0xcd900000 0x100000>; | ||
662 | interrupts = <0 40 0>; | ||
663 | }; | ||
664 | |||
665 | rom-interface@cda00000 { | ||
666 | compatible = "sirf,marco-romif"; | ||
667 | reg = <0xcda00000 0x100000>; | ||
668 | }; | ||
669 | }; | ||
670 | }; | ||
671 | |||
672 | rtc-iobg { | ||
673 | compatible = "sirf,marco-rtciobg", "sirf-marco-rtciobg-bus"; | ||
674 | #address-cells = <1>; | ||
675 | #size-cells = <1>; | ||
676 | reg = <0xc1000000 0x10000>; | ||
677 | |||
678 | gpsrtc@1000 { | ||
679 | compatible = "sirf,marco-gpsrtc"; | ||
680 | reg = <0x1000 0x1000>; | ||
681 | interrupts = <0 55 0>, | ||
682 | <0 56 0>, | ||
683 | <0 57 0>; | ||
684 | }; | ||
685 | |||
686 | sysrtc@2000 { | ||
687 | compatible = "sirf,marco-sysrtc"; | ||
688 | reg = <0x2000 0x1000>; | ||
689 | interrupts = <0 52 0>, | ||
690 | <0 53 0>, | ||
691 | <0 54 0>; | ||
692 | }; | ||
693 | |||
694 | pwrc@3000 { | ||
695 | compatible = "sirf,marco-pwrc"; | ||
696 | reg = <0x3000 0x1000>; | ||
697 | interrupts = <0 32 0>; | ||
698 | }; | ||
699 | }; | ||
700 | |||
701 | uus-iobg { | ||
702 | compatible = "simple-bus"; | ||
703 | #address-cells = <1>; | ||
704 | #size-cells = <1>; | ||
705 | ranges = <0xce000000 0xce000000 0x1000000>; | ||
706 | |||
707 | usb0: usb@ce000000 { | ||
708 | compatible = "chipidea,ci13611a-marco"; | ||
709 | reg = <0xce000000 0x10000>; | ||
710 | interrupts = <0 10 0>; | ||
711 | }; | ||
712 | |||
713 | usb1: usb@ce010000 { | ||
714 | compatible = "chipidea,ci13611a-marco"; | ||
715 | reg = <0xce010000 0x10000>; | ||
716 | interrupts = <0 11 0>; | ||
717 | }; | ||
718 | |||
719 | security@ce020000 { | ||
720 | compatible = "sirf,marco-security"; | ||
721 | reg = <0xce020000 0x10000>; | ||
722 | interrupts = <0 42 0>; | ||
723 | }; | ||
724 | }; | ||
725 | |||
726 | can-iobg { | ||
727 | compatible = "simple-bus"; | ||
728 | #address-cells = <1>; | ||
729 | #size-cells = <1>; | ||
730 | ranges = <0xd0000000 0xd0000000 0x1000000>; | ||
731 | |||
732 | can0: can@d0000000 { | ||
733 | compatible = "sirf,marco-can"; | ||
734 | reg = <0xd0000000 0x10000>; | ||
735 | }; | ||
736 | |||
737 | can1: can@d0010000 { | ||
738 | compatible = "sirf,marco-can"; | ||
739 | reg = <0xd0010000 0x10000>; | ||
740 | }; | ||
741 | }; | ||
742 | |||
743 | lvds-iobg { | ||
744 | compatible = "simple-bus"; | ||
745 | #address-cells = <1>; | ||
746 | #size-cells = <1>; | ||
747 | ranges = <0xd1000000 0xd1000000 0x1000000>; | ||
748 | |||
749 | lvds@d1000000 { | ||
750 | compatible = "sirf,marco-lvds"; | ||
751 | reg = <0xd1000000 0x10000>; | ||
752 | interrupts = <0 64 0>; | ||
753 | }; | ||
754 | }; | ||
755 | }; | ||
756 | }; | ||
diff --git a/arch/arm/configs/prima2_defconfig b/arch/arm/configs/prima2_defconfig index 6a936c7c078a..002a1ceadceb 100644 --- a/arch/arm/configs/prima2_defconfig +++ b/arch/arm/configs/prima2_defconfig | |||
@@ -11,6 +11,9 @@ CONFIG_PARTITION_ADVANCED=y | |||
11 | CONFIG_BSD_DISKLABEL=y | 11 | CONFIG_BSD_DISKLABEL=y |
12 | CONFIG_SOLARIS_X86_PARTITION=y | 12 | CONFIG_SOLARIS_X86_PARTITION=y |
13 | CONFIG_ARCH_SIRF=y | 13 | CONFIG_ARCH_SIRF=y |
14 | # CONFIG_SWP_EMULATE is not set | ||
15 | CONFIG_SMP=y | ||
16 | CONFIG_SCHED_MC=y | ||
14 | CONFIG_PREEMPT=y | 17 | CONFIG_PREEMPT=y |
15 | CONFIG_AEABI=y | 18 | CONFIG_AEABI=y |
16 | CONFIG_KEXEC=y | 19 | CONFIG_KEXEC=y |
diff --git a/arch/arm/mach-prima2/Kconfig b/arch/arm/mach-prima2/Kconfig index 558ccfb8d458..4f7379fe01e2 100644 --- a/arch/arm/mach-prima2/Kconfig +++ b/arch/arm/mach-prima2/Kconfig | |||
@@ -11,6 +11,16 @@ config ARCH_PRIMA2 | |||
11 | help | 11 | help |
12 | Support for CSR SiRFSoC ARM Cortex A9 Platform | 12 | Support for CSR SiRFSoC ARM Cortex A9 Platform |
13 | 13 | ||
14 | config ARCH_MARCO | ||
15 | bool "CSR SiRFSoC MARCO ARM Cortex A9 Platform" | ||
16 | default y | ||
17 | select ARM_GIC | ||
18 | select CPU_V7 | ||
19 | select HAVE_SMP | ||
20 | select SMP_ON_UP | ||
21 | help | ||
22 | Support for CSR SiRFSoC ARM Cortex A9 Platform | ||
23 | |||
14 | endmenu | 24 | endmenu |
15 | 25 | ||
16 | config SIRF_IRQ | 26 | config SIRF_IRQ |
diff --git a/arch/arm/mach-prima2/Makefile b/arch/arm/mach-prima2/Makefile index fc9ce22e2b5a..bfe360cbd177 100644 --- a/arch/arm/mach-prima2/Makefile +++ b/arch/arm/mach-prima2/Makefile | |||
@@ -1,4 +1,3 @@ | |||
1 | obj-y := timer.o | ||
2 | obj-y += rstc.o | 1 | obj-y += rstc.o |
3 | obj-y += common.o | 2 | obj-y += common.o |
4 | obj-y += rtciobrg.o | 3 | obj-y += rtciobrg.o |
@@ -6,3 +5,7 @@ obj-$(CONFIG_DEBUG_LL) += lluart.o | |||
6 | obj-$(CONFIG_CACHE_L2X0) += l2x0.o | 5 | obj-$(CONFIG_CACHE_L2X0) += l2x0.o |
7 | obj-$(CONFIG_SUSPEND) += pm.o sleep.o | 6 | obj-$(CONFIG_SUSPEND) += pm.o sleep.o |
8 | obj-$(CONFIG_SIRF_IRQ) += irq.o | 7 | obj-$(CONFIG_SIRF_IRQ) += irq.o |
8 | obj-$(CONFIG_SMP) += platsmp.o headsmp.o | ||
9 | obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o | ||
10 | obj-$(CONFIG_ARCH_PRIMA2) += timer-prima2.o | ||
11 | obj-$(CONFIG_ARCH_MARCO) += timer-marco.o | ||
diff --git a/arch/arm/mach-prima2/common.c b/arch/arm/mach-prima2/common.c index ed3570e5eb8f..00a65649a7e2 100644 --- a/arch/arm/mach-prima2/common.c +++ b/arch/arm/mach-prima2/common.c | |||
@@ -8,9 +8,11 @@ | |||
8 | 8 | ||
9 | #include <linux/init.h> | 9 | #include <linux/init.h> |
10 | #include <linux/kernel.h> | 10 | #include <linux/kernel.h> |
11 | #include <linux/of_irq.h> | ||
11 | #include <asm/sizes.h> | 12 | #include <asm/sizes.h> |
12 | #include <asm/mach-types.h> | 13 | #include <asm/mach-types.h> |
13 | #include <asm/mach/arch.h> | 14 | #include <asm/mach/arch.h> |
15 | #include <asm/hardware/gic.h> | ||
14 | #include <linux/of.h> | 16 | #include <linux/of.h> |
15 | #include <linux/of_platform.h> | 17 | #include <linux/of_platform.h> |
16 | #include "common.h" | 18 | #include "common.h" |
@@ -30,6 +32,12 @@ void __init sirfsoc_init_late(void) | |||
30 | sirfsoc_pm_init(); | 32 | sirfsoc_pm_init(); |
31 | } | 33 | } |
32 | 34 | ||
35 | static __init void sirfsoc_map_io(void) | ||
36 | { | ||
37 | sirfsoc_map_lluart(); | ||
38 | sirfsoc_map_scu(); | ||
39 | } | ||
40 | |||
33 | #ifdef CONFIG_ARCH_PRIMA2 | 41 | #ifdef CONFIG_ARCH_PRIMA2 |
34 | static const char *prima2_dt_match[] __initdata = { | 42 | static const char *prima2_dt_match[] __initdata = { |
35 | "sirf,prima2", | 43 | "sirf,prima2", |
@@ -38,9 +46,12 @@ static const char *prima2_dt_match[] __initdata = { | |||
38 | 46 | ||
39 | DT_MACHINE_START(PRIMA2_DT, "Generic PRIMA2 (Flattened Device Tree)") | 47 | DT_MACHINE_START(PRIMA2_DT, "Generic PRIMA2 (Flattened Device Tree)") |
40 | /* Maintainer: Barry Song <baohua.song@csr.com> */ | 48 | /* Maintainer: Barry Song <baohua.song@csr.com> */ |
41 | .map_io = sirfsoc_map_lluart, | 49 | .map_io = sirfsoc_map_io, |
42 | .init_irq = sirfsoc_of_irq_init, | 50 | .init_irq = sirfsoc_of_irq_init, |
43 | .init_time = sirfsoc_timer_init, | 51 | .init_time = sirfsoc_prima2_timer_init, |
52 | #ifdef CONFIG_MULTI_IRQ_HANDLER | ||
53 | .handle_irq = sirfsoc_handle_irq, | ||
54 | #endif | ||
44 | .dma_zone_size = SZ_256M, | 55 | .dma_zone_size = SZ_256M, |
45 | .init_machine = sirfsoc_mach_init, | 56 | .init_machine = sirfsoc_mach_init, |
46 | .init_late = sirfsoc_init_late, | 57 | .init_late = sirfsoc_init_late, |
@@ -48,3 +59,33 @@ DT_MACHINE_START(PRIMA2_DT, "Generic PRIMA2 (Flattened Device Tree)") | |||
48 | .restart = sirfsoc_restart, | 59 | .restart = sirfsoc_restart, |
49 | MACHINE_END | 60 | MACHINE_END |
50 | #endif | 61 | #endif |
62 | |||
63 | #ifdef CONFIG_ARCH_MARCO | ||
64 | static const struct of_device_id marco_irq_match[] __initconst = { | ||
65 | { .compatible = "arm,cortex-a9-gic", .data = gic_of_init, }, | ||
66 | { /* sentinel */ } | ||
67 | }; | ||
68 | |||
69 | static void __init marco_init_irq(void) | ||
70 | { | ||
71 | of_irq_init(marco_irq_match); | ||
72 | } | ||
73 | |||
74 | static const char *marco_dt_match[] __initdata = { | ||
75 | "sirf,marco", | ||
76 | NULL | ||
77 | }; | ||
78 | |||
79 | DT_MACHINE_START(MARCO_DT, "Generic MARCO (Flattened Device Tree)") | ||
80 | /* Maintainer: Barry Song <baohua.song@csr.com> */ | ||
81 | .smp = smp_ops(sirfsoc_smp_ops), | ||
82 | .map_io = sirfsoc_map_io, | ||
83 | .init_irq = marco_init_irq, | ||
84 | .init_time = sirfsoc_marco_timer_init, | ||
85 | .handle_irq = gic_handle_irq, | ||
86 | .init_machine = sirfsoc_mach_init, | ||
87 | .init_late = sirfsoc_init_late, | ||
88 | .dt_compat = marco_dt_match, | ||
89 | .restart = sirfsoc_restart, | ||
90 | MACHINE_END | ||
91 | #endif | ||
diff --git a/arch/arm/mach-prima2/common.h b/arch/arm/mach-prima2/common.h index 9c75f124e3cf..b7c26b62e4a7 100644 --- a/arch/arm/mach-prima2/common.h +++ b/arch/arm/mach-prima2/common.h | |||
@@ -11,12 +11,19 @@ | |||
11 | 11 | ||
12 | #include <linux/init.h> | 12 | #include <linux/init.h> |
13 | #include <asm/mach/time.h> | 13 | #include <asm/mach/time.h> |
14 | #include <asm/exception.h> | ||
14 | 15 | ||
15 | extern void sirfsoc_timer_init(void); | 16 | extern void sirfsoc_prima2_timer_init(void); |
17 | extern void sirfsoc_marco_timer_init(void); | ||
18 | |||
19 | extern struct smp_operations sirfsoc_smp_ops; | ||
20 | extern void sirfsoc_secondary_startup(void); | ||
21 | extern void sirfsoc_cpu_die(unsigned int cpu); | ||
16 | 22 | ||
17 | extern void __init sirfsoc_of_irq_init(void); | 23 | extern void __init sirfsoc_of_irq_init(void); |
18 | extern void __init sirfsoc_of_clk_init(void); | 24 | extern void __init sirfsoc_of_clk_init(void); |
19 | extern void sirfsoc_restart(char, const char *); | 25 | extern void sirfsoc_restart(char, const char *); |
26 | extern asmlinkage void __exception_irq_entry sirfsoc_handle_irq(struct pt_regs *regs); | ||
20 | 27 | ||
21 | #ifndef CONFIG_DEBUG_LL | 28 | #ifndef CONFIG_DEBUG_LL |
22 | static inline void sirfsoc_map_lluart(void) {} | 29 | static inline void sirfsoc_map_lluart(void) {} |
@@ -24,6 +31,12 @@ static inline void sirfsoc_map_lluart(void) {} | |||
24 | extern void __init sirfsoc_map_lluart(void); | 31 | extern void __init sirfsoc_map_lluart(void); |
25 | #endif | 32 | #endif |
26 | 33 | ||
34 | #ifndef CONFIG_SMP | ||
35 | static inline void sirfsoc_map_scu(void) {} | ||
36 | #else | ||
37 | extern void sirfsoc_map_scu(void); | ||
38 | #endif | ||
39 | |||
27 | #ifdef CONFIG_SUSPEND | 40 | #ifdef CONFIG_SUSPEND |
28 | extern int sirfsoc_pm_init(void); | 41 | extern int sirfsoc_pm_init(void); |
29 | #else | 42 | #else |
diff --git a/arch/arm/mach-prima2/headsmp.S b/arch/arm/mach-prima2/headsmp.S new file mode 100644 index 000000000000..6ec19d51a271 --- /dev/null +++ b/arch/arm/mach-prima2/headsmp.S | |||
@@ -0,0 +1,79 @@ | |||
1 | /* | ||
2 | * Entry of the second core for CSR Marco dual-core SMP SoCs | ||
3 | * | ||
4 | * Copyright (c) 2012 Cambridge Silicon Radio Limited, a CSR plc group company. | ||
5 | * | ||
6 | * Licensed under GPLv2 or later. | ||
7 | */ | ||
8 | |||
9 | #include <linux/linkage.h> | ||
10 | #include <linux/init.h> | ||
11 | |||
12 | __INIT | ||
13 | /* | ||
14 | * Cold boot and hardware reset show different behaviour, | ||
15 | * system will be always panic if we warm-reset the board | ||
16 | * Here we invalidate L1 of CPU1 to make sure there isn't | ||
17 | * uninitialized data written into memory later | ||
18 | */ | ||
19 | ENTRY(v7_invalidate_l1) | ||
20 | mov r0, #0 | ||
21 | mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache | ||
22 | mcr p15, 2, r0, c0, c0, 0 | ||
23 | mrc p15, 1, r0, c0, c0, 0 | ||
24 | |||
25 | ldr r1, =0x7fff | ||
26 | and r2, r1, r0, lsr #13 | ||
27 | |||
28 | ldr r1, =0x3ff | ||
29 | |||
30 | and r3, r1, r0, lsr #3 @ NumWays - 1 | ||
31 | add r2, r2, #1 @ NumSets | ||
32 | |||
33 | and r0, r0, #0x7 | ||
34 | add r0, r0, #4 @ SetShift | ||
35 | |||
36 | clz r1, r3 @ WayShift | ||
37 | add r4, r3, #1 @ NumWays | ||
38 | 1: sub r2, r2, #1 @ NumSets-- | ||
39 | mov r3, r4 @ Temp = NumWays | ||
40 | 2: subs r3, r3, #1 @ Temp-- | ||
41 | mov r5, r3, lsl r1 | ||
42 | mov r6, r2, lsl r0 | ||
43 | orr r5, r5, r6 @ Reg = (Temp<<WayShift)|(NumSets<<SetShift) | ||
44 | mcr p15, 0, r5, c7, c6, 2 | ||
45 | bgt 2b | ||
46 | cmp r2, #0 | ||
47 | bgt 1b | ||
48 | dsb | ||
49 | isb | ||
50 | mov pc, lr | ||
51 | ENDPROC(v7_invalidate_l1) | ||
52 | |||
53 | /* | ||
54 | * SIRFSOC specific entry point for secondary CPUs. This provides | ||
55 | * a "holding pen" into which all secondary cores are held until we're | ||
56 | * ready for them to initialise. | ||
57 | */ | ||
58 | ENTRY(sirfsoc_secondary_startup) | ||
59 | bl v7_invalidate_l1 | ||
60 | mrc p15, 0, r0, c0, c0, 5 | ||
61 | and r0, r0, #15 | ||
62 | adr r4, 1f | ||
63 | ldmia r4, {r5, r6} | ||
64 | sub r4, r4, r5 | ||
65 | add r6, r6, r4 | ||
66 | pen: ldr r7, [r6] | ||
67 | cmp r7, r0 | ||
68 | bne pen | ||
69 | |||
70 | /* | ||
71 | * we've been released from the holding pen: secondary_stack | ||
72 | * should now contain the SVC stack for this core | ||
73 | */ | ||
74 | b secondary_startup | ||
75 | ENDPROC(sirfsoc_secondary_startup) | ||
76 | |||
77 | .align | ||
78 | 1: .long . | ||
79 | .long pen_release | ||
diff --git a/arch/arm/mach-prima2/hotplug.c b/arch/arm/mach-prima2/hotplug.c new file mode 100644 index 000000000000..97c1ee586442 --- /dev/null +++ b/arch/arm/mach-prima2/hotplug.c | |||
@@ -0,0 +1,41 @@ | |||
1 | /* | ||
2 | * CPU hotplug support for CSR Marco dual-core SMP SoCs | ||
3 | * | ||
4 | * Copyright (c) 2012 Cambridge Silicon Radio Limited, a CSR plc group company. | ||
5 | * | ||
6 | * Licensed under GPLv2 or later. | ||
7 | */ | ||
8 | |||
9 | #include <linux/kernel.h> | ||
10 | #include <linux/errno.h> | ||
11 | #include <linux/smp.h> | ||
12 | |||
13 | #include <asm/cacheflush.h> | ||
14 | #include <asm/smp_plat.h> | ||
15 | |||
16 | static inline void platform_do_lowpower(unsigned int cpu) | ||
17 | { | ||
18 | flush_cache_all(); | ||
19 | |||
20 | /* we put the platform to just WFI */ | ||
21 | for (;;) { | ||
22 | __asm__ __volatile__("dsb\n\t" "wfi\n\t" | ||
23 | : : : "memory"); | ||
24 | if (pen_release == cpu_logical_map(cpu)) { | ||
25 | /* | ||
26 | * OK, proper wakeup, we're done | ||
27 | */ | ||
28 | break; | ||
29 | } | ||
30 | } | ||
31 | } | ||
32 | |||
33 | /* | ||
34 | * platform-specific code to shutdown a CPU | ||
35 | * | ||
36 | * Called with IRQs disabled | ||
37 | */ | ||
38 | void sirfsoc_cpu_die(unsigned int cpu) | ||
39 | { | ||
40 | platform_do_lowpower(cpu); | ||
41 | } | ||
diff --git a/arch/arm/mach-prima2/include/mach/irqs.h b/arch/arm/mach-prima2/include/mach/irqs.h index f6014a07541f..b778a0f248ed 100644 --- a/arch/arm/mach-prima2/include/mach/irqs.h +++ b/arch/arm/mach-prima2/include/mach/irqs.h | |||
@@ -10,8 +10,8 @@ | |||
10 | #define __ASM_ARCH_IRQS_H | 10 | #define __ASM_ARCH_IRQS_H |
11 | 11 | ||
12 | #define SIRFSOC_INTENAL_IRQ_START 0 | 12 | #define SIRFSOC_INTENAL_IRQ_START 0 |
13 | #define SIRFSOC_INTENAL_IRQ_END 59 | 13 | #define SIRFSOC_INTENAL_IRQ_END 127 |
14 | #define SIRFSOC_GPIO_IRQ_START (SIRFSOC_INTENAL_IRQ_END + 1) | 14 | #define SIRFSOC_GPIO_IRQ_START (SIRFSOC_INTENAL_IRQ_END + 1) |
15 | #define NR_IRQS 220 | 15 | #define NR_IRQS 288 |
16 | 16 | ||
17 | #endif | 17 | #endif |
diff --git a/arch/arm/mach-prima2/include/mach/uart.h b/arch/arm/mach-prima2/include/mach/uart.h index c98b4d5ac24a..c10510d01a44 100644 --- a/arch/arm/mach-prima2/include/mach/uart.h +++ b/arch/arm/mach-prima2/include/mach/uart.h | |||
@@ -10,7 +10,13 @@ | |||
10 | #define __MACH_PRIMA2_SIRFSOC_UART_H | 10 | #define __MACH_PRIMA2_SIRFSOC_UART_H |
11 | 11 | ||
12 | /* UART-1: used as serial debug port */ | 12 | /* UART-1: used as serial debug port */ |
13 | #if defined(CONFIG_DEBUG_SIRFPRIMA2_UART1) | ||
13 | #define SIRFSOC_UART1_PA_BASE 0xb0060000 | 14 | #define SIRFSOC_UART1_PA_BASE 0xb0060000 |
15 | #elif defined(CONFIG_DEBUG_SIRFMARCO_UART1) | ||
16 | #define SIRFSOC_UART1_PA_BASE 0xcc060000 | ||
17 | #else | ||
18 | #define SIRFSOC_UART1_PA_BASE 0 | ||
19 | #endif | ||
14 | #define SIRFSOC_UART1_VA_BASE SIRFSOC_VA(0x060000) | 20 | #define SIRFSOC_UART1_VA_BASE SIRFSOC_VA(0x060000) |
15 | #define SIRFSOC_UART1_SIZE SZ_4K | 21 | #define SIRFSOC_UART1_SIZE SZ_4K |
16 | 22 | ||
diff --git a/arch/arm/mach-prima2/include/mach/uncompress.h b/arch/arm/mach-prima2/include/mach/uncompress.h index 0c898fcf909c..15f3edcfbb47 100644 --- a/arch/arm/mach-prima2/include/mach/uncompress.h +++ b/arch/arm/mach-prima2/include/mach/uncompress.h | |||
@@ -25,6 +25,9 @@ static __inline__ void putc(char c) | |||
25 | * during kernel decompression, all mappings are flat: | 25 | * during kernel decompression, all mappings are flat: |
26 | * virt_addr == phys_addr | 26 | * virt_addr == phys_addr |
27 | */ | 27 | */ |
28 | if (!SIRFSOC_UART1_PA_BASE) | ||
29 | return; | ||
30 | |||
28 | while (__raw_readl((void __iomem *)SIRFSOC_UART1_PA_BASE + SIRFSOC_UART_TXFIFO_STATUS) | 31 | while (__raw_readl((void __iomem *)SIRFSOC_UART1_PA_BASE + SIRFSOC_UART_TXFIFO_STATUS) |
29 | & SIRFSOC_UART1_TXFIFO_FULL) | 32 | & SIRFSOC_UART1_TXFIFO_FULL) |
30 | barrier(); | 33 | barrier(); |
diff --git a/arch/arm/mach-prima2/irq.c b/arch/arm/mach-prima2/irq.c index 7dee9176e77a..6c0f3e9c43fb 100644 --- a/arch/arm/mach-prima2/irq.c +++ b/arch/arm/mach-prima2/irq.c | |||
@@ -9,17 +9,19 @@ | |||
9 | #include <linux/init.h> | 9 | #include <linux/init.h> |
10 | #include <linux/io.h> | 10 | #include <linux/io.h> |
11 | #include <linux/irq.h> | 11 | #include <linux/irq.h> |
12 | #include <mach/hardware.h> | ||
13 | #include <asm/mach/irq.h> | ||
14 | #include <linux/of.h> | 12 | #include <linux/of.h> |
15 | #include <linux/of_address.h> | 13 | #include <linux/of_address.h> |
16 | #include <linux/irqdomain.h> | 14 | #include <linux/irqdomain.h> |
17 | #include <linux/syscore_ops.h> | 15 | #include <linux/syscore_ops.h> |
16 | #include <asm/mach/irq.h> | ||
17 | #include <asm/exception.h> | ||
18 | #include <mach/hardware.h> | ||
18 | 19 | ||
19 | #define SIRFSOC_INT_RISC_MASK0 0x0018 | 20 | #define SIRFSOC_INT_RISC_MASK0 0x0018 |
20 | #define SIRFSOC_INT_RISC_MASK1 0x001C | 21 | #define SIRFSOC_INT_RISC_MASK1 0x001C |
21 | #define SIRFSOC_INT_RISC_LEVEL0 0x0020 | 22 | #define SIRFSOC_INT_RISC_LEVEL0 0x0020 |
22 | #define SIRFSOC_INT_RISC_LEVEL1 0x0024 | 23 | #define SIRFSOC_INT_RISC_LEVEL1 0x0024 |
24 | #define SIRFSOC_INIT_IRQ_ID 0x0038 | ||
23 | 25 | ||
24 | void __iomem *sirfsoc_intc_base; | 26 | void __iomem *sirfsoc_intc_base; |
25 | 27 | ||
@@ -52,6 +54,16 @@ static __init void sirfsoc_irq_init(void) | |||
52 | writel_relaxed(0, sirfsoc_intc_base + SIRFSOC_INT_RISC_MASK1); | 54 | writel_relaxed(0, sirfsoc_intc_base + SIRFSOC_INT_RISC_MASK1); |
53 | } | 55 | } |
54 | 56 | ||
57 | asmlinkage void __exception_irq_entry sirfsoc_handle_irq(struct pt_regs *regs) | ||
58 | { | ||
59 | u32 irqstat, irqnr; | ||
60 | |||
61 | irqstat = readl_relaxed(sirfsoc_intc_base + SIRFSOC_INIT_IRQ_ID); | ||
62 | irqnr = irqstat & 0xff; | ||
63 | |||
64 | handle_IRQ(irqnr, regs); | ||
65 | } | ||
66 | |||
55 | static struct of_device_id intc_ids[] = { | 67 | static struct of_device_id intc_ids[] = { |
56 | { .compatible = "sirf,prima2-intc" }, | 68 | { .compatible = "sirf,prima2-intc" }, |
57 | {}, | 69 | {}, |
diff --git a/arch/arm/mach-prima2/l2x0.c b/arch/arm/mach-prima2/l2x0.c index c99837797d76..cbcbe9cb094c 100644 --- a/arch/arm/mach-prima2/l2x0.c +++ b/arch/arm/mach-prima2/l2x0.c | |||
@@ -11,19 +11,38 @@ | |||
11 | #include <linux/of.h> | 11 | #include <linux/of.h> |
12 | #include <asm/hardware/cache-l2x0.h> | 12 | #include <asm/hardware/cache-l2x0.h> |
13 | 13 | ||
14 | static struct of_device_id prima2_l2x0_ids[] = { | 14 | struct l2x0_aux |
15 | { .compatible = "sirf,prima2-pl310-cache" }, | 15 | { |
16 | u32 val; | ||
17 | u32 mask; | ||
18 | }; | ||
19 | |||
20 | static struct l2x0_aux prima2_l2x0_aux __initconst = { | ||
21 | .val = 2 << L2X0_AUX_CTRL_WAY_SIZE_SHIFT, | ||
22 | .mask = 0, | ||
23 | }; | ||
24 | |||
25 | static struct l2x0_aux marco_l2x0_aux __initconst = { | ||
26 | .val = (2 << L2X0_AUX_CTRL_WAY_SIZE_SHIFT) | | ||
27 | (1 << L2X0_AUX_CTRL_ASSOCIATIVITY_SHIFT), | ||
28 | .mask = L2X0_AUX_CTRL_MASK, | ||
29 | }; | ||
30 | |||
31 | static struct of_device_id sirf_l2x0_ids[] __initconst = { | ||
32 | { .compatible = "sirf,prima2-pl310-cache", .data = &prima2_l2x0_aux, }, | ||
33 | { .compatible = "sirf,marco-pl310-cache", .data = &marco_l2x0_aux, }, | ||
16 | {}, | 34 | {}, |
17 | }; | 35 | }; |
18 | 36 | ||
19 | static int __init sirfsoc_l2x0_init(void) | 37 | static int __init sirfsoc_l2x0_init(void) |
20 | { | 38 | { |
21 | struct device_node *np; | 39 | struct device_node *np; |
40 | const struct l2x0_aux *aux; | ||
22 | 41 | ||
23 | np = of_find_matching_node(NULL, prima2_l2x0_ids); | 42 | np = of_find_matching_node(NULL, sirf_l2x0_ids); |
24 | if (np) { | 43 | if (np) { |
25 | pr_info("Initializing prima2 L2 cache\n"); | 44 | aux = of_match_node(sirf_l2x0_ids, np)->data; |
26 | return l2x0_of_init(0x40000, 0); | 45 | return l2x0_of_init(aux->val, aux->mask); |
27 | } | 46 | } |
28 | 47 | ||
29 | return 0; | 48 | return 0; |
diff --git a/arch/arm/mach-prima2/platsmp.c b/arch/arm/mach-prima2/platsmp.c new file mode 100644 index 000000000000..2395022bc733 --- /dev/null +++ b/arch/arm/mach-prima2/platsmp.c | |||
@@ -0,0 +1,163 @@ | |||
1 | /* | ||
2 | * plat smp support for CSR Marco dual-core SMP SoCs | ||
3 | * | ||
4 | * Copyright (c) 2012 Cambridge Silicon Radio Limited, a CSR plc group company. | ||
5 | * | ||
6 | * Licensed under GPLv2 or later. | ||
7 | */ | ||
8 | |||
9 | #include <linux/init.h> | ||
10 | #include <linux/smp.h> | ||
11 | #include <linux/delay.h> | ||
12 | #include <linux/of.h> | ||
13 | #include <linux/of_address.h> | ||
14 | #include <asm/page.h> | ||
15 | #include <asm/mach/map.h> | ||
16 | #include <asm/smp_plat.h> | ||
17 | #include <asm/smp_scu.h> | ||
18 | #include <asm/cacheflush.h> | ||
19 | #include <asm/cputype.h> | ||
20 | #include <asm/hardware/gic.h> | ||
21 | #include <mach/map.h> | ||
22 | |||
23 | #include "common.h" | ||
24 | |||
25 | static void __iomem *scu_base; | ||
26 | static void __iomem *rsc_base; | ||
27 | |||
28 | static DEFINE_SPINLOCK(boot_lock); | ||
29 | |||
30 | static struct map_desc scu_io_desc __initdata = { | ||
31 | .length = SZ_4K, | ||
32 | .type = MT_DEVICE, | ||
33 | }; | ||
34 | |||
35 | void __init sirfsoc_map_scu(void) | ||
36 | { | ||
37 | unsigned long base; | ||
38 | |||
39 | /* Get SCU base */ | ||
40 | asm("mrc p15, 4, %0, c15, c0, 0" : "=r" (base)); | ||
41 | |||
42 | scu_io_desc.virtual = SIRFSOC_VA(base); | ||
43 | scu_io_desc.pfn = __phys_to_pfn(base); | ||
44 | iotable_init(&scu_io_desc, 1); | ||
45 | |||
46 | scu_base = (void __iomem *)SIRFSOC_VA(base); | ||
47 | } | ||
48 | |||
49 | static void __cpuinit sirfsoc_secondary_init(unsigned int cpu) | ||
50 | { | ||
51 | /* | ||
52 | * if any interrupts are already enabled for the primary | ||
53 | * core (e.g. timer irq), then they will not have been enabled | ||
54 | * for us: do so | ||
55 | */ | ||
56 | gic_secondary_init(0); | ||
57 | |||
58 | /* | ||
59 | * let the primary processor know we're out of the | ||
60 | * pen, then head off into the C entry point | ||
61 | */ | ||
62 | pen_release = -1; | ||
63 | smp_wmb(); | ||
64 | |||
65 | /* | ||
66 | * Synchronise with the boot thread. | ||
67 | */ | ||
68 | spin_lock(&boot_lock); | ||
69 | spin_unlock(&boot_lock); | ||
70 | } | ||
71 | |||
72 | static struct of_device_id rsc_ids[] = { | ||
73 | { .compatible = "sirf,marco-rsc" }, | ||
74 | {}, | ||
75 | }; | ||
76 | |||
77 | static int __cpuinit sirfsoc_boot_secondary(unsigned int cpu, struct task_struct *idle) | ||
78 | { | ||
79 | unsigned long timeout; | ||
80 | struct device_node *np; | ||
81 | |||
82 | np = of_find_matching_node(NULL, rsc_ids); | ||
83 | if (!np) | ||
84 | return -ENODEV; | ||
85 | |||
86 | rsc_base = of_iomap(np, 0); | ||
87 | if (!rsc_base) | ||
88 | return -ENOMEM; | ||
89 | |||
90 | /* | ||
91 | * write the address of secondary startup into the sram register | ||
92 | * at offset 0x2C, then write the magic number 0x3CAF5D62 to the | ||
93 | * RSC register at offset 0x28, which is what boot rom code is | ||
94 | * waiting for. This would wake up the secondary core from WFE | ||
95 | */ | ||
96 | #define SIRFSOC_CPU1_JUMPADDR_OFFSET 0x2C | ||
97 | __raw_writel(virt_to_phys(sirfsoc_secondary_startup), | ||
98 | rsc_base + SIRFSOC_CPU1_JUMPADDR_OFFSET); | ||
99 | |||
100 | #define SIRFSOC_CPU1_WAKEMAGIC_OFFSET 0x28 | ||
101 | __raw_writel(0x3CAF5D62, | ||
102 | rsc_base + SIRFSOC_CPU1_WAKEMAGIC_OFFSET); | ||
103 | |||
104 | /* make sure write buffer is drained */ | ||
105 | mb(); | ||
106 | |||
107 | spin_lock(&boot_lock); | ||
108 | |||
109 | /* | ||
110 | * The secondary processor is waiting to be released from | ||
111 | * the holding pen - release it, then wait for it to flag | ||
112 | * that it has been released by resetting pen_release. | ||
113 | * | ||
114 | * Note that "pen_release" is the hardware CPU ID, whereas | ||
115 | * "cpu" is Linux's internal ID. | ||
116 | */ | ||
117 | pen_release = cpu_logical_map(cpu); | ||
118 | __cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release)); | ||
119 | outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1)); | ||
120 | |||
121 | /* | ||
122 | * Send the secondary CPU SEV, thereby causing the boot monitor to read | ||
123 | * the JUMPADDR and WAKEMAGIC, and branch to the address found there. | ||
124 | */ | ||
125 | dsb_sev(); | ||
126 | |||
127 | timeout = jiffies + (1 * HZ); | ||
128 | while (time_before(jiffies, timeout)) { | ||
129 | smp_rmb(); | ||
130 | if (pen_release == -1) | ||
131 | break; | ||
132 | |||
133 | udelay(10); | ||
134 | } | ||
135 | |||
136 | /* | ||
137 | * now the secondary core is starting up let it run its | ||
138 | * calibrations, then wait for it to finish | ||
139 | */ | ||
140 | spin_unlock(&boot_lock); | ||
141 | |||
142 | return pen_release != -1 ? -ENOSYS : 0; | ||
143 | } | ||
144 | |||
145 | static void __init sirfsoc_smp_init_cpus(void) | ||
146 | { | ||
147 | set_smp_cross_call(gic_raise_softirq); | ||
148 | } | ||
149 | |||
150 | static void __init sirfsoc_smp_prepare_cpus(unsigned int max_cpus) | ||
151 | { | ||
152 | scu_enable(scu_base); | ||
153 | } | ||
154 | |||
155 | struct smp_operations sirfsoc_smp_ops __initdata = { | ||
156 | .smp_init_cpus = sirfsoc_smp_init_cpus, | ||
157 | .smp_prepare_cpus = sirfsoc_smp_prepare_cpus, | ||
158 | .smp_secondary_init = sirfsoc_secondary_init, | ||
159 | .smp_boot_secondary = sirfsoc_boot_secondary, | ||
160 | #ifdef CONFIG_HOTPLUG_CPU | ||
161 | .cpu_die = sirfsoc_cpu_die, | ||
162 | #endif | ||
163 | }; | ||
diff --git a/arch/arm/mach-prima2/rstc.c b/arch/arm/mach-prima2/rstc.c index 762adb73ab7c..435019ca0a48 100644 --- a/arch/arm/mach-prima2/rstc.c +++ b/arch/arm/mach-prima2/rstc.c | |||
@@ -19,6 +19,7 @@ static DEFINE_MUTEX(rstc_lock); | |||
19 | 19 | ||
20 | static struct of_device_id rstc_ids[] = { | 20 | static struct of_device_id rstc_ids[] = { |
21 | { .compatible = "sirf,prima2-rstc" }, | 21 | { .compatible = "sirf,prima2-rstc" }, |
22 | { .compatible = "sirf,marco-rstc" }, | ||
22 | {}, | 23 | {}, |
23 | }; | 24 | }; |
24 | 25 | ||
@@ -42,27 +43,37 @@ early_initcall(sirfsoc_of_rstc_init); | |||
42 | 43 | ||
43 | int sirfsoc_reset_device(struct device *dev) | 44 | int sirfsoc_reset_device(struct device *dev) |
44 | { | 45 | { |
45 | const unsigned int *prop = of_get_property(dev->of_node, "reset-bit", NULL); | 46 | u32 reset_bit; |
46 | unsigned int reset_bit; | ||
47 | 47 | ||
48 | if (!prop) | 48 | if (of_property_read_u32(dev->of_node, "reset-bit", &reset_bit)) |
49 | return -ENODEV; | 49 | return -EINVAL; |
50 | |||
51 | reset_bit = be32_to_cpup(prop); | ||
52 | 50 | ||
53 | mutex_lock(&rstc_lock); | 51 | mutex_lock(&rstc_lock); |
54 | 52 | ||
55 | /* | 53 | if (of_device_is_compatible(dev->of_node, "sirf,prima2-rstc")) { |
56 | * Writing 1 to this bit resets corresponding block. Writing 0 to this | 54 | /* |
57 | * bit de-asserts reset signal of the corresponding block. | 55 | * Writing 1 to this bit resets corresponding block. Writing 0 to this |
58 | * datasheet doesn't require explicit delay between the set and clear | 56 | * bit de-asserts reset signal of the corresponding block. |
59 | * of reset bit. it could be shorter if tests pass. | 57 | * datasheet doesn't require explicit delay between the set and clear |
60 | */ | 58 | * of reset bit. it could be shorter if tests pass. |
61 | writel(readl(sirfsoc_rstc_base + (reset_bit / 32) * 4) | reset_bit, | 59 | */ |
62 | sirfsoc_rstc_base + (reset_bit / 32) * 4); | 60 | writel(readl(sirfsoc_rstc_base + (reset_bit / 32) * 4) | reset_bit, |
63 | msleep(10); | 61 | sirfsoc_rstc_base + (reset_bit / 32) * 4); |
64 | writel(readl(sirfsoc_rstc_base + (reset_bit / 32) * 4) & ~reset_bit, | 62 | msleep(10); |
65 | sirfsoc_rstc_base + (reset_bit / 32) * 4); | 63 | writel(readl(sirfsoc_rstc_base + (reset_bit / 32) * 4) & ~reset_bit, |
64 | sirfsoc_rstc_base + (reset_bit / 32) * 4); | ||
65 | } else { | ||
66 | /* | ||
67 | * For MARCO and POLO | ||
68 | * Writing 1 to SET register resets corresponding block. Writing 1 to CLEAR | ||
69 | * register de-asserts reset signal of the corresponding block. | ||
70 | * datasheet doesn't require explicit delay between the set and clear | ||
71 | * of reset bit. it could be shorter if tests pass. | ||
72 | */ | ||
73 | writel(reset_bit, sirfsoc_rstc_base + (reset_bit / 32) * 8); | ||
74 | msleep(10); | ||
75 | writel(reset_bit, sirfsoc_rstc_base + (reset_bit / 32) * 8 + 4); | ||
76 | } | ||
66 | 77 | ||
67 | mutex_unlock(&rstc_lock); | 78 | mutex_unlock(&rstc_lock); |
68 | 79 | ||
diff --git a/arch/arm/mach-prima2/rtciobrg.c b/arch/arm/mach-prima2/rtciobrg.c index 557353602130..9f2da2eec4dc 100644 --- a/arch/arm/mach-prima2/rtciobrg.c +++ b/arch/arm/mach-prima2/rtciobrg.c | |||
@@ -104,6 +104,7 @@ EXPORT_SYMBOL_GPL(sirfsoc_rtc_iobrg_writel); | |||
104 | 104 | ||
105 | static const struct of_device_id rtciobrg_ids[] = { | 105 | static const struct of_device_id rtciobrg_ids[] = { |
106 | { .compatible = "sirf,prima2-rtciobg" }, | 106 | { .compatible = "sirf,prima2-rtciobg" }, |
107 | { .compatible = "sirf,marco-rtciobg" }, | ||
107 | {} | 108 | {} |
108 | }; | 109 | }; |
109 | 110 | ||
diff --git a/arch/arm/mach-prima2/timer-marco.c b/arch/arm/mach-prima2/timer-marco.c new file mode 100644 index 000000000000..f4eea2e97eb0 --- /dev/null +++ b/arch/arm/mach-prima2/timer-marco.c | |||
@@ -0,0 +1,316 @@ | |||
1 | /* | ||
2 | * System timer for CSR SiRFprimaII | ||
3 | * | ||
4 | * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. | ||
5 | * | ||
6 | * Licensed under GPLv2 or later. | ||
7 | */ | ||
8 | |||
9 | #include <linux/kernel.h> | ||
10 | #include <linux/interrupt.h> | ||
11 | #include <linux/clockchips.h> | ||
12 | #include <linux/clocksource.h> | ||
13 | #include <linux/bitops.h> | ||
14 | #include <linux/irq.h> | ||
15 | #include <linux/clk.h> | ||
16 | #include <linux/slab.h> | ||
17 | #include <linux/of.h> | ||
18 | #include <linux/of_irq.h> | ||
19 | #include <linux/of_address.h> | ||
20 | #include <asm/sched_clock.h> | ||
21 | #include <asm/localtimer.h> | ||
22 | #include <asm/mach/time.h> | ||
23 | |||
24 | #include "common.h" | ||
25 | |||
26 | #define SIRFSOC_TIMER_32COUNTER_0_CTRL 0x0000 | ||
27 | #define SIRFSOC_TIMER_32COUNTER_1_CTRL 0x0004 | ||
28 | #define SIRFSOC_TIMER_MATCH_0 0x0018 | ||
29 | #define SIRFSOC_TIMER_MATCH_1 0x001c | ||
30 | #define SIRFSOC_TIMER_COUNTER_0 0x0048 | ||
31 | #define SIRFSOC_TIMER_COUNTER_1 0x004c | ||
32 | #define SIRFSOC_TIMER_INTR_STATUS 0x0060 | ||
33 | #define SIRFSOC_TIMER_WATCHDOG_EN 0x0064 | ||
34 | #define SIRFSOC_TIMER_64COUNTER_CTRL 0x0068 | ||
35 | #define SIRFSOC_TIMER_64COUNTER_LO 0x006c | ||
36 | #define SIRFSOC_TIMER_64COUNTER_HI 0x0070 | ||
37 | #define SIRFSOC_TIMER_64COUNTER_LOAD_LO 0x0074 | ||
38 | #define SIRFSOC_TIMER_64COUNTER_LOAD_HI 0x0078 | ||
39 | #define SIRFSOC_TIMER_64COUNTER_RLATCHED_LO 0x007c | ||
40 | #define SIRFSOC_TIMER_64COUNTER_RLATCHED_HI 0x0080 | ||
41 | |||
42 | #define SIRFSOC_TIMER_REG_CNT 6 | ||
43 | |||
44 | static const u32 sirfsoc_timer_reg_list[SIRFSOC_TIMER_REG_CNT] = { | ||
45 | SIRFSOC_TIMER_WATCHDOG_EN, | ||
46 | SIRFSOC_TIMER_32COUNTER_0_CTRL, | ||
47 | SIRFSOC_TIMER_32COUNTER_1_CTRL, | ||
48 | SIRFSOC_TIMER_64COUNTER_CTRL, | ||
49 | SIRFSOC_TIMER_64COUNTER_RLATCHED_LO, | ||
50 | SIRFSOC_TIMER_64COUNTER_RLATCHED_HI, | ||
51 | }; | ||
52 | |||
53 | static u32 sirfsoc_timer_reg_val[SIRFSOC_TIMER_REG_CNT]; | ||
54 | |||
55 | static void __iomem *sirfsoc_timer_base; | ||
56 | static void __init sirfsoc_of_timer_map(void); | ||
57 | |||
58 | /* disable count and interrupt */ | ||
59 | static inline void sirfsoc_timer_count_disable(int idx) | ||
60 | { | ||
61 | writel_relaxed(readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_32COUNTER_0_CTRL + 4 * idx) & ~0x7, | ||
62 | sirfsoc_timer_base + SIRFSOC_TIMER_32COUNTER_0_CTRL + 4 * idx); | ||
63 | } | ||
64 | |||
65 | /* enable count and interrupt */ | ||
66 | static inline void sirfsoc_timer_count_enable(int idx) | ||
67 | { | ||
68 | writel_relaxed(readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_32COUNTER_0_CTRL + 4 * idx) | 0x7, | ||
69 | sirfsoc_timer_base + SIRFSOC_TIMER_32COUNTER_0_CTRL + 4 * idx); | ||
70 | } | ||
71 | |||
72 | /* timer interrupt handler */ | ||
73 | static irqreturn_t sirfsoc_timer_interrupt(int irq, void *dev_id) | ||
74 | { | ||
75 | struct clock_event_device *ce = dev_id; | ||
76 | int cpu = smp_processor_id(); | ||
77 | |||
78 | /* clear timer interrupt */ | ||
79 | writel_relaxed(BIT(cpu), sirfsoc_timer_base + SIRFSOC_TIMER_INTR_STATUS); | ||
80 | |||
81 | if (ce->mode == CLOCK_EVT_MODE_ONESHOT) | ||
82 | sirfsoc_timer_count_disable(cpu); | ||
83 | |||
84 | ce->event_handler(ce); | ||
85 | |||
86 | return IRQ_HANDLED; | ||
87 | } | ||
88 | |||
89 | /* read 64-bit timer counter */ | ||
90 | static cycle_t sirfsoc_timer_read(struct clocksource *cs) | ||
91 | { | ||
92 | u64 cycles; | ||
93 | |||
94 | writel_relaxed((readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_64COUNTER_CTRL) | | ||
95 | BIT(0)) & ~BIT(1), sirfsoc_timer_base + SIRFSOC_TIMER_64COUNTER_CTRL); | ||
96 | |||
97 | cycles = readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_64COUNTER_RLATCHED_HI); | ||
98 | cycles = (cycles << 32) | readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_64COUNTER_RLATCHED_LO); | ||
99 | |||
100 | return cycles; | ||
101 | } | ||
102 | |||
103 | static int sirfsoc_timer_set_next_event(unsigned long delta, | ||
104 | struct clock_event_device *ce) | ||
105 | { | ||
106 | int cpu = smp_processor_id(); | ||
107 | |||
108 | writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_0 + | ||
109 | 4 * cpu); | ||
110 | writel_relaxed(delta, sirfsoc_timer_base + SIRFSOC_TIMER_MATCH_0 + | ||
111 | 4 * cpu); | ||
112 | |||
113 | /* enable the tick */ | ||
114 | sirfsoc_timer_count_enable(cpu); | ||
115 | |||
116 | return 0; | ||
117 | } | ||
118 | |||
119 | static void sirfsoc_timer_set_mode(enum clock_event_mode mode, | ||
120 | struct clock_event_device *ce) | ||
121 | { | ||
122 | switch (mode) { | ||
123 | case CLOCK_EVT_MODE_ONESHOT: | ||
124 | /* enable in set_next_event */ | ||
125 | break; | ||
126 | default: | ||
127 | break; | ||
128 | } | ||
129 | |||
130 | sirfsoc_timer_count_disable(smp_processor_id()); | ||
131 | } | ||
132 | |||
133 | static void sirfsoc_clocksource_suspend(struct clocksource *cs) | ||
134 | { | ||
135 | int i; | ||
136 | |||
137 | for (i = 0; i < SIRFSOC_TIMER_REG_CNT; i++) | ||
138 | sirfsoc_timer_reg_val[i] = readl_relaxed(sirfsoc_timer_base + sirfsoc_timer_reg_list[i]); | ||
139 | } | ||
140 | |||
141 | static void sirfsoc_clocksource_resume(struct clocksource *cs) | ||
142 | { | ||
143 | int i; | ||
144 | |||
145 | for (i = 0; i < SIRFSOC_TIMER_REG_CNT - 2; i++) | ||
146 | writel_relaxed(sirfsoc_timer_reg_val[i], sirfsoc_timer_base + sirfsoc_timer_reg_list[i]); | ||
147 | |||
148 | writel_relaxed(sirfsoc_timer_reg_val[SIRFSOC_TIMER_REG_CNT - 2], | ||
149 | sirfsoc_timer_base + SIRFSOC_TIMER_64COUNTER_LOAD_LO); | ||
150 | writel_relaxed(sirfsoc_timer_reg_val[SIRFSOC_TIMER_REG_CNT - 1], | ||
151 | sirfsoc_timer_base + SIRFSOC_TIMER_64COUNTER_LOAD_HI); | ||
152 | |||
153 | writel_relaxed(readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_64COUNTER_CTRL) | | ||
154 | BIT(1) | BIT(0), sirfsoc_timer_base + SIRFSOC_TIMER_64COUNTER_CTRL); | ||
155 | } | ||
156 | |||
157 | static struct clock_event_device sirfsoc_clockevent = { | ||
158 | .name = "sirfsoc_clockevent", | ||
159 | .rating = 200, | ||
160 | .features = CLOCK_EVT_FEAT_ONESHOT, | ||
161 | .set_mode = sirfsoc_timer_set_mode, | ||
162 | .set_next_event = sirfsoc_timer_set_next_event, | ||
163 | }; | ||
164 | |||
165 | static struct clocksource sirfsoc_clocksource = { | ||
166 | .name = "sirfsoc_clocksource", | ||
167 | .rating = 200, | ||
168 | .mask = CLOCKSOURCE_MASK(64), | ||
169 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, | ||
170 | .read = sirfsoc_timer_read, | ||
171 | .suspend = sirfsoc_clocksource_suspend, | ||
172 | .resume = sirfsoc_clocksource_resume, | ||
173 | }; | ||
174 | |||
175 | static struct irqaction sirfsoc_timer_irq = { | ||
176 | .name = "sirfsoc_timer0", | ||
177 | .flags = IRQF_TIMER | IRQF_NOBALANCING, | ||
178 | .handler = sirfsoc_timer_interrupt, | ||
179 | .dev_id = &sirfsoc_clockevent, | ||
180 | }; | ||
181 | |||
182 | #ifdef CONFIG_LOCAL_TIMERS | ||
183 | |||
184 | static struct irqaction sirfsoc_timer1_irq = { | ||
185 | .name = "sirfsoc_timer1", | ||
186 | .flags = IRQF_TIMER | IRQF_NOBALANCING, | ||
187 | .handler = sirfsoc_timer_interrupt, | ||
188 | }; | ||
189 | |||
190 | static int __cpuinit sirfsoc_local_timer_setup(struct clock_event_device *ce) | ||
191 | { | ||
192 | /* Use existing clock_event for cpu 0 */ | ||
193 | if (!smp_processor_id()) | ||
194 | return 0; | ||
195 | |||
196 | ce->irq = sirfsoc_timer1_irq.irq; | ||
197 | ce->name = "local_timer"; | ||
198 | ce->features = sirfsoc_clockevent.features; | ||
199 | ce->rating = sirfsoc_clockevent.rating; | ||
200 | ce->set_mode = sirfsoc_timer_set_mode; | ||
201 | ce->set_next_event = sirfsoc_timer_set_next_event; | ||
202 | ce->shift = sirfsoc_clockevent.shift; | ||
203 | ce->mult = sirfsoc_clockevent.mult; | ||
204 | ce->max_delta_ns = sirfsoc_clockevent.max_delta_ns; | ||
205 | ce->min_delta_ns = sirfsoc_clockevent.min_delta_ns; | ||
206 | |||
207 | sirfsoc_timer1_irq.dev_id = ce; | ||
208 | BUG_ON(setup_irq(ce->irq, &sirfsoc_timer1_irq)); | ||
209 | irq_set_affinity(sirfsoc_timer1_irq.irq, cpumask_of(1)); | ||
210 | |||
211 | clockevents_register_device(ce); | ||
212 | return 0; | ||
213 | } | ||
214 | |||
215 | static void sirfsoc_local_timer_stop(struct clock_event_device *ce) | ||
216 | { | ||
217 | sirfsoc_timer_count_disable(1); | ||
218 | |||
219 | remove_irq(sirfsoc_timer1_irq.irq, &sirfsoc_timer1_irq); | ||
220 | } | ||
221 | |||
222 | static struct local_timer_ops sirfsoc_local_timer_ops __cpuinitdata = { | ||
223 | .setup = sirfsoc_local_timer_setup, | ||
224 | .stop = sirfsoc_local_timer_stop, | ||
225 | }; | ||
226 | #endif /* CONFIG_LOCAL_TIMERS */ | ||
227 | |||
228 | static void __init sirfsoc_clockevent_init(void) | ||
229 | { | ||
230 | clockevents_calc_mult_shift(&sirfsoc_clockevent, CLOCK_TICK_RATE, 60); | ||
231 | |||
232 | sirfsoc_clockevent.max_delta_ns = | ||
233 | clockevent_delta2ns(-2, &sirfsoc_clockevent); | ||
234 | sirfsoc_clockevent.min_delta_ns = | ||
235 | clockevent_delta2ns(2, &sirfsoc_clockevent); | ||
236 | |||
237 | sirfsoc_clockevent.cpumask = cpumask_of(0); | ||
238 | clockevents_register_device(&sirfsoc_clockevent); | ||
239 | #ifdef CONFIG_LOCAL_TIMERS | ||
240 | local_timer_register(&sirfsoc_local_timer_ops); | ||
241 | #endif | ||
242 | } | ||
243 | |||
244 | /* initialize the kernel jiffy timer source */ | ||
245 | void __init sirfsoc_marco_timer_init(void) | ||
246 | { | ||
247 | unsigned long rate; | ||
248 | u32 timer_div; | ||
249 | struct clk *clk; | ||
250 | |||
251 | /* initialize clocking early, we want to set the OS timer */ | ||
252 | sirfsoc_of_clk_init(); | ||
253 | |||
254 | /* timer's input clock is io clock */ | ||
255 | clk = clk_get_sys("io", NULL); | ||
256 | |||
257 | BUG_ON(IS_ERR(clk)); | ||
258 | rate = clk_get_rate(clk); | ||
259 | |||
260 | BUG_ON(rate < CLOCK_TICK_RATE); | ||
261 | BUG_ON(rate % CLOCK_TICK_RATE); | ||
262 | |||
263 | sirfsoc_of_timer_map(); | ||
264 | |||
265 | /* Initialize the timer dividers */ | ||
266 | timer_div = rate / CLOCK_TICK_RATE - 1; | ||
267 | writel_relaxed(timer_div << 16, sirfsoc_timer_base + SIRFSOC_TIMER_64COUNTER_CTRL); | ||
268 | writel_relaxed(timer_div << 16, sirfsoc_timer_base + SIRFSOC_TIMER_32COUNTER_0_CTRL); | ||
269 | writel_relaxed(timer_div << 16, sirfsoc_timer_base + SIRFSOC_TIMER_32COUNTER_1_CTRL); | ||
270 | |||
271 | /* Initialize timer counters to 0 */ | ||
272 | writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_64COUNTER_LOAD_LO); | ||
273 | writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_64COUNTER_LOAD_HI); | ||
274 | writel_relaxed(readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_64COUNTER_CTRL) | | ||
275 | BIT(1) | BIT(0), sirfsoc_timer_base + SIRFSOC_TIMER_64COUNTER_CTRL); | ||
276 | writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_0); | ||
277 | writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_1); | ||
278 | |||
279 | /* Clear all interrupts */ | ||
280 | writel_relaxed(0xFFFF, sirfsoc_timer_base + SIRFSOC_TIMER_INTR_STATUS); | ||
281 | |||
282 | BUG_ON(clocksource_register_hz(&sirfsoc_clocksource, CLOCK_TICK_RATE)); | ||
283 | |||
284 | BUG_ON(setup_irq(sirfsoc_timer_irq.irq, &sirfsoc_timer_irq)); | ||
285 | |||
286 | sirfsoc_clockevent_init(); | ||
287 | } | ||
288 | |||
289 | static struct of_device_id timer_ids[] = { | ||
290 | { .compatible = "sirf,marco-tick" }, | ||
291 | {}, | ||
292 | }; | ||
293 | |||
294 | static void __init sirfsoc_of_timer_map(void) | ||
295 | { | ||
296 | struct device_node *np; | ||
297 | |||
298 | np = of_find_matching_node(NULL, timer_ids); | ||
299 | if (!np) | ||
300 | return; | ||
301 | sirfsoc_timer_base = of_iomap(np, 0); | ||
302 | if (!sirfsoc_timer_base) | ||
303 | panic("unable to map timer cpu registers\n"); | ||
304 | |||
305 | sirfsoc_timer_irq.irq = irq_of_parse_and_map(np, 0); | ||
306 | if (!sirfsoc_timer_irq.irq) | ||
307 | panic("No irq passed for timer0 via DT\n"); | ||
308 | |||
309 | #ifdef CONFIG_LOCAL_TIMERS | ||
310 | sirfsoc_timer1_irq.irq = irq_of_parse_and_map(np, 1); | ||
311 | if (!sirfsoc_timer1_irq.irq) | ||
312 | panic("No irq passed for timer1 via DT\n"); | ||
313 | #endif | ||
314 | |||
315 | of_node_put(np); | ||
316 | } | ||
diff --git a/arch/arm/mach-prima2/timer.c b/arch/arm/mach-prima2/timer-prima2.c index a7a2c199c3ea..6da584f8a949 100644 --- a/arch/arm/mach-prima2/timer.c +++ b/arch/arm/mach-prima2/timer-prima2.c | |||
@@ -181,7 +181,7 @@ static void __init sirfsoc_clockevent_init(void) | |||
181 | } | 181 | } |
182 | 182 | ||
183 | /* initialize the kernel jiffy timer source */ | 183 | /* initialize the kernel jiffy timer source */ |
184 | void __init sirfsoc_timer_init(void) | 184 | void __init sirfsoc_prima2_timer_init(void) |
185 | { | 185 | { |
186 | unsigned long rate; | 186 | unsigned long rate; |
187 | struct clk *clk; | 187 | struct clk *clk; |
@@ -220,14 +220,14 @@ static struct of_device_id timer_ids[] = { | |||
220 | {}, | 220 | {}, |
221 | }; | 221 | }; |
222 | 222 | ||
223 | void __init sirfsoc_of_timer_map(void) | 223 | static void __init sirfsoc_of_timer_map(void) |
224 | { | 224 | { |
225 | struct device_node *np; | 225 | struct device_node *np; |
226 | const unsigned int *intspec; | 226 | const unsigned int *intspec; |
227 | 227 | ||
228 | np = of_find_matching_node(NULL, timer_ids); | 228 | np = of_find_matching_node(NULL, timer_ids); |
229 | if (!np) | 229 | if (!np) |
230 | panic("unable to find compatible timer node in dtb\n"); | 230 | return; |
231 | sirfsoc_timer_base = of_iomap(np, 0); | 231 | sirfsoc_timer_base = of_iomap(np, 0); |
232 | if (!sirfsoc_timer_base) | 232 | if (!sirfsoc_timer_base) |
233 | panic("unable to map timer cpu registers\n"); | 233 | panic("unable to map timer cpu registers\n"); |