aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/boot/dts/highbank.dts8
-rw-r--r--arch/arm/boot/dts/imx6q.dtsi6
-rw-r--r--arch/arm/include/asm/hardware/arm_timer.h5
-rw-r--r--arch/arm/include/asm/localtimer.h37
-rw-r--r--arch/arm/include/asm/smp_twd.h25
-rw-r--r--arch/arm/kernel/smp.c22
-rw-r--r--arch/arm/kernel/smp_twd.c123
-rw-r--r--arch/arm/mach-exynos/mct.c18
-rw-r--r--arch/arm/mach-highbank/Makefile1
-rw-r--r--arch/arm/mach-highbank/highbank.c3
-rw-r--r--arch/arm/mach-highbank/localtimer.c40
-rw-r--r--arch/arm/mach-imx/Makefile1
-rw-r--r--arch/arm/mach-imx/localtimer.c35
-rw-r--r--arch/arm/mach-imx/mach-imx6q.c2
-rw-r--r--arch/arm/mach-msm/timer.c79
-rw-r--r--arch/arm/mach-nomadik/board-nhk8815.c7
-rw-r--r--arch/arm/mach-nomadik/include/mach/setup.h19
-rw-r--r--arch/arm/mach-omap2/Makefile1
-rw-r--r--arch/arm/mach-omap2/timer-mpu.c39
-rw-r--r--arch/arm/mach-omap2/timer.c22
-rw-r--r--arch/arm/mach-realview/realview_eb.c27
-rw-r--r--arch/arm/mach-realview/realview_pb11mp.c21
-rw-r--r--arch/arm/mach-realview/realview_pbx.c20
-rw-r--r--arch/arm/mach-shmobile/Makefile1
-rw-r--r--arch/arm/mach-shmobile/board-ag5evm.c39
-rw-r--r--arch/arm/mach-shmobile/board-ap4evb.c44
-rw-r--r--arch/arm/mach-shmobile/board-bonito.c44
-rw-r--r--arch/arm/mach-shmobile/board-g3evm.c38
-rw-r--r--arch/arm/mach-shmobile/board-g4evm.c38
-rw-r--r--arch/arm/mach-shmobile/board-kota2.c38
-rw-r--r--arch/arm/mach-shmobile/board-mackerel.c39
-rw-r--r--arch/arm/mach-shmobile/board-marzen.c62
-rw-r--r--arch/arm/mach-shmobile/clock-r8a7740.c8
-rw-r--r--arch/arm/mach-shmobile/clock-r8a7779.c4
-rw-r--r--arch/arm/mach-shmobile/clock-sh7367.c8
-rw-r--r--arch/arm/mach-shmobile/clock-sh7372.c10
-rw-r--r--arch/arm/mach-shmobile/clock-sh7377.c8
-rw-r--r--arch/arm/mach-shmobile/clock-sh73a0.c14
-rw-r--r--arch/arm/mach-shmobile/clock.c2
-rw-r--r--arch/arm/mach-shmobile/include/mach/common.h11
-rw-r--r--arch/arm/mach-shmobile/localtimer.c26
-rw-r--r--arch/arm/mach-shmobile/platsmp.c1
-rw-r--r--arch/arm/mach-shmobile/setup-r8a7740.c45
-rw-r--r--arch/arm/mach-shmobile/setup-r8a7779.c54
-rw-r--r--arch/arm/mach-shmobile/setup-sh7367.c32
-rw-r--r--arch/arm/mach-shmobile/setup-sh7372.c32
-rw-r--r--arch/arm/mach-shmobile/setup-sh7377.c32
-rw-r--r--arch/arm/mach-shmobile/setup-sh73a0.c32
-rw-r--r--arch/arm/mach-shmobile/smp-r8a7779.c8
-rw-r--r--arch/arm/mach-shmobile/smp-sh73a0.c8
-rw-r--r--arch/arm/mach-shmobile/timer.c16
-rw-r--r--arch/arm/mach-tegra/Kconfig4
-rw-r--r--arch/arm/mach-tegra/Makefile1
-rw-r--r--arch/arm/mach-tegra/board-harmony-pinmux.c6
-rw-r--r--arch/arm/mach-tegra/localtimer.c26
-rw-r--r--arch/arm/mach-tegra/pcie.c16
-rw-r--r--arch/arm/mach-tegra/timer.c22
-rw-r--r--arch/arm/mach-ux500/Makefile1
-rw-r--r--arch/arm/mach-ux500/cpu.c1
-rw-r--r--arch/arm/mach-ux500/include/mach/setup.h3
-rw-r--r--arch/arm/mach-ux500/localtimer.c29
-rw-r--r--arch/arm/mach-ux500/timer.c39
-rw-r--r--arch/arm/mach-vexpress/core.h7
-rw-r--r--arch/arm/mach-vexpress/ct-ca9x4.c67
-rw-r--r--arch/arm/mach-vexpress/include/mach/ct-ca9x4.h3
-rw-r--r--arch/arm/mach-vexpress/include/mach/motherboard.h52
-rw-r--r--arch/arm/mach-vexpress/platsmp.c5
-rw-r--r--arch/arm/mach-vexpress/v2m.c68
-rw-r--r--arch/arm/plat-nomadik/include/plat/mtu.h4
-rw-r--r--arch/arm/plat-nomadik/timer.c33
-rw-r--r--arch/arm/plat-versatile/Makefile1
-rw-r--r--arch/arm/plat-versatile/localtimer.c27
72 files changed, 793 insertions, 877 deletions
diff --git a/arch/arm/boot/dts/highbank.dts b/arch/arm/boot/dts/highbank.dts
index 305635bd45c0..37c0ff9c8b90 100644
--- a/arch/arm/boot/dts/highbank.dts
+++ b/arch/arm/boot/dts/highbank.dts
@@ -72,15 +72,15 @@
72 ranges; 72 ranges;
73 73
74 timer@fff10600 { 74 timer@fff10600 {
75 compatible = "arm,smp-twd"; 75 compatible = "arm,cortex-a9-twd-timer";
76 reg = <0xfff10600 0x20>; 76 reg = <0xfff10600 0x20>;
77 interrupts = <1 13 0xf04>; 77 interrupts = <1 13 0xf01>;
78 }; 78 };
79 79
80 watchdog@fff10620 { 80 watchdog@fff10620 {
81 compatible = "arm,cortex-a9-wdt"; 81 compatible = "arm,cortex-a9-twd-wdt";
82 reg = <0xfff10620 0x20>; 82 reg = <0xfff10620 0x20>;
83 interrupts = <1 14 0xf04>; 83 interrupts = <1 14 0xf01>;
84 }; 84 };
85 85
86 intc: interrupt-controller@fff11000 { 86 intc: interrupt-controller@fff11000 {
diff --git a/arch/arm/boot/dts/imx6q.dtsi b/arch/arm/boot/dts/imx6q.dtsi
index 263e8f3664b5..4905f51a106f 100644
--- a/arch/arm/boot/dts/imx6q.dtsi
+++ b/arch/arm/boot/dts/imx6q.dtsi
@@ -88,9 +88,9 @@
88 ranges; 88 ranges;
89 89
90 timer@00a00600 { 90 timer@00a00600 {
91 compatible = "arm,smp-twd"; 91 compatible = "arm,cortex-a9-twd-timer";
92 reg = <0x00a00600 0x100>; 92 reg = <0x00a00600 0x20>;
93 interrupts = <1 13 0xf4>; 93 interrupts = <1 13 0xf01>;
94 }; 94 };
95 95
96 L2: l2-cache@00a02000 { 96 L2: l2-cache@00a02000 {
diff --git a/arch/arm/include/asm/hardware/arm_timer.h b/arch/arm/include/asm/hardware/arm_timer.h
index c0f4e7bf22de..d6030ff599db 100644
--- a/arch/arm/include/asm/hardware/arm_timer.h
+++ b/arch/arm/include/asm/hardware/arm_timer.h
@@ -9,7 +9,12 @@
9 * 9 *
10 * Integrator AP has 16-bit timers, Integrator CP, Versatile and Realview 10 * Integrator AP has 16-bit timers, Integrator CP, Versatile and Realview
11 * can have 16-bit or 32-bit selectable via a bit in the control register. 11 * can have 16-bit or 32-bit selectable via a bit in the control register.
12 *
13 * Every SP804 contains two identical timers.
12 */ 14 */
15#define TIMER_1_BASE 0x00
16#define TIMER_2_BASE 0x20
17
13#define TIMER_LOAD 0x00 /* ACVR rw */ 18#define TIMER_LOAD 0x00 /* ACVR rw */
14#define TIMER_VALUE 0x04 /* ACVR ro */ 19#define TIMER_VALUE 0x04 /* ACVR ro */
15#define TIMER_CTRL 0x08 /* ACVR rw */ 20#define TIMER_CTRL 0x08 /* ACVR rw */
diff --git a/arch/arm/include/asm/localtimer.h b/arch/arm/include/asm/localtimer.h
index c6a18424888e..f77ffc1eb0c2 100644
--- a/arch/arm/include/asm/localtimer.h
+++ b/arch/arm/include/asm/localtimer.h
@@ -11,47 +11,24 @@
11#define __ASM_ARM_LOCALTIMER_H 11#define __ASM_ARM_LOCALTIMER_H
12 12
13#include <linux/errno.h> 13#include <linux/errno.h>
14#include <linux/interrupt.h>
15 14
16struct clock_event_device; 15struct clock_event_device;
17 16
18/* 17struct local_timer_ops {
19 * Setup a per-cpu timer, whether it be a local timer or dummy broadcast 18 int (*setup)(struct clock_event_device *);
20 */ 19 void (*stop)(struct clock_event_device *);
21void percpu_timer_setup(void); 20};
22 21
23#ifdef CONFIG_LOCAL_TIMERS 22#ifdef CONFIG_LOCAL_TIMERS
24
25#ifdef CONFIG_HAVE_ARM_TWD
26
27#include "smp_twd.h"
28
29#define local_timer_stop(c) twd_timer_stop((c))
30
31#else
32
33/*
34 * Stop the local timer
35 */
36void local_timer_stop(struct clock_event_device *);
37
38#endif
39
40/* 23/*
41 * Setup a local timer interrupt for a CPU. 24 * Register a local timer driver
42 */ 25 */
43int local_timer_setup(struct clock_event_device *); 26int local_timer_register(struct local_timer_ops *);
44
45#else 27#else
46 28static inline int local_timer_register(struct local_timer_ops *ops)
47static inline int local_timer_setup(struct clock_event_device *evt)
48{ 29{
49 return -ENXIO; 30 return -ENXIO;
50} 31}
51
52static inline void local_timer_stop(struct clock_event_device *evt)
53{
54}
55#endif 32#endif
56 33
57#endif 34#endif
diff --git a/arch/arm/include/asm/smp_twd.h b/arch/arm/include/asm/smp_twd.h
index ef9ffba97ad8..0f01f4677bd2 100644
--- a/arch/arm/include/asm/smp_twd.h
+++ b/arch/arm/include/asm/smp_twd.h
@@ -18,11 +18,28 @@
18#define TWD_TIMER_CONTROL_PERIODIC (1 << 1) 18#define TWD_TIMER_CONTROL_PERIODIC (1 << 1)
19#define TWD_TIMER_CONTROL_IT_ENABLE (1 << 2) 19#define TWD_TIMER_CONTROL_IT_ENABLE (1 << 2)
20 20
21struct clock_event_device; 21#include <linux/ioport.h>
22 22
23extern void __iomem *twd_base; 23struct twd_local_timer {
24 struct resource res[2];
25};
24 26
25void twd_timer_setup(struct clock_event_device *); 27#define DEFINE_TWD_LOCAL_TIMER(name,base,irq) \
26void twd_timer_stop(struct clock_event_device *); 28struct twd_local_timer name __initdata = { \
29 .res = { \
30 DEFINE_RES_MEM(base, 0x10), \
31 DEFINE_RES_IRQ(irq), \
32 }, \
33};
34
35int twd_local_timer_register(struct twd_local_timer *);
36
37#ifdef CONFIG_HAVE_ARM_TWD
38void twd_local_timer_of_register(void);
39#else
40static inline void twd_local_timer_of_register(void)
41{
42}
43#endif
27 44
28#endif 45#endif
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index d616ed51e7a7..8f8cce2c46c4 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -246,6 +246,8 @@ static void __cpuinit smp_store_cpu_info(unsigned int cpuid)
246 store_cpu_topology(cpuid); 246 store_cpu_topology(cpuid);
247} 247}
248 248
249static void percpu_timer_setup(void);
250
249/* 251/*
250 * This is the secondary CPU boot entry. We're using this CPUs 252 * This is the secondary CPU boot entry. We're using this CPUs
251 * idle thread stack, but a set of temporary page tables. 253 * idle thread stack, but a set of temporary page tables.
@@ -452,7 +454,20 @@ static void __cpuinit broadcast_timer_setup(struct clock_event_device *evt)
452 clockevents_register_device(evt); 454 clockevents_register_device(evt);
453} 455}
454 456
455void __cpuinit percpu_timer_setup(void) 457static struct local_timer_ops *lt_ops;
458
459#ifdef CONFIG_LOCAL_TIMERS
460int local_timer_register(struct local_timer_ops *ops)
461{
462 if (lt_ops)
463 return -EBUSY;
464
465 lt_ops = ops;
466 return 0;
467}
468#endif
469
470static void __cpuinit percpu_timer_setup(void)
456{ 471{
457 unsigned int cpu = smp_processor_id(); 472 unsigned int cpu = smp_processor_id();
458 struct clock_event_device *evt = &per_cpu(percpu_clockevent, cpu); 473 struct clock_event_device *evt = &per_cpu(percpu_clockevent, cpu);
@@ -460,7 +475,7 @@ void __cpuinit percpu_timer_setup(void)
460 evt->cpumask = cpumask_of(cpu); 475 evt->cpumask = cpumask_of(cpu);
461 evt->broadcast = smp_timer_broadcast; 476 evt->broadcast = smp_timer_broadcast;
462 477
463 if (local_timer_setup(evt)) 478 if (!lt_ops || lt_ops->setup(evt))
464 broadcast_timer_setup(evt); 479 broadcast_timer_setup(evt);
465} 480}
466 481
@@ -475,7 +490,8 @@ static void percpu_timer_stop(void)
475 unsigned int cpu = smp_processor_id(); 490 unsigned int cpu = smp_processor_id();
476 struct clock_event_device *evt = &per_cpu(percpu_clockevent, cpu); 491 struct clock_event_device *evt = &per_cpu(percpu_clockevent, cpu);
477 492
478 local_timer_stop(evt); 493 if (lt_ops)
494 lt_ops->stop(evt);
479} 495}
480#endif 496#endif
481 497
diff --git a/arch/arm/kernel/smp_twd.c b/arch/arm/kernel/smp_twd.c
index 7a79b24597b2..fef42b21cecb 100644
--- a/arch/arm/kernel/smp_twd.c
+++ b/arch/arm/kernel/smp_twd.c
@@ -18,20 +18,23 @@
18#include <linux/smp.h> 18#include <linux/smp.h>
19#include <linux/jiffies.h> 19#include <linux/jiffies.h>
20#include <linux/clockchips.h> 20#include <linux/clockchips.h>
21#include <linux/irq.h> 21#include <linux/interrupt.h>
22#include <linux/io.h> 22#include <linux/io.h>
23#include <linux/of_irq.h>
24#include <linux/of_address.h>
23 25
24#include <asm/smp_twd.h> 26#include <asm/smp_twd.h>
25#include <asm/localtimer.h> 27#include <asm/localtimer.h>
26#include <asm/hardware/gic.h> 28#include <asm/hardware/gic.h>
27 29
28/* set up by the platform code */ 30/* set up by the platform code */
29void __iomem *twd_base; 31static void __iomem *twd_base;
30 32
31static struct clk *twd_clk; 33static struct clk *twd_clk;
32static unsigned long twd_timer_rate; 34static unsigned long twd_timer_rate;
33 35
34static struct clock_event_device __percpu **twd_evt; 36static struct clock_event_device __percpu **twd_evt;
37static int twd_ppi;
35 38
36static void twd_set_mode(enum clock_event_mode mode, 39static void twd_set_mode(enum clock_event_mode mode,
37 struct clock_event_device *clk) 40 struct clock_event_device *clk)
@@ -77,7 +80,7 @@ static int twd_set_next_event(unsigned long evt,
77 * If a local timer interrupt has occurred, acknowledge and return 1. 80 * If a local timer interrupt has occurred, acknowledge and return 1.
78 * Otherwise, return 0. 81 * Otherwise, return 0.
79 */ 82 */
80int twd_timer_ack(void) 83static int twd_timer_ack(void)
81{ 84{
82 if (__raw_readl(twd_base + TWD_TIMER_INTSTAT)) { 85 if (__raw_readl(twd_base + TWD_TIMER_INTSTAT)) {
83 __raw_writel(1, twd_base + TWD_TIMER_INTSTAT); 86 __raw_writel(1, twd_base + TWD_TIMER_INTSTAT);
@@ -87,7 +90,7 @@ int twd_timer_ack(void)
87 return 0; 90 return 0;
88} 91}
89 92
90void twd_timer_stop(struct clock_event_device *clk) 93static void twd_timer_stop(struct clock_event_device *clk)
91{ 94{
92 twd_set_mode(CLOCK_EVT_MODE_UNUSED, clk); 95 twd_set_mode(CLOCK_EVT_MODE_UNUSED, clk);
93 disable_percpu_irq(clk->irq); 96 disable_percpu_irq(clk->irq);
@@ -222,28 +225,10 @@ static struct clk *twd_get_clock(void)
222/* 225/*
223 * Setup the local clock events for a CPU. 226 * Setup the local clock events for a CPU.
224 */ 227 */
225void __cpuinit twd_timer_setup(struct clock_event_device *clk) 228static int __cpuinit twd_timer_setup(struct clock_event_device *clk)
226{ 229{
227 struct clock_event_device **this_cpu_clk; 230 struct clock_event_device **this_cpu_clk;
228 231
229 if (!twd_evt) {
230 int err;
231
232 twd_evt = alloc_percpu(struct clock_event_device *);
233 if (!twd_evt) {
234 pr_err("twd: can't allocate memory\n");
235 return;
236 }
237
238 err = request_percpu_irq(clk->irq, twd_handler,
239 "twd", twd_evt);
240 if (err) {
241 pr_err("twd: can't register interrupt %d (%d)\n",
242 clk->irq, err);
243 return;
244 }
245 }
246
247 if (!twd_clk) 232 if (!twd_clk)
248 twd_clk = twd_get_clock(); 233 twd_clk = twd_get_clock();
249 234
@@ -260,6 +245,7 @@ void __cpuinit twd_timer_setup(struct clock_event_device *clk)
260 clk->rating = 350; 245 clk->rating = 350;
261 clk->set_mode = twd_set_mode; 246 clk->set_mode = twd_set_mode;
262 clk->set_next_event = twd_set_next_event; 247 clk->set_next_event = twd_set_next_event;
248 clk->irq = twd_ppi;
263 249
264 this_cpu_clk = __this_cpu_ptr(twd_evt); 250 this_cpu_clk = __this_cpu_ptr(twd_evt);
265 *this_cpu_clk = clk; 251 *this_cpu_clk = clk;
@@ -267,4 +253,95 @@ void __cpuinit twd_timer_setup(struct clock_event_device *clk)
267 clockevents_config_and_register(clk, twd_timer_rate, 253 clockevents_config_and_register(clk, twd_timer_rate,
268 0xf, 0xffffffff); 254 0xf, 0xffffffff);
269 enable_percpu_irq(clk->irq, 0); 255 enable_percpu_irq(clk->irq, 0);
256
257 return 0;
258}
259
260static struct local_timer_ops twd_lt_ops __cpuinitdata = {
261 .setup = twd_timer_setup,
262 .stop = twd_timer_stop,
263};
264
265static int __init twd_local_timer_common_register(void)
266{
267 int err;
268
269 twd_evt = alloc_percpu(struct clock_event_device *);
270 if (!twd_evt) {
271 err = -ENOMEM;
272 goto out_free;
273 }
274
275 err = request_percpu_irq(twd_ppi, twd_handler, "twd", twd_evt);
276 if (err) {
277 pr_err("twd: can't register interrupt %d (%d)\n", twd_ppi, err);
278 goto out_free;
279 }
280
281 err = local_timer_register(&twd_lt_ops);
282 if (err)
283 goto out_irq;
284
285 return 0;
286
287out_irq:
288 free_percpu_irq(twd_ppi, twd_evt);
289out_free:
290 iounmap(twd_base);
291 twd_base = NULL;
292 free_percpu(twd_evt);
293
294 return err;
270} 295}
296
297int __init twd_local_timer_register(struct twd_local_timer *tlt)
298{
299 if (twd_base || twd_evt)
300 return -EBUSY;
301
302 twd_ppi = tlt->res[1].start;
303
304 twd_base = ioremap(tlt->res[0].start, resource_size(&tlt->res[0]));
305 if (!twd_base)
306 return -ENOMEM;
307
308 return twd_local_timer_common_register();
309}
310
311#ifdef CONFIG_OF
312const static struct of_device_id twd_of_match[] __initconst = {
313 { .compatible = "arm,cortex-a9-twd-timer", },
314 { .compatible = "arm,cortex-a5-twd-timer", },
315 { .compatible = "arm,arm11mp-twd-timer", },
316 { },
317};
318
319void __init twd_local_timer_of_register(void)
320{
321 struct device_node *np;
322 int err;
323
324 np = of_find_matching_node(NULL, twd_of_match);
325 if (!np) {
326 err = -ENODEV;
327 goto out;
328 }
329
330 twd_ppi = irq_of_parse_and_map(np, 0);
331 if (!twd_ppi) {
332 err = -EINVAL;
333 goto out;
334 }
335
336 twd_base = of_iomap(np, 0);
337 if (!twd_base) {
338 err = -ENOMEM;
339 goto out;
340 }
341
342 err = twd_local_timer_common_register();
343
344out:
345 WARN(err, "twd_local_timer_of_register failed (%d)\n", err);
346}
347#endif
diff --git a/arch/arm/mach-exynos/mct.c b/arch/arm/mach-exynos/mct.c
index 85b5527d0918..edc4b9488f2f 100644
--- a/arch/arm/mach-exynos/mct.c
+++ b/arch/arm/mach-exynos/mct.c
@@ -21,6 +21,7 @@
21#include <linux/percpu.h> 21#include <linux/percpu.h>
22 22
23#include <asm/hardware/gic.h> 23#include <asm/hardware/gic.h>
24#include <asm/localtimer.h>
24 25
25#include <plat/cpu.h> 26#include <plat/cpu.h>
26 27
@@ -375,7 +376,7 @@ static struct irqaction mct_tick1_event_irq = {
375 .handler = exynos4_mct_tick_isr, 376 .handler = exynos4_mct_tick_isr,
376}; 377};
377 378
378static void exynos4_mct_tick_init(struct clock_event_device *evt) 379static int __cpuinit exynos4_local_timer_setup(struct clock_event_device *evt)
379{ 380{
380 struct mct_clock_event_device *mevt; 381 struct mct_clock_event_device *mevt;
381 unsigned int cpu = smp_processor_id(); 382 unsigned int cpu = smp_processor_id();
@@ -417,17 +418,11 @@ static void exynos4_mct_tick_init(struct clock_event_device *evt)
417 } else { 418 } else {
418 enable_percpu_irq(IRQ_MCT_LOCALTIMER, 0); 419 enable_percpu_irq(IRQ_MCT_LOCALTIMER, 0);
419 } 420 }
420}
421
422/* Setup the local clock events for a CPU */
423int __cpuinit local_timer_setup(struct clock_event_device *evt)
424{
425 exynos4_mct_tick_init(evt);
426 421
427 return 0; 422 return 0;
428} 423}
429 424
430void local_timer_stop(struct clock_event_device *evt) 425static void exynos4_local_timer_stop(struct clock_event_device *evt)
431{ 426{
432 unsigned int cpu = smp_processor_id(); 427 unsigned int cpu = smp_processor_id();
433 evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt); 428 evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt);
@@ -439,6 +434,11 @@ void local_timer_stop(struct clock_event_device *evt)
439 else 434 else
440 disable_percpu_irq(IRQ_MCT_LOCALTIMER); 435 disable_percpu_irq(IRQ_MCT_LOCALTIMER);
441} 436}
437
438static struct local_timer_ops exynos4_mct_tick_ops __cpuinitdata = {
439 .setup = exynos4_local_timer_setup,
440 .stop = exynos4_local_timer_stop,
441};
442#endif /* CONFIG_LOCAL_TIMERS */ 442#endif /* CONFIG_LOCAL_TIMERS */
443 443
444static void __init exynos4_timer_resources(void) 444static void __init exynos4_timer_resources(void)
@@ -458,6 +458,8 @@ static void __init exynos4_timer_resources(void)
458 WARN(err, "MCT: can't request IRQ %d (%d)\n", 458 WARN(err, "MCT: can't request IRQ %d (%d)\n",
459 IRQ_MCT_LOCALTIMER, err); 459 IRQ_MCT_LOCALTIMER, err);
460 } 460 }
461
462 local_timer_register(&exynos4_mct_tick_ops);
461#endif /* CONFIG_LOCAL_TIMERS */ 463#endif /* CONFIG_LOCAL_TIMERS */
462} 464}
463 465
diff --git a/arch/arm/mach-highbank/Makefile b/arch/arm/mach-highbank/Makefile
index 986958a5a720..f8437dd238c2 100644
--- a/arch/arm/mach-highbank/Makefile
+++ b/arch/arm/mach-highbank/Makefile
@@ -1,6 +1,5 @@
1obj-y := clock.o highbank.o system.o 1obj-y := clock.o highbank.o system.o
2obj-$(CONFIG_DEBUG_HIGHBANK_UART) += lluart.o 2obj-$(CONFIG_DEBUG_HIGHBANK_UART) += lluart.o
3obj-$(CONFIG_SMP) += platsmp.o 3obj-$(CONFIG_SMP) += platsmp.o
4obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o
5obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o 4obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
6obj-$(CONFIG_PM_SLEEP) += pm.o 5obj-$(CONFIG_PM_SLEEP) += pm.o
diff --git a/arch/arm/mach-highbank/highbank.c b/arch/arm/mach-highbank/highbank.c
index 8394d512a402..bb1684f9b68b 100644
--- a/arch/arm/mach-highbank/highbank.c
+++ b/arch/arm/mach-highbank/highbank.c
@@ -27,6 +27,7 @@
27#include <asm/cacheflush.h> 27#include <asm/cacheflush.h>
28#include <asm/smp_plat.h> 28#include <asm/smp_plat.h>
29#include <asm/smp_scu.h> 29#include <asm/smp_scu.h>
30#include <asm/smp_twd.h>
30#include <asm/hardware/arm_timer.h> 31#include <asm/hardware/arm_timer.h>
31#include <asm/hardware/timer-sp.h> 32#include <asm/hardware/timer-sp.h>
32#include <asm/hardware/gic.h> 33#include <asm/hardware/gic.h>
@@ -111,6 +112,8 @@ static void __init highbank_timer_init(void)
111 112
112 sp804_clocksource_init(timer_base + 0x20, "timer1"); 113 sp804_clocksource_init(timer_base + 0x20, "timer1");
113 sp804_clockevents_init(timer_base, irq, "timer0"); 114 sp804_clockevents_init(timer_base, irq, "timer0");
115
116 twd_local_timer_of_register();
114} 117}
115 118
116static struct sys_timer highbank_timer = { 119static struct sys_timer highbank_timer = {
diff --git a/arch/arm/mach-highbank/localtimer.c b/arch/arm/mach-highbank/localtimer.c
deleted file mode 100644
index 5a00e7945fdf..000000000000
--- a/arch/arm/mach-highbank/localtimer.c
+++ /dev/null
@@ -1,40 +0,0 @@
1/*
2 * Copyright 2010-2011 Calxeda, Inc.
3 * Based on localtimer.c, Copyright (C) 2002 ARM Ltd.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17#include <linux/init.h>
18#include <linux/clockchips.h>
19#include <linux/of.h>
20#include <linux/of_address.h>
21#include <linux/of_irq.h>
22
23#include <asm/smp_twd.h>
24
25/*
26 * Setup the local clock events for a CPU.
27 */
28int __cpuinit local_timer_setup(struct clock_event_device *evt)
29{
30 struct device_node *np;
31
32 np = of_find_compatible_node(NULL, NULL, "arm,smp-twd");
33 if (!twd_base) {
34 twd_base = of_iomap(np, 0);
35 WARN_ON(!twd_base);
36 }
37 evt->irq = irq_of_parse_and_map(np, 0);
38 twd_timer_setup(evt);
39 return 0;
40}
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index 55db9c488f2b..190d57006163 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -71,7 +71,6 @@ obj-$(CONFIG_CPU_V7) += head-v7.o
71AFLAGS_head-v7.o :=-Wa,-march=armv7-a 71AFLAGS_head-v7.o :=-Wa,-march=armv7-a
72obj-$(CONFIG_SMP) += platsmp.o 72obj-$(CONFIG_SMP) += platsmp.o
73obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o 73obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
74obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o
75obj-$(CONFIG_SOC_IMX6Q) += clock-imx6q.o mach-imx6q.o 74obj-$(CONFIG_SOC_IMX6Q) += clock-imx6q.o mach-imx6q.o
76 75
77ifeq ($(CONFIG_PM),y) 76ifeq ($(CONFIG_PM),y)
diff --git a/arch/arm/mach-imx/localtimer.c b/arch/arm/mach-imx/localtimer.c
deleted file mode 100644
index 3a163515d41f..000000000000
--- a/arch/arm/mach-imx/localtimer.c
+++ /dev/null
@@ -1,35 +0,0 @@
1/*
2 * Copyright 2011 Freescale Semiconductor, Inc.
3 * Copyright 2011 Linaro Ltd.
4 *
5 * The code contained herein is licensed under the GNU General Public
6 * License. You may obtain a copy of the GNU General Public License
7 * Version 2 or later at the following locations:
8 *
9 * http://www.opensource.org/licenses/gpl-license.html
10 * http://www.gnu.org/copyleft/gpl.html
11 */
12
13#include <linux/init.h>
14#include <linux/clockchips.h>
15#include <linux/of_address.h>
16#include <linux/of_irq.h>
17#include <asm/smp_twd.h>
18
19/*
20 * Setup the local clock events for a CPU.
21 */
22int __cpuinit local_timer_setup(struct clock_event_device *evt)
23{
24 struct device_node *np;
25
26 np = of_find_compatible_node(NULL, NULL, "arm,smp-twd");
27 if (!twd_base) {
28 twd_base = of_iomap(np, 0);
29 WARN_ON(!twd_base);
30 }
31 evt->irq = irq_of_parse_and_map(np, 0);
32 twd_timer_setup(evt);
33
34 return 0;
35}
diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c
index 6075d4d62dd6..21f54a8ecc85 100644
--- a/arch/arm/mach-imx/mach-imx6q.c
+++ b/arch/arm/mach-imx/mach-imx6q.c
@@ -21,6 +21,7 @@
21#include <linux/of_platform.h> 21#include <linux/of_platform.h>
22#include <linux/phy.h> 22#include <linux/phy.h>
23#include <linux/micrel_phy.h> 23#include <linux/micrel_phy.h>
24#include <asm/smp_twd.h>
24#include <asm/hardware/cache-l2x0.h> 25#include <asm/hardware/cache-l2x0.h>
25#include <asm/hardware/gic.h> 26#include <asm/hardware/gic.h>
26#include <asm/mach/arch.h> 27#include <asm/mach/arch.h>
@@ -120,6 +121,7 @@ static void __init imx6q_init_irq(void)
120static void __init imx6q_timer_init(void) 121static void __init imx6q_timer_init(void)
121{ 122{
122 mx6q_clocks_init(); 123 mx6q_clocks_init();
124 twd_local_timer_of_register();
123} 125}
124 126
125static struct sys_timer imx6q_timer = { 127static struct sys_timer imx6q_timer = {
diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c
index 11d0d8f2656c..75f4be40b3e5 100644
--- a/arch/arm/mach-msm/timer.c
+++ b/arch/arm/mach-msm/timer.c
@@ -127,6 +127,45 @@ static struct clocksource msm_clocksource = {
127 .flags = CLOCK_SOURCE_IS_CONTINUOUS, 127 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
128}; 128};
129 129
130#ifdef CONFIG_LOCAL_TIMERS
131static int __cpuinit msm_local_timer_setup(struct clock_event_device *evt)
132{
133 /* Use existing clock_event for cpu 0 */
134 if (!smp_processor_id())
135 return 0;
136
137 writel_relaxed(0, event_base + TIMER_ENABLE);
138 writel_relaxed(0, event_base + TIMER_CLEAR);
139 writel_relaxed(~0, event_base + TIMER_MATCH_VAL);
140 evt->irq = msm_clockevent.irq;
141 evt->name = "local_timer";
142 evt->features = msm_clockevent.features;
143 evt->rating = msm_clockevent.rating;
144 evt->set_mode = msm_timer_set_mode;
145 evt->set_next_event = msm_timer_set_next_event;
146 evt->shift = msm_clockevent.shift;
147 evt->mult = div_sc(GPT_HZ, NSEC_PER_SEC, evt->shift);
148 evt->max_delta_ns = clockevent_delta2ns(0xf0000000, evt);
149 evt->min_delta_ns = clockevent_delta2ns(4, evt);
150
151 *__this_cpu_ptr(msm_evt.percpu_evt) = evt;
152 clockevents_register_device(evt);
153 enable_percpu_irq(evt->irq, 0);
154 return 0;
155}
156
157static void msm_local_timer_stop(struct clock_event_device *evt)
158{
159 evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt);
160 disable_percpu_irq(evt->irq);
161}
162
163static struct local_timer_ops msm_local_timer_ops __cpuinitdata = {
164 .setup = msm_local_timer_setup,
165 .stop = msm_local_timer_stop,
166};
167#endif /* CONFIG_LOCAL_TIMERS */
168
130static void __init msm_timer_init(void) 169static void __init msm_timer_init(void)
131{ 170{
132 struct clock_event_device *ce = &msm_clockevent; 171 struct clock_event_device *ce = &msm_clockevent;
@@ -173,8 +212,12 @@ static void __init msm_timer_init(void)
173 *__this_cpu_ptr(msm_evt.percpu_evt) = ce; 212 *__this_cpu_ptr(msm_evt.percpu_evt) = ce;
174 res = request_percpu_irq(ce->irq, msm_timer_interrupt, 213 res = request_percpu_irq(ce->irq, msm_timer_interrupt,
175 ce->name, msm_evt.percpu_evt); 214 ce->name, msm_evt.percpu_evt);
176 if (!res) 215 if (!res) {
177 enable_percpu_irq(ce->irq, 0); 216 enable_percpu_irq(ce->irq, 0);
217#ifdef CONFIG_LOCAL_TIMERS
218 local_timer_register(&msm_local_timer_ops);
219#endif
220 }
178 } else { 221 } else {
179 msm_evt.evt = ce; 222 msm_evt.evt = ce;
180 res = request_irq(ce->irq, msm_timer_interrupt, 223 res = request_irq(ce->irq, msm_timer_interrupt,
@@ -191,40 +234,6 @@ err:
191 pr_err("clocksource_register failed\n"); 234 pr_err("clocksource_register failed\n");
192} 235}
193 236
194#ifdef CONFIG_LOCAL_TIMERS
195int __cpuinit local_timer_setup(struct clock_event_device *evt)
196{
197 /* Use existing clock_event for cpu 0 */
198 if (!smp_processor_id())
199 return 0;
200
201 writel_relaxed(0, event_base + TIMER_ENABLE);
202 writel_relaxed(0, event_base + TIMER_CLEAR);
203 writel_relaxed(~0, event_base + TIMER_MATCH_VAL);
204 evt->irq = msm_clockevent.irq;
205 evt->name = "local_timer";
206 evt->features = msm_clockevent.features;
207 evt->rating = msm_clockevent.rating;
208 evt->set_mode = msm_timer_set_mode;
209 evt->set_next_event = msm_timer_set_next_event;
210 evt->shift = msm_clockevent.shift;
211 evt->mult = div_sc(GPT_HZ, NSEC_PER_SEC, evt->shift);
212 evt->max_delta_ns = clockevent_delta2ns(0xf0000000, evt);
213 evt->min_delta_ns = clockevent_delta2ns(4, evt);
214
215 *__this_cpu_ptr(msm_evt.percpu_evt) = evt;
216 clockevents_register_device(evt);
217 enable_percpu_irq(evt->irq, 0);
218 return 0;
219}
220
221void local_timer_stop(struct clock_event_device *evt)
222{
223 evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt);
224 disable_percpu_irq(evt->irq);
225}
226#endif /* CONFIG_LOCAL_TIMERS */
227
228struct sys_timer msm_timer = { 237struct sys_timer msm_timer = {
229 .init = msm_timer_init 238 .init = msm_timer_init
230}; 239};
diff --git a/arch/arm/mach-nomadik/board-nhk8815.c b/arch/arm/mach-nomadik/board-nhk8815.c
index f6f74adbe8c4..58cacafcf662 100644
--- a/arch/arm/mach-nomadik/board-nhk8815.c
+++ b/arch/arm/mach-nomadik/board-nhk8815.c
@@ -27,11 +27,11 @@
27#include <asm/mach/arch.h> 27#include <asm/mach/arch.h>
28#include <asm/mach/irq.h> 28#include <asm/mach/irq.h>
29#include <asm/mach/flash.h> 29#include <asm/mach/flash.h>
30#include <asm/mach/time.h>
30 31
31#include <plat/gpio-nomadik.h> 32#include <plat/gpio-nomadik.h>
32#include <plat/mtu.h> 33#include <plat/mtu.h>
33 34
34#include <mach/setup.h>
35#include <mach/nand.h> 35#include <mach/nand.h>
36#include <mach/fsmc.h> 36#include <mach/fsmc.h>
37 37
@@ -246,10 +246,7 @@ static void __init nomadik_timer_init(void)
246 src_cr |= SRC_CR_INIT_VAL; 246 src_cr |= SRC_CR_INIT_VAL;
247 writel(src_cr, io_p2v(NOMADIK_SRC_BASE)); 247 writel(src_cr, io_p2v(NOMADIK_SRC_BASE));
248 248
249 /* Save global pointer to mtu, used by platform timer code */ 249 nmdk_timer_init(io_p2v(NOMADIK_MTU0_BASE));
250 mtu_base = io_p2v(NOMADIK_MTU0_BASE);
251
252 nmdk_timer_init();
253} 250}
254 251
255static struct sys_timer nomadik_timer = { 252static struct sys_timer nomadik_timer = {
diff --git a/arch/arm/mach-nomadik/include/mach/setup.h b/arch/arm/mach-nomadik/include/mach/setup.h
deleted file mode 100644
index bcaeaf41c053..000000000000
--- a/arch/arm/mach-nomadik/include/mach/setup.h
+++ /dev/null
@@ -1,19 +0,0 @@
1
2/*
3 * These symbols are needed for board-specific files to call their
4 * own cpu-specific files
5 */
6
7#ifndef __ASM_ARCH_SETUP_H
8#define __ASM_ARCH_SETUP_H
9
10#include <asm/mach/time.h>
11#include <linux/init.h>
12
13#ifdef CONFIG_NOMADIK_8815
14
15extern void nmdk_timer_init(void);
16
17#endif /* NOMADIK_8815 */
18
19#endif /* __ASM_ARCH_SETUP_H */
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index 28f150065938..3f850fca8c92 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -25,7 +25,6 @@ obj-$(CONFIG_TWL4030_CORE) += omap_twl.o
25 25
26# SMP support ONLY available for OMAP4 26# SMP support ONLY available for OMAP4
27obj-$(CONFIG_SMP) += omap-smp.o omap-headsmp.o 27obj-$(CONFIG_SMP) += omap-smp.o omap-headsmp.o
28obj-$(CONFIG_LOCAL_TIMERS) += timer-mpu.o
29obj-$(CONFIG_HOTPLUG_CPU) += omap-hotplug.o 28obj-$(CONFIG_HOTPLUG_CPU) += omap-hotplug.o
30obj-$(CONFIG_ARCH_OMAP4) += omap4-common.o omap-wakeupgen.o \ 29obj-$(CONFIG_ARCH_OMAP4) += omap4-common.o omap-wakeupgen.o \
31 sleep44xx.o 30 sleep44xx.o
diff --git a/arch/arm/mach-omap2/timer-mpu.c b/arch/arm/mach-omap2/timer-mpu.c
deleted file mode 100644
index 31c0ac4cd66a..000000000000
--- a/arch/arm/mach-omap2/timer-mpu.c
+++ /dev/null
@@ -1,39 +0,0 @@
1/*
2 * The MPU local timer source file. In OMAP4, both cortex-a9 cores have
3 * own timer in it's MPU domain. These timers will be driving the
4 * linux kernel SMP tick framework when active. These timers are not
5 * part of the wake up domain.
6 *
7 * Copyright (C) 2009 Texas Instruments, Inc.
8 *
9 * Author:
10 * Santosh Shilimkar <santosh.shilimkar@ti.com>
11 *
12 * This file is based on arm realview smp platform file.
13 * Copyright (C) 2002 ARM Ltd.
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License version 2 as
17 * published by the Free Software Foundation.
18 */
19#include <linux/init.h>
20#include <linux/smp.h>
21#include <linux/clockchips.h>
22#include <asm/irq.h>
23#include <asm/smp_twd.h>
24#include <asm/localtimer.h>
25
26/*
27 * Setup the local clock events for a CPU.
28 */
29int __cpuinit local_timer_setup(struct clock_event_device *evt)
30{
31 /* Local timers are not supprted on OMAP4430 ES1.0 */
32 if (omap_rev() == OMAP4430_REV_ES1_0)
33 return -ENXIO;
34
35 evt->irq = OMAP44XX_IRQ_LOCALTIMER;
36 twd_timer_setup(evt);
37 return 0;
38}
39
diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
index 5c9acea95761..c512bac69ec5 100644
--- a/arch/arm/mach-omap2/timer.c
+++ b/arch/arm/mach-omap2/timer.c
@@ -39,7 +39,7 @@
39 39
40#include <asm/mach/time.h> 40#include <asm/mach/time.h>
41#include <plat/dmtimer.h> 41#include <plat/dmtimer.h>
42#include <asm/localtimer.h> 42#include <asm/smp_twd.h>
43#include <asm/sched_clock.h> 43#include <asm/sched_clock.h>
44#include "common.h" 44#include "common.h"
45#include <plat/omap_hwmod.h> 45#include <plat/omap_hwmod.h>
@@ -324,14 +324,26 @@ OMAP_SYS_TIMER(3_secure)
324#endif 324#endif
325 325
326#ifdef CONFIG_ARCH_OMAP4 326#ifdef CONFIG_ARCH_OMAP4
327static void __init omap4_timer_init(void)
328{
329#ifdef CONFIG_LOCAL_TIMERS 327#ifdef CONFIG_LOCAL_TIMERS
330 twd_base = ioremap(OMAP44XX_LOCAL_TWD_BASE, SZ_256); 328static DEFINE_TWD_LOCAL_TIMER(twd_local_timer,
331 BUG_ON(!twd_base); 329 OMAP44XX_LOCAL_TWD_BASE,
330 OMAP44XX_IRQ_LOCALTIMER);
332#endif 331#endif
332
333static void __init omap4_timer_init(void)
334{
333 omap2_gp_clockevent_init(1, OMAP4_CLKEV_SOURCE); 335 omap2_gp_clockevent_init(1, OMAP4_CLKEV_SOURCE);
334 omap2_gp_clocksource_init(2, OMAP4_MPU_SOURCE); 336 omap2_gp_clocksource_init(2, OMAP4_MPU_SOURCE);
337#ifdef CONFIG_LOCAL_TIMERS
338 /* Local timers are not supprted on OMAP4430 ES1.0 */
339 if (omap_rev() != OMAP4430_REV_ES1_0) {
340 int err;
341
342 err = twd_local_timer_register(&twd_local_timer);
343 if (err)
344 pr_err("twd_local_timer_register failed %d\n", err);
345 }
346#endif
335} 347}
336OMAP_SYS_TIMER(4) 348OMAP_SYS_TIMER(4)
337#endif 349#endif
diff --git a/arch/arm/mach-realview/realview_eb.c b/arch/arm/mach-realview/realview_eb.c
index 157e1bc6e83c..baf382c5e776 100644
--- a/arch/arm/mach-realview/realview_eb.c
+++ b/arch/arm/mach-realview/realview_eb.c
@@ -36,7 +36,7 @@
36#include <asm/pgtable.h> 36#include <asm/pgtable.h>
37#include <asm/hardware/gic.h> 37#include <asm/hardware/gic.h>
38#include <asm/hardware/cache-l2x0.h> 38#include <asm/hardware/cache-l2x0.h>
39#include <asm/localtimer.h> 39#include <asm/smp_twd.h>
40 40
41#include <asm/mach/arch.h> 41#include <asm/mach/arch.h>
42#include <asm/mach/map.h> 42#include <asm/mach/map.h>
@@ -383,6 +383,23 @@ static void realview_eb11mp_fixup(void)
383 realview_eb_isp1761_resources[1].end = IRQ_EB11MP_USB; 383 realview_eb_isp1761_resources[1].end = IRQ_EB11MP_USB;
384} 384}
385 385
386#ifdef CONFIG_HAVE_ARM_TWD
387static DEFINE_TWD_LOCAL_TIMER(twd_local_timer,
388 REALVIEW_EB11MP_TWD_BASE,
389 IRQ_LOCALTIMER);
390
391static void __init realview_eb_twd_init(void)
392{
393 if (core_tile_eb11mp() || core_tile_a9mp()) {
394 int err = twd_local_timer_register(&twd_local_timer);
395 if (err)
396 pr_err("twd_local_timer_register failed %d\n", err);
397 }
398}
399#else
400#define realview_eb_twd_init() do { } while(0)
401#endif
402
386static void __init realview_eb_timer_init(void) 403static void __init realview_eb_timer_init(void)
387{ 404{
388 unsigned int timer_irq; 405 unsigned int timer_irq;
@@ -392,15 +409,13 @@ static void __init realview_eb_timer_init(void)
392 timer2_va_base = __io_address(REALVIEW_EB_TIMER2_3_BASE); 409 timer2_va_base = __io_address(REALVIEW_EB_TIMER2_3_BASE);
393 timer3_va_base = __io_address(REALVIEW_EB_TIMER2_3_BASE) + 0x20; 410 timer3_va_base = __io_address(REALVIEW_EB_TIMER2_3_BASE) + 0x20;
394 411
395 if (core_tile_eb11mp() || core_tile_a9mp()) { 412 if (core_tile_eb11mp() || core_tile_a9mp())
396#ifdef CONFIG_LOCAL_TIMERS
397 twd_base = __io_address(REALVIEW_EB11MP_TWD_BASE);
398#endif
399 timer_irq = IRQ_EB11MP_TIMER0_1; 413 timer_irq = IRQ_EB11MP_TIMER0_1;
400 } else 414 else
401 timer_irq = IRQ_EB_TIMER0_1; 415 timer_irq = IRQ_EB_TIMER0_1;
402 416
403 realview_timer_init(timer_irq); 417 realview_timer_init(timer_irq);
418 realview_eb_twd_init();
404} 419}
405 420
406static struct sys_timer realview_eb_timer = { 421static struct sys_timer realview_eb_timer = {
diff --git a/arch/arm/mach-realview/realview_pb11mp.c b/arch/arm/mach-realview/realview_pb11mp.c
index ae7fe54f6eb6..a98c536e3327 100644
--- a/arch/arm/mach-realview/realview_pb11mp.c
+++ b/arch/arm/mach-realview/realview_pb11mp.c
@@ -36,7 +36,7 @@
36#include <asm/pgtable.h> 36#include <asm/pgtable.h>
37#include <asm/hardware/gic.h> 37#include <asm/hardware/gic.h>
38#include <asm/hardware/cache-l2x0.h> 38#include <asm/hardware/cache-l2x0.h>
39#include <asm/localtimer.h> 39#include <asm/smp_twd.h>
40 40
41#include <asm/mach/arch.h> 41#include <asm/mach/arch.h>
42#include <asm/mach/flash.h> 42#include <asm/mach/flash.h>
@@ -290,6 +290,21 @@ static void __init gic_init_irq(void)
290 gic_cascade_irq(1, IRQ_TC11MP_PB_IRQ1); 290 gic_cascade_irq(1, IRQ_TC11MP_PB_IRQ1);
291} 291}
292 292
293#ifdef CONFIG_HAVE_ARM_TWD
294static DEFINE_TWD_LOCAL_TIMER(twd_local_timer,
295 REALVIEW_TC11MP_TWD_BASE,
296 IRQ_LOCALTIMER);
297
298static void __init realview_pb11mp_twd_init(void)
299{
300 int err = twd_local_timer_register(&twd_local_timer);
301 if (err)
302 pr_err("twd_local_timer_register failed %d\n", err);
303}
304#else
305#define realview_pb11mp_twd_init() do {} while(0)
306#endif
307
293static void __init realview_pb11mp_timer_init(void) 308static void __init realview_pb11mp_timer_init(void)
294{ 309{
295 timer0_va_base = __io_address(REALVIEW_PB11MP_TIMER0_1_BASE); 310 timer0_va_base = __io_address(REALVIEW_PB11MP_TIMER0_1_BASE);
@@ -297,10 +312,8 @@ static void __init realview_pb11mp_timer_init(void)
297 timer2_va_base = __io_address(REALVIEW_PB11MP_TIMER2_3_BASE); 312 timer2_va_base = __io_address(REALVIEW_PB11MP_TIMER2_3_BASE);
298 timer3_va_base = __io_address(REALVIEW_PB11MP_TIMER2_3_BASE) + 0x20; 313 timer3_va_base = __io_address(REALVIEW_PB11MP_TIMER2_3_BASE) + 0x20;
299 314
300#ifdef CONFIG_LOCAL_TIMERS
301 twd_base = __io_address(REALVIEW_TC11MP_TWD_BASE);
302#endif
303 realview_timer_init(IRQ_TC11MP_TIMER0_1); 315 realview_timer_init(IRQ_TC11MP_TIMER0_1);
316 realview_pb11mp_twd_init();
304} 317}
305 318
306static struct sys_timer realview_pb11mp_timer = { 319static struct sys_timer realview_pb11mp_timer = {
diff --git a/arch/arm/mach-realview/realview_pbx.c b/arch/arm/mach-realview/realview_pbx.c
index 1cd9956f5875..3f2f605624e9 100644
--- a/arch/arm/mach-realview/realview_pbx.c
+++ b/arch/arm/mach-realview/realview_pbx.c
@@ -298,6 +298,21 @@ static void __init gic_init_irq(void)
298 } 298 }
299} 299}
300 300
301#ifdef CONFIG_HAVE_ARM_TWD
302static DEFINE_TWD_LOCAL_TIMER(twd_local_timer,
303 REALVIEW_PBX_TILE_TWD_BASE,
304 IRQ_LOCALTIMER);
305
306static void __init realview_pbx_twd_init(void)
307{
308 int err = twd_local_timer_register(&twd_local_timer);
309 if (err)
310 pr_err("twd_local_timer_register failed %d\n", err);
311}
312#else
313#define realview_pbx_twd_init() do { } while(0)
314#endif
315
301static void __init realview_pbx_timer_init(void) 316static void __init realview_pbx_timer_init(void)
302{ 317{
303 timer0_va_base = __io_address(REALVIEW_PBX_TIMER0_1_BASE); 318 timer0_va_base = __io_address(REALVIEW_PBX_TIMER0_1_BASE);
@@ -305,11 +320,8 @@ static void __init realview_pbx_timer_init(void)
305 timer2_va_base = __io_address(REALVIEW_PBX_TIMER2_3_BASE); 320 timer2_va_base = __io_address(REALVIEW_PBX_TIMER2_3_BASE);
306 timer3_va_base = __io_address(REALVIEW_PBX_TIMER2_3_BASE) + 0x20; 321 timer3_va_base = __io_address(REALVIEW_PBX_TIMER2_3_BASE) + 0x20;
307 322
308#ifdef CONFIG_LOCAL_TIMERS
309 if (core_tile_pbx11mp() || core_tile_pbxa9mp())
310 twd_base = __io_address(REALVIEW_PBX_TILE_TWD_BASE);
311#endif
312 realview_timer_init(IRQ_PBX_TIMER0_1); 323 realview_timer_init(IRQ_PBX_TIMER0_1);
324 realview_pbx_twd_init();
313} 325}
314 326
315static struct sys_timer realview_pbx_timer = { 327static struct sys_timer realview_pbx_timer = {
diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile
index 7ad6954c46cd..e7c2590b75d9 100644
--- a/arch/arm/mach-shmobile/Makefile
+++ b/arch/arm/mach-shmobile/Makefile
@@ -16,7 +16,6 @@ obj-$(CONFIG_ARCH_R8A7779) += setup-r8a7779.o clock-r8a7779.o intc-r8a7779.o
16# SMP objects 16# SMP objects
17smp-y := platsmp.o headsmp.o 17smp-y := platsmp.o headsmp.o
18smp-$(CONFIG_HOTPLUG_CPU) += hotplug.o 18smp-$(CONFIG_HOTPLUG_CPU) += hotplug.o
19smp-$(CONFIG_LOCAL_TIMERS) += localtimer.o
20smp-$(CONFIG_ARCH_SH73A0) += smp-sh73a0.o 19smp-$(CONFIG_ARCH_SH73A0) += smp-sh73a0.o
21smp-$(CONFIG_ARCH_R8A7779) += smp-r8a7779.o 20smp-$(CONFIG_ARCH_R8A7779) += smp-r8a7779.o
22 21
diff --git a/arch/arm/mach-shmobile/board-ag5evm.c b/arch/arm/mach-shmobile/board-ag5evm.c
index 12c431f3443f..f50d7c8b1221 100644
--- a/arch/arm/mach-shmobile/board-ag5evm.c
+++ b/arch/arm/mach-shmobile/board-ag5evm.c
@@ -47,8 +47,6 @@
47#include <mach/common.h> 47#include <mach/common.h>
48#include <asm/mach-types.h> 48#include <asm/mach-types.h>
49#include <asm/mach/arch.h> 49#include <asm/mach/arch.h>
50#include <asm/mach/map.h>
51#include <asm/mach/time.h>
52#include <asm/hardware/gic.h> 50#include <asm/hardware/gic.h>
53#include <asm/hardware/cache-l2x0.h> 51#include <asm/hardware/cache-l2x0.h>
54#include <asm/traps.h> 52#include <asm/traps.h>
@@ -477,27 +475,6 @@ static struct platform_device *ag5evm_devices[] __initdata = {
477 &sdhi1_device, 475 &sdhi1_device,
478}; 476};
479 477
480static struct map_desc ag5evm_io_desc[] __initdata = {
481 /* create a 1:1 entity map for 0xe6xxxxxx
482 * used by CPGA, INTC and PFC.
483 */
484 {
485 .virtual = 0xe6000000,
486 .pfn = __phys_to_pfn(0xe6000000),
487 .length = 256 << 20,
488 .type = MT_DEVICE_NONSHARED
489 },
490};
491
492static void __init ag5evm_map_io(void)
493{
494 iotable_init(ag5evm_io_desc, ARRAY_SIZE(ag5evm_io_desc));
495
496 /* setup early devices and console here as well */
497 sh73a0_add_early_devices();
498 shmobile_setup_console();
499}
500
501static void __init ag5evm_init(void) 478static void __init ag5evm_init(void)
502{ 479{
503 sh73a0_pinmux_init(); 480 sh73a0_pinmux_init();
@@ -613,22 +590,12 @@ static void __init ag5evm_init(void)
613 platform_add_devices(ag5evm_devices, ARRAY_SIZE(ag5evm_devices)); 590 platform_add_devices(ag5evm_devices, ARRAY_SIZE(ag5evm_devices));
614} 591}
615 592
616static void __init ag5evm_timer_init(void)
617{
618 sh73a0_clock_init();
619 shmobile_timer.init();
620 return;
621}
622
623struct sys_timer ag5evm_timer = {
624 .init = ag5evm_timer_init,
625};
626
627MACHINE_START(AG5EVM, "ag5evm") 593MACHINE_START(AG5EVM, "ag5evm")
628 .map_io = ag5evm_map_io, 594 .map_io = sh73a0_map_io,
595 .init_early = sh73a0_add_early_devices,
629 .nr_irqs = NR_IRQS_LEGACY, 596 .nr_irqs = NR_IRQS_LEGACY,
630 .init_irq = sh73a0_init_irq, 597 .init_irq = sh73a0_init_irq,
631 .handle_irq = gic_handle_irq, 598 .handle_irq = gic_handle_irq,
632 .init_machine = ag5evm_init, 599 .init_machine = ag5evm_init,
633 .timer = &ag5evm_timer, 600 .timer = &shmobile_timer,
634MACHINE_END 601MACHINE_END
diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c
index f90ba5b850a3..262f8def5577 100644
--- a/arch/arm/mach-shmobile/board-ap4evb.c
+++ b/arch/arm/mach-shmobile/board-ap4evb.c
@@ -61,8 +61,6 @@
61 61
62#include <asm/mach-types.h> 62#include <asm/mach-types.h>
63#include <asm/mach/arch.h> 63#include <asm/mach/arch.h>
64#include <asm/mach/map.h>
65#include <asm/mach/time.h>
66#include <asm/setup.h> 64#include <asm/setup.h>
67 65
68/* 66/*
@@ -1188,27 +1186,6 @@ static struct i2c_board_info i2c1_devices[] = {
1188 }, 1186 },
1189}; 1187};
1190 1188
1191static struct map_desc ap4evb_io_desc[] __initdata = {
1192 /* create a 1:1 entity map for 0xe6xxxxxx
1193 * used by CPGA, INTC and PFC.
1194 */
1195 {
1196 .virtual = 0xe6000000,
1197 .pfn = __phys_to_pfn(0xe6000000),
1198 .length = 256 << 20,
1199 .type = MT_DEVICE_NONSHARED
1200 },
1201};
1202
1203static void __init ap4evb_map_io(void)
1204{
1205 iotable_init(ap4evb_io_desc, ARRAY_SIZE(ap4evb_io_desc));
1206
1207 /* setup early devices and console here as well */
1208 sh7372_add_early_devices();
1209 shmobile_setup_console();
1210}
1211
1212#define GPIO_PORT9CR 0xE6051009 1189#define GPIO_PORT9CR 0xE6051009
1213#define GPIO_PORT10CR 0xE605100A 1190#define GPIO_PORT10CR 0xE605100A
1214#define USCCR1 0xE6058144 1191#define USCCR1 0xE6058144
@@ -1217,6 +1194,9 @@ static void __init ap4evb_init(void)
1217 u32 srcr4; 1194 u32 srcr4;
1218 struct clk *clk; 1195 struct clk *clk;
1219 1196
1197 /* External clock source */
1198 clk_set_rate(&sh7372_dv_clki_clk, 27000000);
1199
1220 sh7372_pinmux_init(); 1200 sh7372_pinmux_init();
1221 1201
1222 /* enable SCIFA0 */ 1202 /* enable SCIFA0 */
@@ -1453,23 +1433,11 @@ static void __init ap4evb_init(void)
1453 pm_clk_add(&lcdc1_device.dev, "hdmi"); 1433 pm_clk_add(&lcdc1_device.dev, "hdmi");
1454} 1434}
1455 1435
1456static void __init ap4evb_timer_init(void)
1457{
1458 sh7372_clock_init();
1459 shmobile_timer.init();
1460
1461 /* External clock source */
1462 clk_set_rate(&sh7372_dv_clki_clk, 27000000);
1463}
1464
1465static struct sys_timer ap4evb_timer = {
1466 .init = ap4evb_timer_init,
1467};
1468
1469MACHINE_START(AP4EVB, "ap4evb") 1436MACHINE_START(AP4EVB, "ap4evb")
1470 .map_io = ap4evb_map_io, 1437 .map_io = sh7372_map_io,
1438 .init_early = sh7372_add_early_devices,
1471 .init_irq = sh7372_init_irq, 1439 .init_irq = sh7372_init_irq,
1472 .handle_irq = shmobile_handle_irq_intc, 1440 .handle_irq = shmobile_handle_irq_intc,
1473 .init_machine = ap4evb_init, 1441 .init_machine = ap4evb_init,
1474 .timer = &ap4evb_timer, 1442 .timer = &shmobile_timer,
1475MACHINE_END 1443MACHINE_END
diff --git a/arch/arm/mach-shmobile/board-bonito.c b/arch/arm/mach-shmobile/board-bonito.c
index c79baa9ef61b..8b2124da245d 100644
--- a/arch/arm/mach-shmobile/board-bonito.c
+++ b/arch/arm/mach-shmobile/board-bonito.c
@@ -328,28 +328,6 @@ static struct platform_device *bonito_base_devices[] __initdata = {
328 * map I/O 328 * map I/O
329 */ 329 */
330static struct map_desc bonito_io_desc[] __initdata = { 330static struct map_desc bonito_io_desc[] __initdata = {
331 /*
332 * for CPGA/INTC/PFC
333 * 0xe6000000-0xefffffff -> 0xe6000000-0xefffffff
334 */
335 {
336 .virtual = 0xe6000000,
337 .pfn = __phys_to_pfn(0xe6000000),
338 .length = 160 << 20,
339 .type = MT_DEVICE_NONSHARED
340 },
341#ifdef CONFIG_CACHE_L2X0
342 /*
343 * for l2x0_init()
344 * 0xf0100000-0xf0101000 -> 0xf0002000-0xf0003000
345 */
346 {
347 .virtual = 0xf0002000,
348 .pfn = __phys_to_pfn(0xf0100000),
349 .length = PAGE_SIZE,
350 .type = MT_DEVICE_NONSHARED
351 },
352#endif
353 /* 331 /*
354 * for FPGA (0x1800000-0x19ffffff) 332 * for FPGA (0x1800000-0x19ffffff)
355 * 0x18000000-0x18002000 -> 0xf0003000-0xf0005000 333 * 0x18000000-0x18002000 -> 0xf0003000-0xf0005000
@@ -364,11 +342,8 @@ static struct map_desc bonito_io_desc[] __initdata = {
364 342
365static void __init bonito_map_io(void) 343static void __init bonito_map_io(void)
366{ 344{
345 r8a7740_map_io();
367 iotable_init(bonito_io_desc, ARRAY_SIZE(bonito_io_desc)); 346 iotable_init(bonito_io_desc, ARRAY_SIZE(bonito_io_desc));
368
369 /* setup early devices and console here as well */
370 r8a7740_add_early_devices();
371 shmobile_setup_console();
372} 347}
373 348
374/* 349/*
@@ -492,7 +467,7 @@ static void __init bonito_init(void)
492 } 467 }
493} 468}
494 469
495static void __init bonito_timer_init(void) 470static void __init bonito_earlytimer_init(void)
496{ 471{
497 u16 val; 472 u16 val;
498 u8 md_ck = 0; 473 u8 md_ck = 0;
@@ -507,17 +482,22 @@ static void __init bonito_timer_init(void)
507 md_ck |= MD_CK0; 482 md_ck |= MD_CK0;
508 483
509 r8a7740_clock_init(md_ck); 484 r8a7740_clock_init(md_ck);
510 shmobile_timer.init(); 485 shmobile_earlytimer_init();
511} 486}
512 487
513struct sys_timer bonito_timer = { 488void __init bonito_add_early_devices(void)
514 .init = bonito_timer_init, 489{
515}; 490 r8a7740_add_early_devices();
491
492 /* override timer setup with board-specific code */
493 shmobile_timer.init = bonito_earlytimer_init;
494}
516 495
517MACHINE_START(BONITO, "bonito") 496MACHINE_START(BONITO, "bonito")
518 .map_io = bonito_map_io, 497 .map_io = bonito_map_io,
498 .init_early = bonito_add_early_devices,
519 .init_irq = r8a7740_init_irq, 499 .init_irq = r8a7740_init_irq,
520 .handle_irq = shmobile_handle_irq_intc, 500 .handle_irq = shmobile_handle_irq_intc,
521 .init_machine = bonito_init, 501 .init_machine = bonito_init,
522 .timer = &bonito_timer, 502 .timer = &shmobile_timer,
523MACHINE_END 503MACHINE_END
diff --git a/arch/arm/mach-shmobile/board-g3evm.c b/arch/arm/mach-shmobile/board-g3evm.c
index 72d557281b1f..b627e89037f5 100644
--- a/arch/arm/mach-shmobile/board-g3evm.c
+++ b/arch/arm/mach-shmobile/board-g3evm.c
@@ -37,8 +37,6 @@
37#include <mach/common.h> 37#include <mach/common.h>
38#include <asm/mach-types.h> 38#include <asm/mach-types.h>
39#include <asm/mach/arch.h> 39#include <asm/mach/arch.h>
40#include <asm/mach/map.h>
41#include <asm/mach/time.h>
42 40
43/* 41/*
44 * IrDA 42 * IrDA
@@ -246,27 +244,6 @@ static struct platform_device *g3evm_devices[] __initdata = {
246 &irda_device, 244 &irda_device,
247}; 245};
248 246
249static struct map_desc g3evm_io_desc[] __initdata = {
250 /* create a 1:1 entity map for 0xe6xxxxxx
251 * used by CPGA, INTC and PFC.
252 */
253 {
254 .virtual = 0xe6000000,
255 .pfn = __phys_to_pfn(0xe6000000),
256 .length = 256 << 20,
257 .type = MT_DEVICE_NONSHARED
258 },
259};
260
261static void __init g3evm_map_io(void)
262{
263 iotable_init(g3evm_io_desc, ARRAY_SIZE(g3evm_io_desc));
264
265 /* setup early devices and console here as well */
266 sh7367_add_early_devices();
267 shmobile_setup_console();
268}
269
270static void __init g3evm_init(void) 247static void __init g3evm_init(void)
271{ 248{
272 sh7367_pinmux_init(); 249 sh7367_pinmux_init();
@@ -354,20 +331,11 @@ static void __init g3evm_init(void)
354 platform_add_devices(g3evm_devices, ARRAY_SIZE(g3evm_devices)); 331 platform_add_devices(g3evm_devices, ARRAY_SIZE(g3evm_devices));
355} 332}
356 333
357static void __init g3evm_timer_init(void)
358{
359 sh7367_clock_init();
360 shmobile_timer.init();
361}
362
363static struct sys_timer g3evm_timer = {
364 .init = g3evm_timer_init,
365};
366
367MACHINE_START(G3EVM, "g3evm") 334MACHINE_START(G3EVM, "g3evm")
368 .map_io = g3evm_map_io, 335 .map_io = sh7367_map_io,
336 .init_early = sh7367_add_early_devices,
369 .init_irq = sh7367_init_irq, 337 .init_irq = sh7367_init_irq,
370 .handle_irq = shmobile_handle_irq_intc, 338 .handle_irq = shmobile_handle_irq_intc,
371 .init_machine = g3evm_init, 339 .init_machine = g3evm_init,
372 .timer = &g3evm_timer, 340 .timer = &shmobile_timer,
373MACHINE_END 341MACHINE_END
diff --git a/arch/arm/mach-shmobile/board-g4evm.c b/arch/arm/mach-shmobile/board-g4evm.c
index 2220b885cff5..46d757d2759d 100644
--- a/arch/arm/mach-shmobile/board-g4evm.c
+++ b/arch/arm/mach-shmobile/board-g4evm.c
@@ -38,8 +38,6 @@
38#include <mach/common.h> 38#include <mach/common.h>
39#include <asm/mach-types.h> 39#include <asm/mach-types.h>
40#include <asm/mach/arch.h> 40#include <asm/mach/arch.h>
41#include <asm/mach/map.h>
42#include <asm/mach/time.h>
43 41
44/* 42/*
45 * SDHI 43 * SDHI
@@ -260,27 +258,6 @@ static struct platform_device *g4evm_devices[] __initdata = {
260 &sdhi1_device, 258 &sdhi1_device,
261}; 259};
262 260
263static struct map_desc g4evm_io_desc[] __initdata = {
264 /* create a 1:1 entity map for 0xe6xxxxxx
265 * used by CPGA, INTC and PFC.
266 */
267 {
268 .virtual = 0xe6000000,
269 .pfn = __phys_to_pfn(0xe6000000),
270 .length = 256 << 20,
271 .type = MT_DEVICE_NONSHARED
272 },
273};
274
275static void __init g4evm_map_io(void)
276{
277 iotable_init(g4evm_io_desc, ARRAY_SIZE(g4evm_io_desc));
278
279 /* setup early devices and console here as well */
280 sh7377_add_early_devices();
281 shmobile_setup_console();
282}
283
284#define GPIO_SDHID0_D0 0xe60520fc 261#define GPIO_SDHID0_D0 0xe60520fc
285#define GPIO_SDHID0_D1 0xe60520fd 262#define GPIO_SDHID0_D1 0xe60520fd
286#define GPIO_SDHID0_D2 0xe60520fe 263#define GPIO_SDHID0_D2 0xe60520fe
@@ -397,20 +374,11 @@ static void __init g4evm_init(void)
397 platform_add_devices(g4evm_devices, ARRAY_SIZE(g4evm_devices)); 374 platform_add_devices(g4evm_devices, ARRAY_SIZE(g4evm_devices));
398} 375}
399 376
400static void __init g4evm_timer_init(void)
401{
402 sh7377_clock_init();
403 shmobile_timer.init();
404}
405
406static struct sys_timer g4evm_timer = {
407 .init = g4evm_timer_init,
408};
409
410MACHINE_START(G4EVM, "g4evm") 377MACHINE_START(G4EVM, "g4evm")
411 .map_io = g4evm_map_io, 378 .map_io = sh7377_map_io,
379 .init_early = sh7377_add_early_devices,
412 .init_irq = sh7377_init_irq, 380 .init_irq = sh7377_init_irq,
413 .handle_irq = shmobile_handle_irq_intc, 381 .handle_irq = shmobile_handle_irq_intc,
414 .init_machine = g4evm_init, 382 .init_machine = g4evm_init,
415 .timer = &g4evm_timer, 383 .timer = &shmobile_timer,
416MACHINE_END 384MACHINE_END
diff --git a/arch/arm/mach-shmobile/board-kota2.c b/arch/arm/mach-shmobile/board-kota2.c
index c8e7ca23fc06..61c067294660 100644
--- a/arch/arm/mach-shmobile/board-kota2.c
+++ b/arch/arm/mach-shmobile/board-kota2.c
@@ -43,7 +43,6 @@
43#include <mach/common.h> 43#include <mach/common.h>
44#include <asm/mach-types.h> 44#include <asm/mach-types.h>
45#include <asm/mach/arch.h> 45#include <asm/mach/arch.h>
46#include <asm/mach/map.h>
47#include <asm/mach/time.h> 46#include <asm/mach/time.h>
48#include <asm/hardware/gic.h> 47#include <asm/hardware/gic.h>
49#include <asm/hardware/cache-l2x0.h> 48#include <asm/hardware/cache-l2x0.h>
@@ -409,27 +408,6 @@ static struct platform_device *kota2_devices[] __initdata = {
409 &sdhi1_device, 408 &sdhi1_device,
410}; 409};
411 410
412static struct map_desc kota2_io_desc[] __initdata = {
413 /* create a 1:1 entity map for 0xe6xxxxxx
414 * used by CPGA, INTC and PFC.
415 */
416 {
417 .virtual = 0xe6000000,
418 .pfn = __phys_to_pfn(0xe6000000),
419 .length = 256 << 20,
420 .type = MT_DEVICE_NONSHARED
421 },
422};
423
424static void __init kota2_map_io(void)
425{
426 iotable_init(kota2_io_desc, ARRAY_SIZE(kota2_io_desc));
427
428 /* setup early devices and console here as well */
429 sh73a0_add_early_devices();
430 shmobile_setup_console();
431}
432
433static void __init kota2_init(void) 411static void __init kota2_init(void)
434{ 412{
435 sh73a0_pinmux_init(); 413 sh73a0_pinmux_init();
@@ -535,22 +513,12 @@ static void __init kota2_init(void)
535 platform_add_devices(kota2_devices, ARRAY_SIZE(kota2_devices)); 513 platform_add_devices(kota2_devices, ARRAY_SIZE(kota2_devices));
536} 514}
537 515
538static void __init kota2_timer_init(void)
539{
540 sh73a0_clock_init();
541 shmobile_timer.init();
542 return;
543}
544
545struct sys_timer kota2_timer = {
546 .init = kota2_timer_init,
547};
548
549MACHINE_START(KOTA2, "kota2") 516MACHINE_START(KOTA2, "kota2")
550 .map_io = kota2_map_io, 517 .map_io = sh73a0_map_io,
518 .init_early = sh73a0_add_early_devices,
551 .nr_irqs = NR_IRQS_LEGACY, 519 .nr_irqs = NR_IRQS_LEGACY,
552 .init_irq = sh73a0_init_irq, 520 .init_irq = sh73a0_init_irq,
553 .handle_irq = gic_handle_irq, 521 .handle_irq = gic_handle_irq,
554 .init_machine = kota2_init, 522 .init_machine = kota2_init,
555 .timer = &kota2_timer, 523 .timer = &shmobile_timer,
556MACHINE_END 524MACHINE_END
diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c
index 865d56d96299..bd4253ba05b6 100644
--- a/arch/arm/mach-shmobile/board-mackerel.c
+++ b/arch/arm/mach-shmobile/board-mackerel.c
@@ -57,8 +57,6 @@
57#include <mach/sh7372.h> 57#include <mach/sh7372.h>
58 58
59#include <asm/mach/arch.h> 59#include <asm/mach/arch.h>
60#include <asm/mach/time.h>
61#include <asm/mach/map.h>
62#include <asm/mach-types.h> 60#include <asm/mach-types.h>
63 61
64/* 62/*
@@ -1329,29 +1327,13 @@ static struct i2c_board_info i2c1_devices[] = {
1329 }, 1327 },
1330}; 1328};
1331 1329
1332static struct map_desc mackerel_io_desc[] __initdata = {
1333 /* create a 1:1 entity map for 0xe6xxxxxx
1334 * used by CPGA, INTC and PFC.
1335 */
1336 {
1337 .virtual = 0xe6000000,
1338 .pfn = __phys_to_pfn(0xe6000000),
1339 .length = 256 << 20,
1340 .type = MT_DEVICE_NONSHARED
1341 },
1342};
1343
1344static void __init mackerel_map_io(void) 1330static void __init mackerel_map_io(void)
1345{ 1331{
1346 iotable_init(mackerel_io_desc, ARRAY_SIZE(mackerel_io_desc)); 1332 sh7372_map_io();
1347 /* DMA memory at 0xff200000 - 0xffdfffff. The default 2MB size isn't 1333 /* DMA memory at 0xff200000 - 0xffdfffff. The default 2MB size isn't
1348 * enough to allocate the frame buffer memory. 1334 * enough to allocate the frame buffer memory.
1349 */ 1335 */
1350 init_consistent_dma_size(12 << 20); 1336 init_consistent_dma_size(12 << 20);
1351
1352 /* setup early devices and console here as well */
1353 sh7372_add_early_devices();
1354 shmobile_setup_console();
1355} 1337}
1356 1338
1357#define GPIO_PORT9CR 0xE6051009 1339#define GPIO_PORT9CR 0xE6051009
@@ -1366,6 +1348,9 @@ static void __init mackerel_init(void)
1366 struct clk *clk; 1348 struct clk *clk;
1367 int ret; 1349 int ret;
1368 1350
1351 /* External clock source */
1352 clk_set_rate(&sh7372_dv_clki_clk, 27000000);
1353
1369 sh7372_pinmux_init(); 1354 sh7372_pinmux_init();
1370 1355
1371 /* enable SCIFA0 */ 1356 /* enable SCIFA0 */
@@ -1569,23 +1554,11 @@ static void __init mackerel_init(void)
1569 pm_clk_add(&hdmi_lcdc_device.dev, "hdmi"); 1554 pm_clk_add(&hdmi_lcdc_device.dev, "hdmi");
1570} 1555}
1571 1556
1572static void __init mackerel_timer_init(void)
1573{
1574 sh7372_clock_init();
1575 shmobile_timer.init();
1576
1577 /* External clock source */
1578 clk_set_rate(&sh7372_dv_clki_clk, 27000000);
1579}
1580
1581static struct sys_timer mackerel_timer = {
1582 .init = mackerel_timer_init,
1583};
1584
1585MACHINE_START(MACKEREL, "mackerel") 1557MACHINE_START(MACKEREL, "mackerel")
1586 .map_io = mackerel_map_io, 1558 .map_io = mackerel_map_io,
1559 .init_early = sh7372_add_early_devices,
1587 .init_irq = sh7372_init_irq, 1560 .init_irq = sh7372_init_irq,
1588 .handle_irq = shmobile_handle_irq_intc, 1561 .handle_irq = shmobile_handle_irq_intc,
1589 .init_machine = mackerel_init, 1562 .init_machine = mackerel_init,
1590 .timer = &mackerel_timer, 1563 .timer = &shmobile_timer,
1591MACHINE_END 1564MACHINE_END
diff --git a/arch/arm/mach-shmobile/board-marzen.c b/arch/arm/mach-shmobile/board-marzen.c
index f0e02c0ce99f..cbd5e4cd06d2 100644
--- a/arch/arm/mach-shmobile/board-marzen.c
+++ b/arch/arm/mach-shmobile/board-marzen.c
@@ -33,8 +33,6 @@
33#include <mach/common.h> 33#include <mach/common.h>
34#include <asm/mach-types.h> 34#include <asm/mach-types.h>
35#include <asm/mach/arch.h> 35#include <asm/mach/arch.h>
36#include <asm/mach/map.h>
37#include <asm/mach/time.h>
38#include <asm/hardware/gic.h> 36#include <asm/hardware/gic.h>
39#include <asm/traps.h> 37#include <asm/traps.h>
40 38
@@ -72,49 +70,6 @@ static struct platform_device *marzen_devices[] __initdata = {
72 &eth_device, 70 &eth_device,
73}; 71};
74 72
75static struct map_desc marzen_io_desc[] __initdata = {
76 /* 2M entity map for 0xf0000000 (MPCORE) */
77 {
78 .virtual = 0xf0000000,
79 .pfn = __phys_to_pfn(0xf0000000),
80 .length = SZ_2M,
81 .type = MT_DEVICE_NONSHARED
82 },
83 /* 16M entity map for 0xfexxxxxx (DMAC-S/HPBREG/INTC2/LRAM/DBSC) */
84 {
85 .virtual = 0xfe000000,
86 .pfn = __phys_to_pfn(0xfe000000),
87 .length = SZ_16M,
88 .type = MT_DEVICE_NONSHARED
89 },
90};
91
92static void __init marzen_map_io(void)
93{
94 iotable_init(marzen_io_desc, ARRAY_SIZE(marzen_io_desc));
95}
96
97static void __init marzen_init_early(void)
98{
99 r8a7779_add_early_devices();
100
101 /* Early serial console setup is not included here due to
102 * memory map collisions. The SCIF serial ports in r8a7779
103 * are difficult to entity map 1:1 due to collision with the
104 * virtual memory range used by the coherent DMA code on ARM.
105 *
106 * Anyone wanting to debug early can remove UPF_IOREMAP from
107 * the sh-sci serial console platform data, adjust mapbase
108 * to a static M:N virt:phys mapping that needs to be added to
109 * the mappings passed with iotable_init() above.
110 *
111 * Then add a call to shmobile_setup_console() from this function.
112 *
113 * As a final step pass earlyprint=sh-sci.2,115200 on the kernel
114 * command line.
115 */
116}
117
118static void __init marzen_init(void) 73static void __init marzen_init(void)
119{ 74{
120 r8a7779_pinmux_init(); 75 r8a7779_pinmux_init();
@@ -135,23 +90,12 @@ static void __init marzen_init(void)
135 platform_add_devices(marzen_devices, ARRAY_SIZE(marzen_devices)); 90 platform_add_devices(marzen_devices, ARRAY_SIZE(marzen_devices));
136} 91}
137 92
138static void __init marzen_timer_init(void)
139{
140 r8a7779_clock_init();
141 shmobile_timer.init();
142 return;
143}
144
145struct sys_timer marzen_timer = {
146 .init = marzen_timer_init,
147};
148
149MACHINE_START(MARZEN, "marzen") 93MACHINE_START(MARZEN, "marzen")
150 .map_io = marzen_map_io, 94 .map_io = r8a7779_map_io,
151 .init_early = marzen_init_early, 95 .init_early = r8a7779_add_early_devices,
152 .nr_irqs = NR_IRQS_LEGACY, 96 .nr_irqs = NR_IRQS_LEGACY,
153 .init_irq = r8a7779_init_irq, 97 .init_irq = r8a7779_init_irq,
154 .handle_irq = gic_handle_irq, 98 .handle_irq = gic_handle_irq,
155 .init_machine = marzen_init, 99 .init_machine = marzen_init,
156 .timer = &marzen_timer, 100 .timer = &shmobile_timer,
157MACHINE_END 101MACHINE_END
diff --git a/arch/arm/mach-shmobile/clock-r8a7740.c b/arch/arm/mach-shmobile/clock-r8a7740.c
index 3b35b9afc001..99c4d743a99c 100644
--- a/arch/arm/mach-shmobile/clock-r8a7740.c
+++ b/arch/arm/mach-shmobile/clock-r8a7740.c
@@ -93,7 +93,7 @@ static unsigned long div_recalc(struct clk *clk)
93 return clk->parent->rate / (int)(clk->priv); 93 return clk->parent->rate / (int)(clk->priv);
94} 94}
95 95
96static struct clk_ops div_clk_ops = { 96static struct sh_clk_ops div_clk_ops = {
97 .recalc = div_recalc, 97 .recalc = div_recalc,
98}; 98};
99 99
@@ -125,7 +125,7 @@ static struct clk extal2_div2_clk = {
125 .parent = &extal2_clk, 125 .parent = &extal2_clk,
126}; 126};
127 127
128static struct clk_ops followparent_clk_ops = { 128static struct sh_clk_ops followparent_clk_ops = {
129 .recalc = followparent_recalc, 129 .recalc = followparent_recalc,
130}; 130};
131 131
@@ -156,7 +156,7 @@ static unsigned long pllc01_recalc(struct clk *clk)
156 return clk->parent->rate * mult; 156 return clk->parent->rate * mult;
157} 157}
158 158
159static struct clk_ops pllc01_clk_ops = { 159static struct sh_clk_ops pllc01_clk_ops = {
160 .recalc = pllc01_recalc, 160 .recalc = pllc01_recalc,
161}; 161};
162 162
@@ -376,7 +376,7 @@ void __init r8a7740_clock_init(u8 md_ck)
376 clkdev_add_table(lookups, ARRAY_SIZE(lookups)); 376 clkdev_add_table(lookups, ARRAY_SIZE(lookups));
377 377
378 if (!ret) 378 if (!ret)
379 clk_init(); 379 shmobile_clk_init();
380 else 380 else
381 panic("failed to setup r8a7740 clocks\n"); 381 panic("failed to setup r8a7740 clocks\n");
382} 382}
diff --git a/arch/arm/mach-shmobile/clock-r8a7779.c b/arch/arm/mach-shmobile/clock-r8a7779.c
index b4b0e8cd096d..7d6e9fe47b56 100644
--- a/arch/arm/mach-shmobile/clock-r8a7779.c
+++ b/arch/arm/mach-shmobile/clock-r8a7779.c
@@ -107,7 +107,7 @@ static unsigned long mul4_recalc(struct clk *clk)
107 return clk->parent->rate * 4; 107 return clk->parent->rate * 4;
108} 108}
109 109
110static struct clk_ops mul4_clk_ops = { 110static struct sh_clk_ops mul4_clk_ops = {
111 .recalc = mul4_recalc, 111 .recalc = mul4_recalc,
112}; 112};
113 113
@@ -170,7 +170,7 @@ void __init r8a7779_clock_init(void)
170 clkdev_add_table(lookups, ARRAY_SIZE(lookups)); 170 clkdev_add_table(lookups, ARRAY_SIZE(lookups));
171 171
172 if (!ret) 172 if (!ret)
173 clk_init(); 173 shmobile_clk_init();
174 else 174 else
175 panic("failed to setup r8a7779 clocks\n"); 175 panic("failed to setup r8a7779 clocks\n");
176} 176}
diff --git a/arch/arm/mach-shmobile/clock-sh7367.c b/arch/arm/mach-shmobile/clock-sh7367.c
index 5218c34a9cc6..006e7b5d304c 100644
--- a/arch/arm/mach-shmobile/clock-sh7367.c
+++ b/arch/arm/mach-shmobile/clock-sh7367.c
@@ -74,7 +74,7 @@ static unsigned long div2_recalc(struct clk *clk)
74 return clk->parent->rate / 2; 74 return clk->parent->rate / 2;
75} 75}
76 76
77static struct clk_ops div2_clk_ops = { 77static struct sh_clk_ops div2_clk_ops = {
78 .recalc = div2_recalc, 78 .recalc = div2_recalc,
79}; 79};
80 80
@@ -101,7 +101,7 @@ static unsigned long pllc1_recalc(struct clk *clk)
101 return clk->parent->rate * mult; 101 return clk->parent->rate * mult;
102} 102}
103 103
104static struct clk_ops pllc1_clk_ops = { 104static struct sh_clk_ops pllc1_clk_ops = {
105 .recalc = pllc1_recalc, 105 .recalc = pllc1_recalc,
106}; 106};
107 107
@@ -128,7 +128,7 @@ static unsigned long pllc2_recalc(struct clk *clk)
128 return clk->parent->rate * mult; 128 return clk->parent->rate * mult;
129} 129}
130 130
131static struct clk_ops pllc2_clk_ops = { 131static struct sh_clk_ops pllc2_clk_ops = {
132 .recalc = pllc2_recalc, 132 .recalc = pllc2_recalc,
133}; 133};
134 134
@@ -349,7 +349,7 @@ void __init sh7367_clock_init(void)
349 clkdev_add_table(lookups, ARRAY_SIZE(lookups)); 349 clkdev_add_table(lookups, ARRAY_SIZE(lookups));
350 350
351 if (!ret) 351 if (!ret)
352 clk_init(); 352 shmobile_clk_init();
353 else 353 else
354 panic("failed to setup sh7367 clocks\n"); 354 panic("failed to setup sh7367 clocks\n");
355} 355}
diff --git a/arch/arm/mach-shmobile/clock-sh7372.c b/arch/arm/mach-shmobile/clock-sh7372.c
index 293456d8dcfd..de243e3c8392 100644
--- a/arch/arm/mach-shmobile/clock-sh7372.c
+++ b/arch/arm/mach-shmobile/clock-sh7372.c
@@ -89,7 +89,7 @@ static unsigned long div2_recalc(struct clk *clk)
89 return clk->parent->rate / 2; 89 return clk->parent->rate / 2;
90} 90}
91 91
92static struct clk_ops div2_clk_ops = { 92static struct sh_clk_ops div2_clk_ops = {
93 .recalc = div2_recalc, 93 .recalc = div2_recalc,
94}; 94};
95 95
@@ -128,7 +128,7 @@ static unsigned long pllc01_recalc(struct clk *clk)
128 return clk->parent->rate * mult; 128 return clk->parent->rate * mult;
129} 129}
130 130
131static struct clk_ops pllc01_clk_ops = { 131static struct sh_clk_ops pllc01_clk_ops = {
132 .recalc = pllc01_recalc, 132 .recalc = pllc01_recalc,
133}; 133};
134 134
@@ -276,7 +276,7 @@ static int pllc2_set_parent(struct clk *clk, struct clk *parent)
276 return 0; 276 return 0;
277} 277}
278 278
279static struct clk_ops pllc2_clk_ops = { 279static struct sh_clk_ops pllc2_clk_ops = {
280 .recalc = pllc2_recalc, 280 .recalc = pllc2_recalc,
281 .round_rate = pllc2_round_rate, 281 .round_rate = pllc2_round_rate,
282 .set_rate = pllc2_set_rate, 282 .set_rate = pllc2_set_rate,
@@ -468,7 +468,7 @@ static int fsidiv_set_rate(struct clk *clk, unsigned long rate)
468 return 0; 468 return 0;
469} 469}
470 470
471static struct clk_ops fsidiv_clk_ops = { 471static struct sh_clk_ops fsidiv_clk_ops = {
472 .recalc = fsidiv_recalc, 472 .recalc = fsidiv_recalc,
473 .round_rate = fsidiv_round_rate, 473 .round_rate = fsidiv_round_rate,
474 .set_rate = fsidiv_set_rate, 474 .set_rate = fsidiv_set_rate,
@@ -710,7 +710,7 @@ void __init sh7372_clock_init(void)
710 clkdev_add_table(lookups, ARRAY_SIZE(lookups)); 710 clkdev_add_table(lookups, ARRAY_SIZE(lookups));
711 711
712 if (!ret) 712 if (!ret)
713 clk_init(); 713 shmobile_clk_init();
714 else 714 else
715 panic("failed to setup sh7372 clocks\n"); 715 panic("failed to setup sh7372 clocks\n");
716 716
diff --git a/arch/arm/mach-shmobile/clock-sh7377.c b/arch/arm/mach-shmobile/clock-sh7377.c
index 8cee7b151ae3..0798a15936c3 100644
--- a/arch/arm/mach-shmobile/clock-sh7377.c
+++ b/arch/arm/mach-shmobile/clock-sh7377.c
@@ -77,7 +77,7 @@ static unsigned long div2_recalc(struct clk *clk)
77 return clk->parent->rate / 2; 77 return clk->parent->rate / 2;
78} 78}
79 79
80static struct clk_ops div2_clk_ops = { 80static struct sh_clk_ops div2_clk_ops = {
81 .recalc = div2_recalc, 81 .recalc = div2_recalc,
82}; 82};
83 83
@@ -110,7 +110,7 @@ static unsigned long pllc1_recalc(struct clk *clk)
110 return clk->parent->rate * mult; 110 return clk->parent->rate * mult;
111} 111}
112 112
113static struct clk_ops pllc1_clk_ops = { 113static struct sh_clk_ops pllc1_clk_ops = {
114 .recalc = pllc1_recalc, 114 .recalc = pllc1_recalc,
115}; 115};
116 116
@@ -137,7 +137,7 @@ static unsigned long pllc2_recalc(struct clk *clk)
137 return clk->parent->rate * mult; 137 return clk->parent->rate * mult;
138} 138}
139 139
140static struct clk_ops pllc2_clk_ops = { 140static struct sh_clk_ops pllc2_clk_ops = {
141 .recalc = pllc2_recalc, 141 .recalc = pllc2_recalc,
142}; 142};
143 143
@@ -360,7 +360,7 @@ void __init sh7377_clock_init(void)
360 clkdev_add_table(lookups, ARRAY_SIZE(lookups)); 360 clkdev_add_table(lookups, ARRAY_SIZE(lookups));
361 361
362 if (!ret) 362 if (!ret)
363 clk_init(); 363 shmobile_clk_init();
364 else 364 else
365 panic("failed to setup sh7377 clocks\n"); 365 panic("failed to setup sh7377 clocks\n");
366} 366}
diff --git a/arch/arm/mach-shmobile/clock-sh73a0.c b/arch/arm/mach-shmobile/clock-sh73a0.c
index 7727cca6136c..472d1f5361e5 100644
--- a/arch/arm/mach-shmobile/clock-sh73a0.c
+++ b/arch/arm/mach-shmobile/clock-sh73a0.c
@@ -88,7 +88,7 @@ static unsigned long div2_recalc(struct clk *clk)
88 return clk->parent->rate / 2; 88 return clk->parent->rate / 2;
89} 89}
90 90
91static struct clk_ops div2_clk_ops = { 91static struct sh_clk_ops div2_clk_ops = {
92 .recalc = div2_recalc, 92 .recalc = div2_recalc,
93}; 93};
94 94
@@ -97,7 +97,7 @@ static unsigned long div7_recalc(struct clk *clk)
97 return clk->parent->rate / 7; 97 return clk->parent->rate / 7;
98} 98}
99 99
100static struct clk_ops div7_clk_ops = { 100static struct sh_clk_ops div7_clk_ops = {
101 .recalc = div7_recalc, 101 .recalc = div7_recalc,
102}; 102};
103 103
@@ -106,7 +106,7 @@ static unsigned long div13_recalc(struct clk *clk)
106 return clk->parent->rate / 13; 106 return clk->parent->rate / 13;
107} 107}
108 108
109static struct clk_ops div13_clk_ops = { 109static struct sh_clk_ops div13_clk_ops = {
110 .recalc = div13_recalc, 110 .recalc = div13_recalc,
111}; 111};
112 112
@@ -122,7 +122,7 @@ static struct clk extal2_div2_clk = {
122 .parent = &sh73a0_extal2_clk, 122 .parent = &sh73a0_extal2_clk,
123}; 123};
124 124
125static struct clk_ops main_clk_ops = { 125static struct sh_clk_ops main_clk_ops = {
126 .recalc = followparent_recalc, 126 .recalc = followparent_recalc,
127}; 127};
128 128
@@ -156,7 +156,7 @@ static unsigned long pll_recalc(struct clk *clk)
156 return clk->parent->rate * mult; 156 return clk->parent->rate * mult;
157} 157}
158 158
159static struct clk_ops pll_clk_ops = { 159static struct sh_clk_ops pll_clk_ops = {
160 .recalc = pll_recalc, 160 .recalc = pll_recalc,
161}; 161};
162 162
@@ -438,7 +438,7 @@ static int dsiphy_set_rate(struct clk *clk, unsigned long rate)
438 return 0; 438 return 0;
439} 439}
440 440
441static struct clk_ops dsiphy_clk_ops = { 441static struct sh_clk_ops dsiphy_clk_ops = {
442 .recalc = dsiphy_recalc, 442 .recalc = dsiphy_recalc,
443 .round_rate = dsiphy_round_rate, 443 .round_rate = dsiphy_round_rate,
444 .set_rate = dsiphy_set_rate, 444 .set_rate = dsiphy_set_rate,
@@ -620,7 +620,7 @@ void __init sh73a0_clock_init(void)
620 clkdev_add_table(lookups, ARRAY_SIZE(lookups)); 620 clkdev_add_table(lookups, ARRAY_SIZE(lookups));
621 621
622 if (!ret) 622 if (!ret)
623 clk_init(); 623 shmobile_clk_init();
624 else 624 else
625 panic("failed to setup sh73a0 clocks\n"); 625 panic("failed to setup sh73a0 clocks\n");
626} 626}
diff --git a/arch/arm/mach-shmobile/clock.c b/arch/arm/mach-shmobile/clock.c
index 31654d78b96b..e816ca9bd213 100644
--- a/arch/arm/mach-shmobile/clock.c
+++ b/arch/arm/mach-shmobile/clock.c
@@ -24,7 +24,7 @@
24#include <linux/sh_clk.h> 24#include <linux/sh_clk.h>
25#include <linux/export.h> 25#include <linux/export.h>
26 26
27int __init clk_init(void) 27int __init shmobile_clk_init(void)
28{ 28{
29 /* Kick the child clocks.. */ 29 /* Kick the child clocks.. */
30 recalculate_root_clocks(); 30 recalculate_root_clocks();
diff --git a/arch/arm/mach-shmobile/include/mach/common.h b/arch/arm/mach-shmobile/include/mach/common.h
index e4b945e271e7..83ad3fe0a75f 100644
--- a/arch/arm/mach-shmobile/include/mach/common.h
+++ b/arch/arm/mach-shmobile/include/mach/common.h
@@ -1,12 +1,15 @@
1#ifndef __ARCH_MACH_COMMON_H 1#ifndef __ARCH_MACH_COMMON_H
2#define __ARCH_MACH_COMMON_H 2#define __ARCH_MACH_COMMON_H
3 3
4extern void shmobile_earlytimer_init(void);
4extern struct sys_timer shmobile_timer; 5extern struct sys_timer shmobile_timer;
6struct twd_local_timer;
7void shmobile_twd_init(struct twd_local_timer *twd_local_timer);
5extern void shmobile_setup_console(void); 8extern void shmobile_setup_console(void);
6extern void shmobile_secondary_vector(void); 9extern void shmobile_secondary_vector(void);
7extern int shmobile_platform_cpu_kill(unsigned int cpu); 10extern int shmobile_platform_cpu_kill(unsigned int cpu);
8struct clk; 11struct clk;
9extern int clk_init(void); 12extern int shmobile_clk_init(void);
10extern void shmobile_handle_irq_intc(struct pt_regs *); 13extern void shmobile_handle_irq_intc(struct pt_regs *);
11extern struct platform_suspend_ops shmobile_suspend_ops; 14extern struct platform_suspend_ops shmobile_suspend_ops;
12struct cpuidle_driver; 15struct cpuidle_driver;
@@ -14,6 +17,7 @@ extern void (*shmobile_cpuidle_modes[])(void);
14extern void (*shmobile_cpuidle_setup)(struct cpuidle_driver *drv); 17extern void (*shmobile_cpuidle_setup)(struct cpuidle_driver *drv);
15 18
16extern void sh7367_init_irq(void); 19extern void sh7367_init_irq(void);
20extern void sh7367_map_io(void);
17extern void sh7367_add_early_devices(void); 21extern void sh7367_add_early_devices(void);
18extern void sh7367_add_standard_devices(void); 22extern void sh7367_add_standard_devices(void);
19extern void sh7367_clock_init(void); 23extern void sh7367_clock_init(void);
@@ -22,6 +26,7 @@ extern struct clk sh7367_extalb1_clk;
22extern struct clk sh7367_extal2_clk; 26extern struct clk sh7367_extal2_clk;
23 27
24extern void sh7377_init_irq(void); 28extern void sh7377_init_irq(void);
29extern void sh7377_map_io(void);
25extern void sh7377_add_early_devices(void); 30extern void sh7377_add_early_devices(void);
26extern void sh7377_add_standard_devices(void); 31extern void sh7377_add_standard_devices(void);
27extern void sh7377_clock_init(void); 32extern void sh7377_clock_init(void);
@@ -30,6 +35,7 @@ extern struct clk sh7377_extalc1_clk;
30extern struct clk sh7377_extal2_clk; 35extern struct clk sh7377_extal2_clk;
31 36
32extern void sh7372_init_irq(void); 37extern void sh7372_init_irq(void);
38extern void sh7372_map_io(void);
33extern void sh7372_add_early_devices(void); 39extern void sh7372_add_early_devices(void);
34extern void sh7372_add_standard_devices(void); 40extern void sh7372_add_standard_devices(void);
35extern void sh7372_clock_init(void); 41extern void sh7372_clock_init(void);
@@ -41,6 +47,7 @@ extern struct clk sh7372_extal1_clk;
41extern struct clk sh7372_extal2_clk; 47extern struct clk sh7372_extal2_clk;
42 48
43extern void sh73a0_init_irq(void); 49extern void sh73a0_init_irq(void);
50extern void sh73a0_map_io(void);
44extern void sh73a0_add_early_devices(void); 51extern void sh73a0_add_early_devices(void);
45extern void sh73a0_add_standard_devices(void); 52extern void sh73a0_add_standard_devices(void);
46extern void sh73a0_clock_init(void); 53extern void sh73a0_clock_init(void);
@@ -56,12 +63,14 @@ extern int sh73a0_boot_secondary(unsigned int cpu);
56extern void sh73a0_smp_prepare_cpus(void); 63extern void sh73a0_smp_prepare_cpus(void);
57 64
58extern void r8a7740_init_irq(void); 65extern void r8a7740_init_irq(void);
66extern void r8a7740_map_io(void);
59extern void r8a7740_add_early_devices(void); 67extern void r8a7740_add_early_devices(void);
60extern void r8a7740_add_standard_devices(void); 68extern void r8a7740_add_standard_devices(void);
61extern void r8a7740_clock_init(u8 md_ck); 69extern void r8a7740_clock_init(u8 md_ck);
62extern void r8a7740_pinmux_init(void); 70extern void r8a7740_pinmux_init(void);
63 71
64extern void r8a7779_init_irq(void); 72extern void r8a7779_init_irq(void);
73extern void r8a7779_map_io(void);
65extern void r8a7779_add_early_devices(void); 74extern void r8a7779_add_early_devices(void);
66extern void r8a7779_add_standard_devices(void); 75extern void r8a7779_add_standard_devices(void);
67extern void r8a7779_clock_init(void); 76extern void r8a7779_clock_init(void);
diff --git a/arch/arm/mach-shmobile/localtimer.c b/arch/arm/mach-shmobile/localtimer.c
deleted file mode 100644
index ad9ccc9900c8..000000000000
--- a/arch/arm/mach-shmobile/localtimer.c
+++ /dev/null
@@ -1,26 +0,0 @@
1/*
2 * SMP support for R-Mobile / SH-Mobile - local timer portion
3 *
4 * Copyright (C) 2010 Magnus Damm
5 *
6 * Based on vexpress, Copyright (C) 2002 ARM Ltd, All Rights Reserved
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12#include <linux/init.h>
13#include <linux/smp.h>
14#include <linux/clockchips.h>
15#include <asm/smp_twd.h>
16#include <asm/localtimer.h>
17
18/*
19 * Setup the local clock events for a CPU.
20 */
21int __cpuinit local_timer_setup(struct clock_event_device *evt)
22{
23 evt->irq = 29;
24 twd_timer_setup(evt);
25 return 0;
26}
diff --git a/arch/arm/mach-shmobile/platsmp.c b/arch/arm/mach-shmobile/platsmp.c
index 993381257f69..45fa3924c6a1 100644
--- a/arch/arm/mach-shmobile/platsmp.c
+++ b/arch/arm/mach-shmobile/platsmp.c
@@ -17,7 +17,6 @@
17#include <linux/smp.h> 17#include <linux/smp.h>
18#include <linux/io.h> 18#include <linux/io.h>
19#include <asm/hardware/gic.h> 19#include <asm/hardware/gic.h>
20#include <asm/localtimer.h>
21#include <asm/mach-types.h> 20#include <asm/mach-types.h>
22#include <mach/common.h> 21#include <mach/common.h>
23 22
diff --git a/arch/arm/mach-shmobile/setup-r8a7740.c b/arch/arm/mach-shmobile/setup-r8a7740.c
index 986dca6b3fad..74e52341dd1b 100644
--- a/arch/arm/mach-shmobile/setup-r8a7740.c
+++ b/arch/arm/mach-shmobile/setup-r8a7740.c
@@ -25,8 +25,41 @@
25#include <linux/serial_sci.h> 25#include <linux/serial_sci.h>
26#include <linux/sh_timer.h> 26#include <linux/sh_timer.h>
27#include <mach/r8a7740.h> 27#include <mach/r8a7740.h>
28#include <mach/common.h>
28#include <asm/mach-types.h> 29#include <asm/mach-types.h>
30#include <asm/mach/map.h>
29#include <asm/mach/arch.h> 31#include <asm/mach/arch.h>
32#include <asm/mach/time.h>
33
34static struct map_desc r8a7740_io_desc[] __initdata = {
35 /*
36 * for CPGA/INTC/PFC
37 * 0xe6000000-0xefffffff -> 0xe6000000-0xefffffff
38 */
39 {
40 .virtual = 0xe6000000,
41 .pfn = __phys_to_pfn(0xe6000000),
42 .length = 160 << 20,
43 .type = MT_DEVICE_NONSHARED
44 },
45#ifdef CONFIG_CACHE_L2X0
46 /*
47 * for l2x0_init()
48 * 0xf0100000-0xf0101000 -> 0xf0002000-0xf0003000
49 */
50 {
51 .virtual = 0xf0002000,
52 .pfn = __phys_to_pfn(0xf0100000),
53 .length = PAGE_SIZE,
54 .type = MT_DEVICE_NONSHARED
55 },
56#endif
57};
58
59void __init r8a7740_map_io(void)
60{
61 iotable_init(r8a7740_io_desc, ARRAY_SIZE(r8a7740_io_desc));
62}
30 63
31/* SCIFA0 */ 64/* SCIFA0 */
32static struct plat_sci_port scif0_platform_data = { 65static struct plat_sci_port scif0_platform_data = {
@@ -345,8 +378,20 @@ void __init r8a7740_add_standard_devices(void)
345 ARRAY_SIZE(r8a7740_late_devices)); 378 ARRAY_SIZE(r8a7740_late_devices));
346} 379}
347 380
381static void __init r8a7740_earlytimer_init(void)
382{
383 r8a7740_clock_init(0);
384 shmobile_earlytimer_init();
385}
386
348void __init r8a7740_add_early_devices(void) 387void __init r8a7740_add_early_devices(void)
349{ 388{
350 early_platform_add_devices(r8a7740_early_devices, 389 early_platform_add_devices(r8a7740_early_devices,
351 ARRAY_SIZE(r8a7740_early_devices)); 390 ARRAY_SIZE(r8a7740_early_devices));
391
392 /* setup early console here as well */
393 shmobile_setup_console();
394
395 /* override timer setup with soc-specific code */
396 shmobile_timer.init = r8a7740_earlytimer_init;
352} 397}
diff --git a/arch/arm/mach-shmobile/setup-r8a7779.c b/arch/arm/mach-shmobile/setup-r8a7779.c
index 4725663bd032..6820d785493d 100644
--- a/arch/arm/mach-shmobile/setup-r8a7779.c
+++ b/arch/arm/mach-shmobile/setup-r8a7779.c
@@ -33,6 +33,31 @@
33#include <mach/common.h> 33#include <mach/common.h>
34#include <asm/mach-types.h> 34#include <asm/mach-types.h>
35#include <asm/mach/arch.h> 35#include <asm/mach/arch.h>
36#include <asm/mach/time.h>
37#include <asm/mach/map.h>
38#include <asm/hardware/cache-l2x0.h>
39
40static struct map_desc r8a7779_io_desc[] __initdata = {
41 /* 2M entity map for 0xf0000000 (MPCORE) */
42 {
43 .virtual = 0xf0000000,
44 .pfn = __phys_to_pfn(0xf0000000),
45 .length = SZ_2M,
46 .type = MT_DEVICE_NONSHARED
47 },
48 /* 16M entity map for 0xfexxxxxx (DMAC-S/HPBREG/INTC2/LRAM/DBSC) */
49 {
50 .virtual = 0xfe000000,
51 .pfn = __phys_to_pfn(0xfe000000),
52 .length = SZ_16M,
53 .type = MT_DEVICE_NONSHARED
54 },
55};
56
57void __init r8a7779_map_io(void)
58{
59 iotable_init(r8a7779_io_desc, ARRAY_SIZE(r8a7779_io_desc));
60}
36 61
37static struct plat_sci_port scif0_platform_data = { 62static struct plat_sci_port scif0_platform_data = {
38 .mapbase = 0xffe40000, 63 .mapbase = 0xffe40000,
@@ -219,6 +244,10 @@ static struct platform_device *r8a7779_late_devices[] __initdata = {
219 244
220void __init r8a7779_add_standard_devices(void) 245void __init r8a7779_add_standard_devices(void)
221{ 246{
247#ifdef CONFIG_CACHE_L2X0
248 /* Early BRESP enable, Shared attribute override enable, 64K*16way */
249 l2x0_init((void __iomem __force *)(0xf0100000), 0x40470000, 0x82000fff);
250#endif
222 r8a7779_pm_init(); 251 r8a7779_pm_init();
223 252
224 r8a7779_init_pm_domain(&r8a7779_sh4a); 253 r8a7779_init_pm_domain(&r8a7779_sh4a);
@@ -232,8 +261,33 @@ void __init r8a7779_add_standard_devices(void)
232 ARRAY_SIZE(r8a7779_late_devices)); 261 ARRAY_SIZE(r8a7779_late_devices));
233} 262}
234 263
264static void __init r8a7779_earlytimer_init(void)
265{
266 r8a7779_clock_init();
267 shmobile_earlytimer_init();
268}
269
235void __init r8a7779_add_early_devices(void) 270void __init r8a7779_add_early_devices(void)
236{ 271{
237 early_platform_add_devices(r8a7779_early_devices, 272 early_platform_add_devices(r8a7779_early_devices,
238 ARRAY_SIZE(r8a7779_early_devices)); 273 ARRAY_SIZE(r8a7779_early_devices));
274
275 /* Early serial console setup is not included here due to
276 * memory map collisions. The SCIF serial ports in r8a7779
277 * are difficult to entity map 1:1 due to collision with the
278 * virtual memory range used by the coherent DMA code on ARM.
279 *
280 * Anyone wanting to debug early can remove UPF_IOREMAP from
281 * the sh-sci serial console platform data, adjust mapbase
282 * to a static M:N virt:phys mapping that needs to be added to
283 * the mappings passed with iotable_init() above.
284 *
285 * Then add a call to shmobile_setup_console() from this function.
286 *
287 * As a final step pass earlyprint=sh-sci.2,115200 on the kernel
288 * command line in case of the marzen board.
289 */
290
291 /* override timer setup with soc-specific code */
292 shmobile_timer.init = r8a7779_earlytimer_init;
239} 293}
diff --git a/arch/arm/mach-shmobile/setup-sh7367.c b/arch/arm/mach-shmobile/setup-sh7367.c
index e546017f15de..a51e1a1e6996 100644
--- a/arch/arm/mach-shmobile/setup-sh7367.c
+++ b/arch/arm/mach-shmobile/setup-sh7367.c
@@ -29,8 +29,28 @@
29#include <linux/serial_sci.h> 29#include <linux/serial_sci.h>
30#include <linux/sh_timer.h> 30#include <linux/sh_timer.h>
31#include <mach/hardware.h> 31#include <mach/hardware.h>
32#include <mach/common.h>
32#include <asm/mach-types.h> 33#include <asm/mach-types.h>
33#include <asm/mach/arch.h> 34#include <asm/mach/arch.h>
35#include <asm/mach/map.h>
36#include <asm/mach/time.h>
37
38static struct map_desc sh7367_io_desc[] __initdata = {
39 /* create a 1:1 entity map for 0xe6xxxxxx
40 * used by CPGA, INTC and PFC.
41 */
42 {
43 .virtual = 0xe6000000,
44 .pfn = __phys_to_pfn(0xe6000000),
45 .length = 256 << 20,
46 .type = MT_DEVICE_NONSHARED
47 },
48};
49
50void __init sh7367_map_io(void)
51{
52 iotable_init(sh7367_io_desc, ARRAY_SIZE(sh7367_io_desc));
53}
34 54
35/* SCIFA0 */ 55/* SCIFA0 */
36static struct plat_sci_port scif0_platform_data = { 56static struct plat_sci_port scif0_platform_data = {
@@ -435,6 +455,12 @@ void __init sh7367_add_standard_devices(void)
435 ARRAY_SIZE(sh7367_devices)); 455 ARRAY_SIZE(sh7367_devices));
436} 456}
437 457
458static void __init sh7367_earlytimer_init(void)
459{
460 sh7367_clock_init();
461 shmobile_earlytimer_init();
462}
463
438#define SYMSTPCR2 0xe6158048 464#define SYMSTPCR2 0xe6158048
439#define SYMSTPCR2_CMT1 (1 << 29) 465#define SYMSTPCR2_CMT1 (1 << 29)
440 466
@@ -445,4 +471,10 @@ void __init sh7367_add_early_devices(void)
445 471
446 early_platform_add_devices(sh7367_early_devices, 472 early_platform_add_devices(sh7367_early_devices,
447 ARRAY_SIZE(sh7367_early_devices)); 473 ARRAY_SIZE(sh7367_early_devices));
474
475 /* setup early console here as well */
476 shmobile_setup_console();
477
478 /* override timer setup with soc-specific code */
479 shmobile_timer.init = sh7367_earlytimer_init;
448} 480}
diff --git a/arch/arm/mach-shmobile/setup-sh7372.c b/arch/arm/mach-shmobile/setup-sh7372.c
index cccf91b8fae1..5375325d7ca7 100644
--- a/arch/arm/mach-shmobile/setup-sh7372.c
+++ b/arch/arm/mach-shmobile/setup-sh7372.c
@@ -33,8 +33,28 @@
33#include <linux/pm_domain.h> 33#include <linux/pm_domain.h>
34#include <mach/hardware.h> 34#include <mach/hardware.h>
35#include <mach/sh7372.h> 35#include <mach/sh7372.h>
36#include <mach/common.h>
37#include <asm/mach/map.h>
36#include <asm/mach-types.h> 38#include <asm/mach-types.h>
37#include <asm/mach/arch.h> 39#include <asm/mach/arch.h>
40#include <asm/mach/time.h>
41
42static struct map_desc sh7372_io_desc[] __initdata = {
43 /* create a 1:1 entity map for 0xe6xxxxxx
44 * used by CPGA, INTC and PFC.
45 */
46 {
47 .virtual = 0xe6000000,
48 .pfn = __phys_to_pfn(0xe6000000),
49 .length = 256 << 20,
50 .type = MT_DEVICE_NONSHARED
51 },
52};
53
54void __init sh7372_map_io(void)
55{
56 iotable_init(sh7372_io_desc, ARRAY_SIZE(sh7372_io_desc));
57}
38 58
39/* SCIFA0 */ 59/* SCIFA0 */
40static struct plat_sci_port scif0_platform_data = { 60static struct plat_sci_port scif0_platform_data = {
@@ -1047,8 +1067,20 @@ void __init sh7372_add_standard_devices(void)
1047 sh7372_add_device_to_domain(&sh7372_a4r, &tmu01_device); 1067 sh7372_add_device_to_domain(&sh7372_a4r, &tmu01_device);
1048} 1068}
1049 1069
1070static void __init sh7372_earlytimer_init(void)
1071{
1072 sh7372_clock_init();
1073 shmobile_earlytimer_init();
1074}
1075
1050void __init sh7372_add_early_devices(void) 1076void __init sh7372_add_early_devices(void)
1051{ 1077{
1052 early_platform_add_devices(sh7372_early_devices, 1078 early_platform_add_devices(sh7372_early_devices,
1053 ARRAY_SIZE(sh7372_early_devices)); 1079 ARRAY_SIZE(sh7372_early_devices));
1080
1081 /* setup early console here as well */
1082 shmobile_setup_console();
1083
1084 /* override timer setup with soc-specific code */
1085 shmobile_timer.init = sh7372_earlytimer_init;
1054} 1086}
diff --git a/arch/arm/mach-shmobile/setup-sh7377.c b/arch/arm/mach-shmobile/setup-sh7377.c
index bb405b8e459b..9f146095098b 100644
--- a/arch/arm/mach-shmobile/setup-sh7377.c
+++ b/arch/arm/mach-shmobile/setup-sh7377.c
@@ -30,8 +30,28 @@
30#include <linux/sh_intc.h> 30#include <linux/sh_intc.h>
31#include <linux/sh_timer.h> 31#include <linux/sh_timer.h>
32#include <mach/hardware.h> 32#include <mach/hardware.h>
33#include <mach/common.h>
34#include <asm/mach/map.h>
33#include <asm/mach-types.h> 35#include <asm/mach-types.h>
34#include <asm/mach/arch.h> 36#include <asm/mach/arch.h>
37#include <asm/mach/time.h>
38
39static struct map_desc sh7377_io_desc[] __initdata = {
40 /* create a 1:1 entity map for 0xe6xxxxxx
41 * used by CPGA, INTC and PFC.
42 */
43 {
44 .virtual = 0xe6000000,
45 .pfn = __phys_to_pfn(0xe6000000),
46 .length = 256 << 20,
47 .type = MT_DEVICE_NONSHARED
48 },
49};
50
51void __init sh7377_map_io(void)
52{
53 iotable_init(sh7377_io_desc, ARRAY_SIZE(sh7377_io_desc));
54}
35 55
36/* SCIFA0 */ 56/* SCIFA0 */
37static struct plat_sci_port scif0_platform_data = { 57static struct plat_sci_port scif0_platform_data = {
@@ -456,6 +476,12 @@ void __init sh7377_add_standard_devices(void)
456 ARRAY_SIZE(sh7377_devices)); 476 ARRAY_SIZE(sh7377_devices));
457} 477}
458 478
479static void __init sh7377_earlytimer_init(void)
480{
481 sh7377_clock_init();
482 shmobile_earlytimer_init();
483}
484
459#define SMSTPCR3 0xe615013c 485#define SMSTPCR3 0xe615013c
460#define SMSTPCR3_CMT1 (1 << 29) 486#define SMSTPCR3_CMT1 (1 << 29)
461 487
@@ -466,4 +492,10 @@ void __init sh7377_add_early_devices(void)
466 492
467 early_platform_add_devices(sh7377_early_devices, 493 early_platform_add_devices(sh7377_early_devices,
468 ARRAY_SIZE(sh7377_early_devices)); 494 ARRAY_SIZE(sh7377_early_devices));
495
496 /* setup early console here as well */
497 shmobile_setup_console();
498
499 /* override timer setup with soc-specific code */
500 shmobile_timer.init = sh7377_earlytimer_init;
469} 501}
diff --git a/arch/arm/mach-shmobile/setup-sh73a0.c b/arch/arm/mach-shmobile/setup-sh73a0.c
index 20e71e5cace4..b6a0734a738e 100644
--- a/arch/arm/mach-shmobile/setup-sh73a0.c
+++ b/arch/arm/mach-shmobile/setup-sh73a0.c
@@ -32,8 +32,28 @@
32#include <linux/sh_timer.h> 32#include <linux/sh_timer.h>
33#include <mach/hardware.h> 33#include <mach/hardware.h>
34#include <mach/sh73a0.h> 34#include <mach/sh73a0.h>
35#include <mach/common.h>
35#include <asm/mach-types.h> 36#include <asm/mach-types.h>
37#include <asm/mach/map.h>
36#include <asm/mach/arch.h> 38#include <asm/mach/arch.h>
39#include <asm/mach/time.h>
40
41static struct map_desc sh73a0_io_desc[] __initdata = {
42 /* create a 1:1 entity map for 0xe6xxxxxx
43 * used by CPGA, INTC and PFC.
44 */
45 {
46 .virtual = 0xe6000000,
47 .pfn = __phys_to_pfn(0xe6000000),
48 .length = 256 << 20,
49 .type = MT_DEVICE_NONSHARED
50 },
51};
52
53void __init sh73a0_map_io(void)
54{
55 iotable_init(sh73a0_io_desc, ARRAY_SIZE(sh73a0_io_desc));
56}
37 57
38static struct plat_sci_port scif0_platform_data = { 58static struct plat_sci_port scif0_platform_data = {
39 .mapbase = 0xe6c40000, 59 .mapbase = 0xe6c40000,
@@ -667,8 +687,20 @@ void __init sh73a0_add_standard_devices(void)
667 ARRAY_SIZE(sh73a0_late_devices)); 687 ARRAY_SIZE(sh73a0_late_devices));
668} 688}
669 689
690static void __init sh73a0_earlytimer_init(void)
691{
692 sh73a0_clock_init();
693 shmobile_earlytimer_init();
694}
695
670void __init sh73a0_add_early_devices(void) 696void __init sh73a0_add_early_devices(void)
671{ 697{
672 early_platform_add_devices(sh73a0_early_devices, 698 early_platform_add_devices(sh73a0_early_devices,
673 ARRAY_SIZE(sh73a0_early_devices)); 699 ARRAY_SIZE(sh73a0_early_devices));
700
701 /* setup early console here as well */
702 shmobile_setup_console();
703
704 /* override timer setup with soc-specific code */
705 shmobile_timer.init = sh73a0_earlytimer_init;
674} 706}
diff --git a/arch/arm/mach-shmobile/smp-r8a7779.c b/arch/arm/mach-shmobile/smp-r8a7779.c
index 4fe2e9eaf501..9bb7b8575a1f 100644
--- a/arch/arm/mach-shmobile/smp-r8a7779.c
+++ b/arch/arm/mach-shmobile/smp-r8a7779.c
@@ -64,6 +64,8 @@ static void __iomem *scu_base_addr(void)
64static DEFINE_SPINLOCK(scu_lock); 64static DEFINE_SPINLOCK(scu_lock);
65static unsigned long tmp; 65static unsigned long tmp;
66 66
67static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, 0xf0000600, 29);
68
67static void modify_scu_cpu_psr(unsigned long set, unsigned long clr) 69static void modify_scu_cpu_psr(unsigned long set, unsigned long clr)
68{ 70{
69 void __iomem *scu_base = scu_base_addr(); 71 void __iomem *scu_base = scu_base_addr();
@@ -82,11 +84,7 @@ unsigned int __init r8a7779_get_core_count(void)
82{ 84{
83 void __iomem *scu_base = scu_base_addr(); 85 void __iomem *scu_base = scu_base_addr();
84 86
85#ifdef CONFIG_HAVE_ARM_TWD 87 shmobile_twd_init(&twd_local_timer);
86 /* twd_base needs to be initialized before percpu_timer_setup() */
87 twd_base = (void __iomem *)0xf0000600;
88#endif
89
90 return scu_get_core_count(scu_base); 88 return scu_get_core_count(scu_base);
91} 89}
92 90
diff --git a/arch/arm/mach-shmobile/smp-sh73a0.c b/arch/arm/mach-shmobile/smp-sh73a0.c
index 2d0d4212be41..c0a9093ba3a8 100644
--- a/arch/arm/mach-shmobile/smp-sh73a0.c
+++ b/arch/arm/mach-shmobile/smp-sh73a0.c
@@ -42,6 +42,8 @@ static void __iomem *scu_base_addr(void)
42static DEFINE_SPINLOCK(scu_lock); 42static DEFINE_SPINLOCK(scu_lock);
43static unsigned long tmp; 43static unsigned long tmp;
44 44
45static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, 0xf0000600, 29);
46
45static void modify_scu_cpu_psr(unsigned long set, unsigned long clr) 47static void modify_scu_cpu_psr(unsigned long set, unsigned long clr)
46{ 48{
47 void __iomem *scu_base = scu_base_addr(); 49 void __iomem *scu_base = scu_base_addr();
@@ -60,11 +62,7 @@ unsigned int __init sh73a0_get_core_count(void)
60{ 62{
61 void __iomem *scu_base = scu_base_addr(); 63 void __iomem *scu_base = scu_base_addr();
62 64
63#ifdef CONFIG_HAVE_ARM_TWD 65 shmobile_twd_init(&twd_local_timer);
64 /* twd_base needs to be initialized before percpu_timer_setup() */
65 twd_base = (void __iomem *)0xf0000600;
66#endif
67
68 return scu_get_core_count(scu_base); 66 return scu_get_core_count(scu_base);
69} 67}
70 68
diff --git a/arch/arm/mach-shmobile/timer.c b/arch/arm/mach-shmobile/timer.c
index 895794b543cd..2fba5f3d1c8a 100644
--- a/arch/arm/mach-shmobile/timer.c
+++ b/arch/arm/mach-shmobile/timer.c
@@ -20,6 +20,7 @@
20 */ 20 */
21#include <linux/platform_device.h> 21#include <linux/platform_device.h>
22#include <asm/mach/time.h> 22#include <asm/mach/time.h>
23#include <asm/smp_twd.h>
23 24
24static void __init shmobile_late_time_init(void) 25static void __init shmobile_late_time_init(void)
25{ 26{
@@ -36,11 +37,24 @@ static void __init shmobile_late_time_init(void)
36 early_platform_driver_probe("earlytimer", 2, 0); 37 early_platform_driver_probe("earlytimer", 2, 0);
37} 38}
38 39
39static void __init shmobile_timer_init(void) 40void __init shmobile_earlytimer_init(void)
40{ 41{
41 late_time_init = shmobile_late_time_init; 42 late_time_init = shmobile_late_time_init;
42} 43}
43 44
45static void __init shmobile_timer_init(void)
46{
47}
48
49void __init shmobile_twd_init(struct twd_local_timer *twd_local_timer)
50{
51#ifdef CONFIG_HAVE_ARM_TWD
52 int err = twd_local_timer_register(twd_local_timer);
53 if (err)
54 pr_err("twd_local_timer_register failed %d\n", err);
55#endif
56}
57
44struct sys_timer shmobile_timer = { 58struct sys_timer shmobile_timer = {
45 .init = shmobile_timer_init, 59 .init = shmobile_timer_init,
46}; 60};
diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig
index 16511199bad6..d0f2546706ca 100644
--- a/arch/arm/mach-tegra/Kconfig
+++ b/arch/arm/mach-tegra/Kconfig
@@ -10,7 +10,7 @@ config ARCH_TEGRA_2x_SOC
10 select PINCTRL 10 select PINCTRL
11 select PINCTRL_TEGRA20 11 select PINCTRL_TEGRA20
12 select USB_ARCH_HAS_EHCI if USB_SUPPORT 12 select USB_ARCH_HAS_EHCI if USB_SUPPORT
13 select USB_ULPI if USB_SUPPORT 13 select USB_ULPI if USB
14 select USB_ULPI_VIEWPORT if USB_SUPPORT 14 select USB_ULPI_VIEWPORT if USB_SUPPORT
15 select ARM_ERRATA_720789 15 select ARM_ERRATA_720789
16 select ARM_ERRATA_742230 16 select ARM_ERRATA_742230
@@ -32,7 +32,7 @@ config ARCH_TEGRA_3x_SOC
32 select PINCTRL 32 select PINCTRL
33 select PINCTRL_TEGRA30 33 select PINCTRL_TEGRA30
34 select USB_ARCH_HAS_EHCI if USB_SUPPORT 34 select USB_ARCH_HAS_EHCI if USB_SUPPORT
35 select USB_ULPI if USB_SUPPORT 35 select USB_ULPI if USB
36 select USB_ULPI_VIEWPORT if USB_SUPPORT 36 select USB_ULPI_VIEWPORT if USB_SUPPORT
37 select USE_OF 37 select USE_OF
38 select ARM_ERRATA_743622 38 select ARM_ERRATA_743622
diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile
index 829066fdc2ad..bcbb4e8d5530 100644
--- a/arch/arm/mach-tegra/Makefile
+++ b/arch/arm/mach-tegra/Makefile
@@ -14,7 +14,6 @@ obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += pinmux-tegra20-tables.o
14obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += pinmux-tegra30-tables.o 14obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += pinmux-tegra30-tables.o
15obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += board-dt-tegra30.o 15obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += board-dt-tegra30.o
16obj-$(CONFIG_SMP) += platsmp.o headsmp.o 16obj-$(CONFIG_SMP) += platsmp.o headsmp.o
17obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o
18obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o 17obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
19obj-$(CONFIG_TEGRA_SYSTEM_DMA) += dma.o 18obj-$(CONFIG_TEGRA_SYSTEM_DMA) += dma.o
20obj-$(CONFIG_CPU_FREQ) += cpu-tegra.o 19obj-$(CONFIG_CPU_FREQ) += cpu-tegra.o
diff --git a/arch/arm/mach-tegra/board-harmony-pinmux.c b/arch/arm/mach-tegra/board-harmony-pinmux.c
index 465808c8ac0b..1af85bccc0f1 100644
--- a/arch/arm/mach-tegra/board-harmony-pinmux.c
+++ b/arch/arm/mach-tegra/board-harmony-pinmux.c
@@ -53,7 +53,7 @@ static struct tegra_pingroup_config harmony_pinmux[] = {
53 {TEGRA_PINGROUP_GME, TEGRA_MUX_SDIO4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, 53 {TEGRA_PINGROUP_GME, TEGRA_MUX_SDIO4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
54 {TEGRA_PINGROUP_GPU, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, 54 {TEGRA_PINGROUP_GPU, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
55 {TEGRA_PINGROUP_GPU7, TEGRA_MUX_RTCK, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, 55 {TEGRA_PINGROUP_GPU7, TEGRA_MUX_RTCK, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
56 {TEGRA_PINGROUP_GPV, TEGRA_MUX_PCIE, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, 56 {TEGRA_PINGROUP_GPV, TEGRA_MUX_PCIE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
57 {TEGRA_PINGROUP_HDINT, TEGRA_MUX_HDMI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, 57 {TEGRA_PINGROUP_HDINT, TEGRA_MUX_HDMI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
58 {TEGRA_PINGROUP_I2CP, TEGRA_MUX_I2C, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, 58 {TEGRA_PINGROUP_I2CP, TEGRA_MUX_I2C, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
59 {TEGRA_PINGROUP_IRRX, TEGRA_MUX_UARTA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, 59 {TEGRA_PINGROUP_IRRX, TEGRA_MUX_UARTA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
@@ -112,10 +112,10 @@ static struct tegra_pingroup_config harmony_pinmux[] = {
112 {TEGRA_PINGROUP_SDC, TEGRA_MUX_PWM, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL}, 112 {TEGRA_PINGROUP_SDC, TEGRA_MUX_PWM, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
113 {TEGRA_PINGROUP_SDD, TEGRA_MUX_PWM, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE}, 113 {TEGRA_PINGROUP_SDD, TEGRA_MUX_PWM, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
114 {TEGRA_PINGROUP_SDIO1, TEGRA_MUX_SDIO1, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, 114 {TEGRA_PINGROUP_SDIO1, TEGRA_MUX_SDIO1, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
115 {TEGRA_PINGROUP_SLXA, TEGRA_MUX_PCIE, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, 115 {TEGRA_PINGROUP_SLXA, TEGRA_MUX_PCIE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
116 {TEGRA_PINGROUP_SLXC, TEGRA_MUX_SPDIF, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, 116 {TEGRA_PINGROUP_SLXC, TEGRA_MUX_SPDIF, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
117 {TEGRA_PINGROUP_SLXD, TEGRA_MUX_SPDIF, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, 117 {TEGRA_PINGROUP_SLXD, TEGRA_MUX_SPDIF, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
118 {TEGRA_PINGROUP_SLXK, TEGRA_MUX_PCIE, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, 118 {TEGRA_PINGROUP_SLXK, TEGRA_MUX_PCIE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
119 {TEGRA_PINGROUP_SPDI, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, 119 {TEGRA_PINGROUP_SPDI, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
120 {TEGRA_PINGROUP_SPDO, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE}, 120 {TEGRA_PINGROUP_SPDO, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
121 {TEGRA_PINGROUP_SPIA, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL}, 121 {TEGRA_PINGROUP_SPIA, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
diff --git a/arch/arm/mach-tegra/localtimer.c b/arch/arm/mach-tegra/localtimer.c
deleted file mode 100644
index e91d681d45a2..000000000000
--- a/arch/arm/mach-tegra/localtimer.c
+++ /dev/null
@@ -1,26 +0,0 @@
1/*
2 * arch/arm/mach-tegra/localtimer.c
3 *
4 * Copyright (C) 2002 ARM Ltd.
5 * All Rights Reserved
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#include <linux/init.h>
12#include <linux/smp.h>
13#include <linux/clockchips.h>
14#include <asm/irq.h>
15#include <asm/smp_twd.h>
16#include <asm/localtimer.h>
17
18/*
19 * Setup the local clock events for a CPU.
20 */
21int __cpuinit local_timer_setup(struct clock_event_device *evt)
22{
23 evt->irq = IRQ_LOCALTIMER;
24 twd_timer_setup(evt);
25 return 0;
26}
diff --git a/arch/arm/mach-tegra/pcie.c b/arch/arm/mach-tegra/pcie.c
index 14b29ab5d8f0..54a816ff3847 100644
--- a/arch/arm/mach-tegra/pcie.c
+++ b/arch/arm/mach-tegra/pcie.c
@@ -585,10 +585,10 @@ static void tegra_pcie_setup_translations(void)
585 afi_writel(0, AFI_MSI_BAR_SZ); 585 afi_writel(0, AFI_MSI_BAR_SZ);
586} 586}
587 587
588static void tegra_pcie_enable_controller(void) 588static int tegra_pcie_enable_controller(void)
589{ 589{
590 u32 val, reg; 590 u32 val, reg;
591 int i; 591 int i, timeout;
592 592
593 /* Enable slot clock and pulse the reset signals */ 593 /* Enable slot clock and pulse the reset signals */
594 for (i = 0, reg = AFI_PEX0_CTRL; i < 2; i++, reg += 0x8) { 594 for (i = 0, reg = AFI_PEX0_CTRL; i < 2; i++, reg += 0x8) {
@@ -639,8 +639,14 @@ static void tegra_pcie_enable_controller(void)
639 pads_writel(0xfa5cfa5c, 0xc8); 639 pads_writel(0xfa5cfa5c, 0xc8);
640 640
641 /* Wait for the PLL to lock */ 641 /* Wait for the PLL to lock */
642 timeout = 300;
642 do { 643 do {
643 val = pads_readl(PADS_PLL_CTL); 644 val = pads_readl(PADS_PLL_CTL);
645 usleep_range(1000, 1000);
646 if (--timeout == 0) {
647 pr_err("Tegra PCIe error: timeout waiting for PLL\n");
648 return -EBUSY;
649 }
644 } while (!(val & PADS_PLL_CTL_LOCKDET)); 650 } while (!(val & PADS_PLL_CTL_LOCKDET));
645 651
646 /* turn off IDDQ override */ 652 /* turn off IDDQ override */
@@ -671,7 +677,7 @@ static void tegra_pcie_enable_controller(void)
671 /* Disable all execptions */ 677 /* Disable all execptions */
672 afi_writel(0, AFI_FPCI_ERROR_MASKS); 678 afi_writel(0, AFI_FPCI_ERROR_MASKS);
673 679
674 return; 680 return 0;
675} 681}
676 682
677static void tegra_pcie_xclk_clamp(bool clamp) 683static void tegra_pcie_xclk_clamp(bool clamp)
@@ -921,7 +927,9 @@ int __init tegra_pcie_init(bool init_port0, bool init_port1)
921 if (err) 927 if (err)
922 return err; 928 return err;
923 929
924 tegra_pcie_enable_controller(); 930 err = tegra_pcie_enable_controller();
931 if (err)
932 return err;
925 933
926 /* setup the AFI address translations */ 934 /* setup the AFI address translations */
927 tegra_pcie_setup_translations(); 935 tegra_pcie_setup_translations();
diff --git a/arch/arm/mach-tegra/timer.c b/arch/arm/mach-tegra/timer.c
index 1d1acda4f3e0..1eed8d4a80ef 100644
--- a/arch/arm/mach-tegra/timer.c
+++ b/arch/arm/mach-tegra/timer.c
@@ -28,7 +28,7 @@
28#include <linux/io.h> 28#include <linux/io.h>
29 29
30#include <asm/mach/time.h> 30#include <asm/mach/time.h>
31#include <asm/localtimer.h> 31#include <asm/smp_twd.h>
32#include <asm/sched_clock.h> 32#include <asm/sched_clock.h>
33 33
34#include <mach/iomap.h> 34#include <mach/iomap.h>
@@ -162,6 +162,21 @@ static struct irqaction tegra_timer_irq = {
162 .irq = INT_TMR3, 162 .irq = INT_TMR3,
163}; 163};
164 164
165#ifdef CONFIG_HAVE_ARM_TWD
166static DEFINE_TWD_LOCAL_TIMER(twd_local_timer,
167 TEGRA_ARM_PERIF_BASE + 0x600,
168 IRQ_LOCALTIMER);
169
170static void __init tegra_twd_init(void)
171{
172 int err = twd_local_timer_register(&twd_local_timer);
173 if (err)
174 pr_err("twd_local_timer_register failed %d\n", err);
175}
176#else
177#define tegra_twd_init() do {} while(0)
178#endif
179
165static void __init tegra_init_timer(void) 180static void __init tegra_init_timer(void)
166{ 181{
167 struct clk *clk; 182 struct clk *clk;
@@ -188,10 +203,6 @@ static void __init tegra_init_timer(void)
188 else 203 else
189 clk_enable(clk); 204 clk_enable(clk);
190 205
191#ifdef CONFIG_HAVE_ARM_TWD
192 twd_base = IO_ADDRESS(TEGRA_ARM_PERIF_BASE + 0x600);
193#endif
194
195 switch (rate) { 206 switch (rate) {
196 case 12000000: 207 case 12000000:
197 timer_writel(0x000b, TIMERUS_USEC_CFG); 208 timer_writel(0x000b, TIMERUS_USEC_CFG);
@@ -231,6 +242,7 @@ static void __init tegra_init_timer(void)
231 tegra_clockevent.cpumask = cpu_all_mask; 242 tegra_clockevent.cpumask = cpu_all_mask;
232 tegra_clockevent.irq = tegra_timer_irq.irq; 243 tegra_clockevent.irq = tegra_timer_irq.irq;
233 clockevents_register_device(&tegra_clockevent); 244 clockevents_register_device(&tegra_clockevent);
245 tegra_twd_init();
234} 246}
235 247
236struct sys_timer tegra_timer = { 248struct sys_timer tegra_timer = {
diff --git a/arch/arm/mach-ux500/Makefile b/arch/arm/mach-ux500/Makefile
index 8dd75f210d2b..465b9ec9510a 100644
--- a/arch/arm/mach-ux500/Makefile
+++ b/arch/arm/mach-ux500/Makefile
@@ -15,7 +15,6 @@ obj-$(CONFIG_MACH_MOP500) += board-mop500.o board-mop500-sdi.o \
15obj-$(CONFIG_MACH_U5500) += board-u5500.o board-u5500-sdi.o 15obj-$(CONFIG_MACH_U5500) += board-u5500.o board-u5500-sdi.o
16obj-$(CONFIG_SMP) += platsmp.o headsmp.o 16obj-$(CONFIG_SMP) += platsmp.o headsmp.o
17obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o 17obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
18obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o
19obj-$(CONFIG_U5500_MODEM_IRQ) += modem-irq-db5500.o 18obj-$(CONFIG_U5500_MODEM_IRQ) += modem-irq-db5500.o
20obj-$(CONFIG_U5500_MBOX) += mbox-db5500.o 19obj-$(CONFIG_U5500_MBOX) += mbox-db5500.o
21 20
diff --git a/arch/arm/mach-ux500/cpu.c b/arch/arm/mach-ux500/cpu.c
index f41857494375..851308bf6424 100644
--- a/arch/arm/mach-ux500/cpu.c
+++ b/arch/arm/mach-ux500/cpu.c
@@ -14,7 +14,6 @@
14 14
15#include <asm/hardware/gic.h> 15#include <asm/hardware/gic.h>
16#include <asm/mach/map.h> 16#include <asm/mach/map.h>
17#include <asm/localtimer.h>
18 17
19#include <mach/hardware.h> 18#include <mach/hardware.h>
20#include <mach/setup.h> 19#include <mach/setup.h>
diff --git a/arch/arm/mach-ux500/include/mach/setup.h b/arch/arm/mach-ux500/include/mach/setup.h
index a7d363fdb4cd..93d403955eaa 100644
--- a/arch/arm/mach-ux500/include/mach/setup.h
+++ b/arch/arm/mach-ux500/include/mach/setup.h
@@ -27,9 +27,6 @@ extern void __init u5500_sdi_init(void);
27 27
28extern void __init db5500_dma_init(void); 28extern void __init db5500_dma_init(void);
29 29
30/* We re-use nomadik_timer for this platform */
31extern void nmdk_timer_init(void);
32
33struct amba_device; 30struct amba_device;
34extern void __init amba_add_devices(struct amba_device *devs[], int num); 31extern void __init amba_add_devices(struct amba_device *devs[], int num);
35 32
diff --git a/arch/arm/mach-ux500/localtimer.c b/arch/arm/mach-ux500/localtimer.c
deleted file mode 100644
index 5ba113309a0b..000000000000
--- a/arch/arm/mach-ux500/localtimer.c
+++ /dev/null
@@ -1,29 +0,0 @@
1/*
2 * Copyright (C) 2008-2009 ST-Ericsson
3 * Srinidhi Kasagar <srinidhi.kasagar@stericsson.com>
4 *
5 * This file is heavily based on relaview platform, almost a copy.
6 *
7 * Copyright (C) 2002 ARM Ltd.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13#include <linux/init.h>
14#include <linux/smp.h>
15#include <linux/clockchips.h>
16
17#include <asm/irq.h>
18#include <asm/smp_twd.h>
19#include <asm/localtimer.h>
20
21/*
22 * Setup the local clock events for a CPU.
23 */
24int __cpuinit local_timer_setup(struct clock_event_device *evt)
25{
26 evt->irq = IRQ_LOCALTIMER;
27 twd_timer_setup(evt);
28 return 0;
29}
diff --git a/arch/arm/mach-ux500/timer.c b/arch/arm/mach-ux500/timer.c
index aea467d04ff7..e9d580702fbb 100644
--- a/arch/arm/mach-ux500/timer.c
+++ b/arch/arm/mach-ux500/timer.c
@@ -8,28 +8,46 @@
8#include <linux/errno.h> 8#include <linux/errno.h>
9#include <linux/clksrc-dbx500-prcmu.h> 9#include <linux/clksrc-dbx500-prcmu.h>
10 10
11#include <asm/localtimer.h> 11#include <asm/smp_twd.h>
12 12
13#include <plat/mtu.h> 13#include <plat/mtu.h>
14 14
15#include <mach/setup.h> 15#include <mach/setup.h>
16#include <mach/hardware.h> 16#include <mach/hardware.h>
17#include <mach/irqs.h>
18
19#ifdef CONFIG_HAVE_ARM_TWD
20static DEFINE_TWD_LOCAL_TIMER(u5500_twd_local_timer,
21 U5500_TWD_BASE, IRQ_LOCALTIMER);
22static DEFINE_TWD_LOCAL_TIMER(u8500_twd_local_timer,
23 U8500_TWD_BASE, IRQ_LOCALTIMER);
24
25static void __init ux500_twd_init(void)
26{
27 struct twd_local_timer *twd_local_timer;
28 int err;
29
30 twd_local_timer = cpu_is_u5500() ? &u5500_twd_local_timer :
31 &u8500_twd_local_timer;
32
33 err = twd_local_timer_register(twd_local_timer);
34 if (err)
35 pr_err("twd_local_timer_register failed %d\n", err);
36}
37#else
38#define ux500_twd_init() do { } while(0)
39#endif
17 40
18static void __init ux500_timer_init(void) 41static void __init ux500_timer_init(void)
19{ 42{
43 void __iomem *mtu_timer_base;
20 void __iomem *prcmu_timer_base; 44 void __iomem *prcmu_timer_base;
21 45
22 if (cpu_is_u5500()) { 46 if (cpu_is_u5500()) {
23#ifdef CONFIG_LOCAL_TIMERS 47 mtu_timer_base = __io_address(U5500_MTU0_BASE);
24 twd_base = __io_address(U5500_TWD_BASE);
25#endif
26 mtu_base = __io_address(U5500_MTU0_BASE);
27 prcmu_timer_base = __io_address(U5500_PRCMU_TIMER_3_BASE); 48 prcmu_timer_base = __io_address(U5500_PRCMU_TIMER_3_BASE);
28 } else if (cpu_is_u8500()) { 49 } else if (cpu_is_u8500()) {
29#ifdef CONFIG_LOCAL_TIMERS 50 mtu_timer_base = __io_address(U8500_MTU0_BASE);
30 twd_base = __io_address(U8500_TWD_BASE);
31#endif
32 mtu_base = __io_address(U8500_MTU0_BASE);
33 prcmu_timer_base = __io_address(U8500_PRCMU_TIMER_4_BASE); 51 prcmu_timer_base = __io_address(U8500_PRCMU_TIMER_4_BASE);
34 } else { 52 } else {
35 ux500_unknown_soc(); 53 ux500_unknown_soc();
@@ -52,8 +70,9 @@ static void __init ux500_timer_init(void)
52 * 70 *
53 */ 71 */
54 72
55 nmdk_timer_init(); 73 nmdk_timer_init(mtu_timer_base);
56 clksrc_dbx500_prcmu_init(prcmu_timer_base); 74 clksrc_dbx500_prcmu_init(prcmu_timer_base);
75 ux500_twd_init();
57} 76}
58 77
59static void ux500_timer_reset(void) 78static void ux500_timer_reset(void)
diff --git a/arch/arm/mach-vexpress/core.h b/arch/arm/mach-vexpress/core.h
index 9f0f2827c711..33c5a825aba1 100644
--- a/arch/arm/mach-vexpress/core.h
+++ b/arch/arm/mach-vexpress/core.h
@@ -1,2 +1,5 @@
1#define __MMIO_P2V(x) (((x) & 0xfffff) | (((x) & 0x0f000000) >> 4) | 0xf8000000) 1/* 2MB large area for motherboard's peripherals static mapping */
2#define MMIO_P2V(x) ((void __iomem *)__MMIO_P2V(x)) 2#define V2M_PERIPH 0xf8000000
3
4/* Tile's peripherals static mappings should start here */
5#define V2T_PERIPH 0xf8200000
diff --git a/arch/arm/mach-vexpress/ct-ca9x4.c b/arch/arm/mach-vexpress/ct-ca9x4.c
index 1b1d2e4892b9..c65cc3b462a5 100644
--- a/arch/arm/mach-vexpress/ct-ca9x4.c
+++ b/arch/arm/mach-vexpress/ct-ca9x4.c
@@ -30,57 +30,40 @@
30 30
31#include <plat/clcd.h> 31#include <plat/clcd.h>
32 32
33#define V2M_PA_CS7 0x10000000
34
35static struct map_desc ct_ca9x4_io_desc[] __initdata = { 33static struct map_desc ct_ca9x4_io_desc[] __initdata = {
36 { 34 {
37 .virtual = __MMIO_P2V(CT_CA9X4_MPIC), 35 .virtual = V2T_PERIPH,
38 .pfn = __phys_to_pfn(CT_CA9X4_MPIC), 36 .pfn = __phys_to_pfn(CT_CA9X4_MPIC),
39 .length = SZ_16K, 37 .length = SZ_8K,
40 .type = MT_DEVICE, 38 .type = MT_DEVICE,
41 }, {
42 .virtual = __MMIO_P2V(CT_CA9X4_SP804_TIMER),
43 .pfn = __phys_to_pfn(CT_CA9X4_SP804_TIMER),
44 .length = SZ_4K,
45 .type = MT_DEVICE,
46 }, {
47 .virtual = __MMIO_P2V(CT_CA9X4_L2CC),
48 .pfn = __phys_to_pfn(CT_CA9X4_L2CC),
49 .length = SZ_4K,
50 .type = MT_DEVICE,
51 }, 39 },
52}; 40};
53 41
54static void __init ct_ca9x4_map_io(void) 42static void __init ct_ca9x4_map_io(void)
55{ 43{
56#ifdef CONFIG_LOCAL_TIMERS
57 twd_base = MMIO_P2V(A9_MPCORE_TWD);
58#endif
59 iotable_init(ct_ca9x4_io_desc, ARRAY_SIZE(ct_ca9x4_io_desc)); 44 iotable_init(ct_ca9x4_io_desc, ARRAY_SIZE(ct_ca9x4_io_desc));
60} 45}
61 46
62static void __init ct_ca9x4_init_irq(void) 47#ifdef CONFIG_HAVE_ARM_TWD
48static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, A9_MPCORE_TWD, IRQ_LOCALTIMER);
49
50static void __init ca9x4_twd_init(void)
63{ 51{
64 gic_init(0, 29, MMIO_P2V(A9_MPCORE_GIC_DIST), 52 int err = twd_local_timer_register(&twd_local_timer);
65 MMIO_P2V(A9_MPCORE_GIC_CPU)); 53 if (err)
54 pr_err("twd_local_timer_register failed %d\n", err);
66} 55}
56#else
57#define ca9x4_twd_init() do {} while(0)
58#endif
67 59
68#if 0 60static void __init ct_ca9x4_init_irq(void)
69static void __init ct_ca9x4_timer_init(void)
70{ 61{
71 writel(0, MMIO_P2V(CT_CA9X4_TIMER0) + TIMER_CTRL); 62 gic_init(0, 29, ioremap(A9_MPCORE_GIC_DIST, SZ_4K),
72 writel(0, MMIO_P2V(CT_CA9X4_TIMER1) + TIMER_CTRL); 63 ioremap(A9_MPCORE_GIC_CPU, SZ_256));
73 64 ca9x4_twd_init();
74 sp804_clocksource_init(MMIO_P2V(CT_CA9X4_TIMER1), "ct-timer1");
75 sp804_clockevents_init(MMIO_P2V(CT_CA9X4_TIMER0), IRQ_CT_CA9X4_TIMER0,
76 "ct-timer0");
77} 65}
78 66
79static struct sys_timer ct_ca9x4_timer = {
80 .init = ct_ca9x4_timer_init,
81};
82#endif
83
84static void ct_ca9x4_clcd_enable(struct clcd_fb *fb) 67static void ct_ca9x4_clcd_enable(struct clcd_fb *fb)
85{ 68{
86 v2m_cfg_write(SYS_CFG_MUXFPGA | SYS_CFG_SITE_DB1, 0); 69 v2m_cfg_write(SYS_CFG_MUXFPGA | SYS_CFG_SITE_DB1, 0);
@@ -201,7 +184,7 @@ static void __init ct_ca9x4_init(void)
201 int i; 184 int i;
202 185
203#ifdef CONFIG_CACHE_L2X0 186#ifdef CONFIG_CACHE_L2X0
204 void __iomem *l2x0_base = MMIO_P2V(CT_CA9X4_L2CC); 187 void __iomem *l2x0_base = ioremap(CT_CA9X4_L2CC, SZ_4K);
205 188
206 /* set RAM latencies to 1 cycle for this core tile. */ 189 /* set RAM latencies to 1 cycle for this core tile. */
207 writel(0, l2x0_base + L2X0_TAG_LATENCY_CTRL); 190 writel(0, l2x0_base + L2X0_TAG_LATENCY_CTRL);
@@ -217,9 +200,17 @@ static void __init ct_ca9x4_init(void)
217} 200}
218 201
219#ifdef CONFIG_SMP 202#ifdef CONFIG_SMP
203static void *ct_ca9x4_scu_base __initdata;
204
220static void __init ct_ca9x4_init_cpu_map(void) 205static void __init ct_ca9x4_init_cpu_map(void)
221{ 206{
222 int i, ncores = scu_get_core_count(MMIO_P2V(A9_MPCORE_SCU)); 207 int i, ncores;
208
209 ct_ca9x4_scu_base = ioremap(A9_MPCORE_SCU, SZ_128);
210 if (WARN_ON(!ct_ca9x4_scu_base))
211 return;
212
213 ncores = scu_get_core_count(ct_ca9x4_scu_base);
223 214
224 if (ncores > nr_cpu_ids) { 215 if (ncores > nr_cpu_ids) {
225 pr_warn("SMP: %u cores greater than maximum (%u), clipping\n", 216 pr_warn("SMP: %u cores greater than maximum (%u), clipping\n",
@@ -235,7 +226,7 @@ static void __init ct_ca9x4_init_cpu_map(void)
235 226
236static void __init ct_ca9x4_smp_enable(unsigned int max_cpus) 227static void __init ct_ca9x4_smp_enable(unsigned int max_cpus)
237{ 228{
238 scu_enable(MMIO_P2V(A9_MPCORE_SCU)); 229 scu_enable(ct_ca9x4_scu_base);
239} 230}
240#endif 231#endif
241 232
diff --git a/arch/arm/mach-vexpress/include/mach/ct-ca9x4.h b/arch/arm/mach-vexpress/include/mach/ct-ca9x4.h
index a40468f3b938..84acf8439d4b 100644
--- a/arch/arm/mach-vexpress/include/mach/ct-ca9x4.h
+++ b/arch/arm/mach-vexpress/include/mach/ct-ca9x4.h
@@ -22,9 +22,6 @@
22#define CT_CA9X4_SYSWDT (0x1e007000) 22#define CT_CA9X4_SYSWDT (0x1e007000)
23#define CT_CA9X4_L2CC (0x1e00a000) 23#define CT_CA9X4_L2CC (0x1e00a000)
24 24
25#define CT_CA9X4_TIMER0 (CT_CA9X4_SP804_TIMER + 0x000)
26#define CT_CA9X4_TIMER1 (CT_CA9X4_SP804_TIMER + 0x020)
27
28#define A9_MPCORE_SCU (CT_CA9X4_MPIC + 0x0000) 25#define A9_MPCORE_SCU (CT_CA9X4_MPIC + 0x0000)
29#define A9_MPCORE_GIC_CPU (CT_CA9X4_MPIC + 0x0100) 26#define A9_MPCORE_GIC_CPU (CT_CA9X4_MPIC + 0x0100)
30#define A9_MPCORE_GIT (CT_CA9X4_MPIC + 0x0200) 27#define A9_MPCORE_GIT (CT_CA9X4_MPIC + 0x0200)
diff --git a/arch/arm/mach-vexpress/include/mach/motherboard.h b/arch/arm/mach-vexpress/include/mach/motherboard.h
index 0a3a37518405..b4c498c1dbee 100644
--- a/arch/arm/mach-vexpress/include/mach/motherboard.h
+++ b/arch/arm/mach-vexpress/include/mach/motherboard.h
@@ -39,33 +39,30 @@
39#define V2M_CF (V2M_PA_CS7 + 0x0001a000) 39#define V2M_CF (V2M_PA_CS7 + 0x0001a000)
40#define V2M_CLCD (V2M_PA_CS7 + 0x0001f000) 40#define V2M_CLCD (V2M_PA_CS7 + 0x0001f000)
41 41
42#define V2M_SYS_ID (V2M_SYSREGS + 0x000) 42/*
43#define V2M_SYS_SW (V2M_SYSREGS + 0x004) 43 * Offsets from SYSREGS base
44#define V2M_SYS_LED (V2M_SYSREGS + 0x008) 44 */
45#define V2M_SYS_100HZ (V2M_SYSREGS + 0x024) 45#define V2M_SYS_ID 0x000
46#define V2M_SYS_FLAGS (V2M_SYSREGS + 0x030) 46#define V2M_SYS_SW 0x004
47#define V2M_SYS_FLAGSSET (V2M_SYSREGS + 0x030) 47#define V2M_SYS_LED 0x008
48#define V2M_SYS_FLAGSCLR (V2M_SYSREGS + 0x034) 48#define V2M_SYS_100HZ 0x024
49#define V2M_SYS_NVFLAGS (V2M_SYSREGS + 0x038) 49#define V2M_SYS_FLAGS 0x030
50#define V2M_SYS_NVFLAGSSET (V2M_SYSREGS + 0x038) 50#define V2M_SYS_FLAGSSET 0x030
51#define V2M_SYS_NVFLAGSCLR (V2M_SYSREGS + 0x03c) 51#define V2M_SYS_FLAGSCLR 0x034
52#define V2M_SYS_MCI (V2M_SYSREGS + 0x048) 52#define V2M_SYS_NVFLAGS 0x038
53#define V2M_SYS_FLASH (V2M_SYSREGS + 0x03c) 53#define V2M_SYS_NVFLAGSSET 0x038
54#define V2M_SYS_CFGSW (V2M_SYSREGS + 0x058) 54#define V2M_SYS_NVFLAGSCLR 0x03c
55#define V2M_SYS_24MHZ (V2M_SYSREGS + 0x05c) 55#define V2M_SYS_MCI 0x048
56#define V2M_SYS_MISC (V2M_SYSREGS + 0x060) 56#define V2M_SYS_FLASH 0x03c
57#define V2M_SYS_DMA (V2M_SYSREGS + 0x064) 57#define V2M_SYS_CFGSW 0x058
58#define V2M_SYS_PROCID0 (V2M_SYSREGS + 0x084) 58#define V2M_SYS_24MHZ 0x05c
59#define V2M_SYS_PROCID1 (V2M_SYSREGS + 0x088) 59#define V2M_SYS_MISC 0x060
60#define V2M_SYS_CFGDATA (V2M_SYSREGS + 0x0a0) 60#define V2M_SYS_DMA 0x064
61#define V2M_SYS_CFGCTRL (V2M_SYSREGS + 0x0a4) 61#define V2M_SYS_PROCID0 0x084
62#define V2M_SYS_CFGSTAT (V2M_SYSREGS + 0x0a8) 62#define V2M_SYS_PROCID1 0x088
63 63#define V2M_SYS_CFGDATA 0x0a0
64#define V2M_TIMER0 (V2M_TIMER01 + 0x000) 64#define V2M_SYS_CFGCTRL 0x0a4
65#define V2M_TIMER1 (V2M_TIMER01 + 0x020) 65#define V2M_SYS_CFGSTAT 0x0a8
66
67#define V2M_TIMER2 (V2M_TIMER23 + 0x000)
68#define V2M_TIMER3 (V2M_TIMER23 + 0x020)
69 66
70 67
71/* 68/*
@@ -117,6 +114,7 @@
117 114
118int v2m_cfg_write(u32 devfn, u32 data); 115int v2m_cfg_write(u32 devfn, u32 data);
119int v2m_cfg_read(u32 devfn, u32 *data); 116int v2m_cfg_read(u32 devfn, u32 *data);
117void v2m_flags_set(u32 data);
120 118
121/* 119/*
122 * Core tile IDs 120 * Core tile IDs
diff --git a/arch/arm/mach-vexpress/platsmp.c b/arch/arm/mach-vexpress/platsmp.c
index 124ffb169093..a1ed6d68597d 100644
--- a/arch/arm/mach-vexpress/platsmp.c
+++ b/arch/arm/mach-vexpress/platsmp.c
@@ -14,7 +14,6 @@
14#include <linux/io.h> 14#include <linux/io.h>
15 15
16#include <mach/motherboard.h> 16#include <mach/motherboard.h>
17#define V2M_PA_CS7 0x10000000
18 17
19#include "core.h" 18#include "core.h"
20 19
@@ -43,7 +42,5 @@ void __init platform_smp_prepare_cpus(unsigned int max_cpus)
43 * until it receives a soft interrupt, and then the 42 * until it receives a soft interrupt, and then the
44 * secondary CPU branches to this address. 43 * secondary CPU branches to this address.
45 */ 44 */
46 writel(~0, MMIO_P2V(V2M_SYS_FLAGSCLR)); 45 v2m_flags_set(virt_to_phys(versatile_secondary_startup));
47 writel(virt_to_phys(versatile_secondary_startup),
48 MMIO_P2V(V2M_SYS_FLAGSSET));
49} 46}
diff --git a/arch/arm/mach-vexpress/v2m.c b/arch/arm/mach-vexpress/v2m.c
index ad64f97a2003..663a98831920 100644
--- a/arch/arm/mach-vexpress/v2m.c
+++ b/arch/arm/mach-vexpress/v2m.c
@@ -40,29 +40,45 @@
40 40
41static struct map_desc v2m_io_desc[] __initdata = { 41static struct map_desc v2m_io_desc[] __initdata = {
42 { 42 {
43 .virtual = __MMIO_P2V(V2M_PA_CS7), 43 .virtual = V2M_PERIPH,
44 .pfn = __phys_to_pfn(V2M_PA_CS7), 44 .pfn = __phys_to_pfn(V2M_PA_CS7),
45 .length = SZ_128K, 45 .length = SZ_128K,
46 .type = MT_DEVICE, 46 .type = MT_DEVICE,
47 }, 47 },
48}; 48};
49 49
50static void __init v2m_timer_init(void) 50static void __iomem *v2m_sysreg_base;
51
52static void __init v2m_sysctl_init(void __iomem *base)
51{ 53{
52 u32 scctrl; 54 u32 scctrl;
53 55
56 if (WARN_ON(!base))
57 return;
58
54 /* Select 1MHz TIMCLK as the reference clock for SP804 timers */ 59 /* Select 1MHz TIMCLK as the reference clock for SP804 timers */
55 scctrl = readl(MMIO_P2V(V2M_SYSCTL + SCCTRL)); 60 scctrl = readl(base + SCCTRL);
56 scctrl |= SCCTRL_TIMEREN0SEL_TIMCLK; 61 scctrl |= SCCTRL_TIMEREN0SEL_TIMCLK;
57 scctrl |= SCCTRL_TIMEREN1SEL_TIMCLK; 62 scctrl |= SCCTRL_TIMEREN1SEL_TIMCLK;
58 writel(scctrl, MMIO_P2V(V2M_SYSCTL + SCCTRL)); 63 writel(scctrl, base + SCCTRL);
64}
59 65
60 writel(0, MMIO_P2V(V2M_TIMER0) + TIMER_CTRL); 66static void __init v2m_sp804_init(void __iomem *base, unsigned int irq)
61 writel(0, MMIO_P2V(V2M_TIMER1) + TIMER_CTRL); 67{
68 if (WARN_ON(!base || irq == NO_IRQ))
69 return;
70
71 writel(0, base + TIMER_1_BASE + TIMER_CTRL);
72 writel(0, base + TIMER_2_BASE + TIMER_CTRL);
62 73
63 sp804_clocksource_init(MMIO_P2V(V2M_TIMER1), "v2m-timer1"); 74 sp804_clocksource_init(base + TIMER_2_BASE, "v2m-timer1");
64 sp804_clockevents_init(MMIO_P2V(V2M_TIMER0), IRQ_V2M_TIMER0, 75 sp804_clockevents_init(base + TIMER_1_BASE, irq, "v2m-timer0");
65 "v2m-timer0"); 76}
77
78static void __init v2m_timer_init(void)
79{
80 v2m_sysctl_init(ioremap(V2M_SYSCTL, SZ_4K));
81 v2m_sp804_init(ioremap(V2M_TIMER01, SZ_4K), IRQ_V2M_TIMER0);
66} 82}
67 83
68static struct sys_timer v2m_timer = { 84static struct sys_timer v2m_timer = {
@@ -82,14 +98,14 @@ int v2m_cfg_write(u32 devfn, u32 data)
82 devfn |= SYS_CFG_START | SYS_CFG_WRITE; 98 devfn |= SYS_CFG_START | SYS_CFG_WRITE;
83 99
84 spin_lock(&v2m_cfg_lock); 100 spin_lock(&v2m_cfg_lock);
85 val = readl(MMIO_P2V(V2M_SYS_CFGSTAT)); 101 val = readl(v2m_sysreg_base + V2M_SYS_CFGSTAT);
86 writel(val & ~SYS_CFG_COMPLETE, MMIO_P2V(V2M_SYS_CFGSTAT)); 102 writel(val & ~SYS_CFG_COMPLETE, v2m_sysreg_base + V2M_SYS_CFGSTAT);
87 103
88 writel(data, MMIO_P2V(V2M_SYS_CFGDATA)); 104 writel(data, v2m_sysreg_base + V2M_SYS_CFGDATA);
89 writel(devfn, MMIO_P2V(V2M_SYS_CFGCTRL)); 105 writel(devfn, v2m_sysreg_base + V2M_SYS_CFGCTRL);
90 106
91 do { 107 do {
92 val = readl(MMIO_P2V(V2M_SYS_CFGSTAT)); 108 val = readl(v2m_sysreg_base + V2M_SYS_CFGSTAT);
93 } while (val == 0); 109 } while (val == 0);
94 spin_unlock(&v2m_cfg_lock); 110 spin_unlock(&v2m_cfg_lock);
95 111
@@ -103,22 +119,28 @@ int v2m_cfg_read(u32 devfn, u32 *data)
103 devfn |= SYS_CFG_START; 119 devfn |= SYS_CFG_START;
104 120
105 spin_lock(&v2m_cfg_lock); 121 spin_lock(&v2m_cfg_lock);
106 writel(0, MMIO_P2V(V2M_SYS_CFGSTAT)); 122 writel(0, v2m_sysreg_base + V2M_SYS_CFGSTAT);
107 writel(devfn, MMIO_P2V(V2M_SYS_CFGCTRL)); 123 writel(devfn, v2m_sysreg_base + V2M_SYS_CFGCTRL);
108 124
109 mb(); 125 mb();
110 126
111 do { 127 do {
112 cpu_relax(); 128 cpu_relax();
113 val = readl(MMIO_P2V(V2M_SYS_CFGSTAT)); 129 val = readl(v2m_sysreg_base + V2M_SYS_CFGSTAT);
114 } while (val == 0); 130 } while (val == 0);
115 131
116 *data = readl(MMIO_P2V(V2M_SYS_CFGDATA)); 132 *data = readl(v2m_sysreg_base + V2M_SYS_CFGDATA);
117 spin_unlock(&v2m_cfg_lock); 133 spin_unlock(&v2m_cfg_lock);
118 134
119 return !!(val & SYS_CFG_ERR); 135 return !!(val & SYS_CFG_ERR);
120} 136}
121 137
138void __init v2m_flags_set(u32 data)
139{
140 writel(~0, v2m_sysreg_base + V2M_SYS_FLAGSCLR);
141 writel(data, v2m_sysreg_base + V2M_SYS_FLAGSSET);
142}
143
122 144
123static struct resource v2m_pcie_i2c_resource = { 145static struct resource v2m_pcie_i2c_resource = {
124 .start = V2M_SERIAL_BUS_PCI, 146 .start = V2M_SERIAL_BUS_PCI,
@@ -204,7 +226,7 @@ static struct platform_device v2m_usb_device = {
204 226
205static void v2m_flash_set_vpp(struct platform_device *pdev, int on) 227static void v2m_flash_set_vpp(struct platform_device *pdev, int on)
206{ 228{
207 writel(on != 0, MMIO_P2V(V2M_SYS_FLASH)); 229 writel(on != 0, v2m_sysreg_base + V2M_SYS_FLASH);
208} 230}
209 231
210static struct physmap_flash_data v2m_flash_data = { 232static struct physmap_flash_data v2m_flash_data = {
@@ -258,7 +280,7 @@ static struct platform_device v2m_cf_device = {
258 280
259static unsigned int v2m_mmci_status(struct device *dev) 281static unsigned int v2m_mmci_status(struct device *dev)
260{ 282{
261 return readl(MMIO_P2V(V2M_SYS_MCI)) & (1 << 0); 283 return readl(v2m_sysreg_base + V2M_SYS_MCI) & (1 << 0);
262} 284}
263 285
264static struct mmci_platform_data v2m_mmci_data = { 286static struct mmci_platform_data v2m_mmci_data = {
@@ -371,7 +393,7 @@ static void __init v2m_init_early(void)
371{ 393{
372 ct_desc->init_early(); 394 ct_desc->init_early();
373 clkdev_add_table(v2m_lookups, ARRAY_SIZE(v2m_lookups)); 395 clkdev_add_table(v2m_lookups, ARRAY_SIZE(v2m_lookups));
374 versatile_sched_clock_init(MMIO_P2V(V2M_SYS_24MHZ), 24000000); 396 versatile_sched_clock_init(v2m_sysreg_base + V2M_SYS_24MHZ, 24000000);
375} 397}
376 398
377static void v2m_power_off(void) 399static void v2m_power_off(void)
@@ -400,7 +422,8 @@ static void __init v2m_populate_ct_desc(void)
400 u32 current_tile_id; 422 u32 current_tile_id;
401 423
402 ct_desc = NULL; 424 ct_desc = NULL;
403 current_tile_id = readl(MMIO_P2V(V2M_SYS_PROCID0)) & V2M_CT_ID_MASK; 425 current_tile_id = readl(v2m_sysreg_base + V2M_SYS_PROCID0)
426 & V2M_CT_ID_MASK;
404 427
405 for (i = 0; i < ARRAY_SIZE(ct_descs) && !ct_desc; ++i) 428 for (i = 0; i < ARRAY_SIZE(ct_descs) && !ct_desc; ++i)
406 if (ct_descs[i]->id == current_tile_id) 429 if (ct_descs[i]->id == current_tile_id)
@@ -414,6 +437,7 @@ static void __init v2m_populate_ct_desc(void)
414static void __init v2m_map_io(void) 437static void __init v2m_map_io(void)
415{ 438{
416 iotable_init(v2m_io_desc, ARRAY_SIZE(v2m_io_desc)); 439 iotable_init(v2m_io_desc, ARRAY_SIZE(v2m_io_desc));
440 v2m_sysreg_base = ioremap(V2M_SYSREGS, SZ_4K);
417 v2m_populate_ct_desc(); 441 v2m_populate_ct_desc();
418 ct_desc->map_io(); 442 ct_desc->map_io();
419} 443}
diff --git a/arch/arm/plat-nomadik/include/plat/mtu.h b/arch/arm/plat-nomadik/include/plat/mtu.h
index 6508e7694a4b..582641f3dc01 100644
--- a/arch/arm/plat-nomadik/include/plat/mtu.h
+++ b/arch/arm/plat-nomadik/include/plat/mtu.h
@@ -1,9 +1,7 @@
1#ifndef __PLAT_MTU_H 1#ifndef __PLAT_MTU_H
2#define __PLAT_MTU_H 2#define __PLAT_MTU_H
3 3
4/* should be set by the platform code */ 4void nmdk_timer_init(void __iomem *base);
5extern void __iomem *mtu_base;
6
7void nmdk_clkevt_reset(void); 5void nmdk_clkevt_reset(void);
8void nmdk_clksrc_reset(void); 6void nmdk_clksrc_reset(void);
9 7
diff --git a/arch/arm/plat-nomadik/timer.c b/arch/arm/plat-nomadik/timer.c
index ad1b45b605a4..9222e5522a43 100644
--- a/arch/arm/plat-nomadik/timer.c
+++ b/arch/arm/plat-nomadik/timer.c
@@ -21,12 +21,6 @@
21#include <asm/sched_clock.h> 21#include <asm/sched_clock.h>
22 22
23/* 23/*
24 * Guaranteed runtime conversion range in seconds for
25 * the clocksource and clockevent.
26 */
27#define MTU_MIN_RANGE 4
28
29/*
30 * The MTU device hosts four different counters, with 4 set of 24 * The MTU device hosts four different counters, with 4 set of
31 * registers. These are register names. 25 * registers. These are register names.
32 */ 26 */
@@ -66,12 +60,11 @@
66#define MTU_PCELL2 0xff8 60#define MTU_PCELL2 0xff8
67#define MTU_PCELL3 0xffC 61#define MTU_PCELL3 0xffC
68 62
63static void __iomem *mtu_base;
69static bool clkevt_periodic; 64static bool clkevt_periodic;
70static u32 clk_prescale; 65static u32 clk_prescale;
71static u32 nmdk_cycle; /* write-once */ 66static u32 nmdk_cycle; /* write-once */
72 67
73void __iomem *mtu_base; /* Assigned by machine code */
74
75#ifdef CONFIG_NOMADIK_MTU_SCHED_CLOCK 68#ifdef CONFIG_NOMADIK_MTU_SCHED_CLOCK
76/* 69/*
77 * Override the global weak sched_clock symbol with this 70 * Override the global weak sched_clock symbol with this
@@ -103,7 +96,6 @@ static int nmdk_clkevt_next(unsigned long evt, struct clock_event_device *ev)
103void nmdk_clkevt_reset(void) 96void nmdk_clkevt_reset(void)
104{ 97{
105 if (clkevt_periodic) { 98 if (clkevt_periodic) {
106
107 /* Timer: configure load and background-load, and fire it up */ 99 /* Timer: configure load and background-load, and fire it up */
108 writel(nmdk_cycle, mtu_base + MTU_LR(1)); 100 writel(nmdk_cycle, mtu_base + MTU_LR(1));
109 writel(nmdk_cycle, mtu_base + MTU_BGLR(1)); 101 writel(nmdk_cycle, mtu_base + MTU_BGLR(1));
@@ -121,7 +113,6 @@ void nmdk_clkevt_reset(void)
121static void nmdk_clkevt_mode(enum clock_event_mode mode, 113static void nmdk_clkevt_mode(enum clock_event_mode mode,
122 struct clock_event_device *dev) 114 struct clock_event_device *dev)
123{ 115{
124
125 switch (mode) { 116 switch (mode) {
126 case CLOCK_EVT_MODE_PERIODIC: 117 case CLOCK_EVT_MODE_PERIODIC:
127 clkevt_periodic = true; 118 clkevt_periodic = true;
@@ -183,15 +174,16 @@ void nmdk_clksrc_reset(void)
183 mtu_base + MTU_CR(0)); 174 mtu_base + MTU_CR(0));
184} 175}
185 176
186void __init nmdk_timer_init(void) 177void __init nmdk_timer_init(void __iomem *base)
187{ 178{
188 unsigned long rate; 179 unsigned long rate;
189 struct clk *clk0; 180 struct clk *clk0;
190 181
182 mtu_base = base;
191 clk0 = clk_get_sys("mtu0", NULL); 183 clk0 = clk_get_sys("mtu0", NULL);
192 BUG_ON(IS_ERR(clk0)); 184 BUG_ON(IS_ERR(clk0));
193 185 BUG_ON(clk_prepare(clk0) < 0);
194 clk_enable(clk0); 186 BUG_ON(clk_enable(clk0) < 0);
195 187
196 /* 188 /*
197 * Tick rate is 2.4MHz for Nomadik and 2.4Mhz, 100MHz or 133 MHz 189 * Tick rate is 2.4MHz for Nomadik and 2.4Mhz, 100MHz or 133 MHz
@@ -224,17 +216,8 @@ void __init nmdk_timer_init(void)
224 setup_sched_clock(nomadik_read_sched_clock, 32, rate); 216 setup_sched_clock(nomadik_read_sched_clock, 32, rate);
225#endif 217#endif
226 218
227 /* Timer 1 is used for events */ 219 /* Timer 1 is used for events, register irq and clockevents */
228
229 clockevents_calc_mult_shift(&nmdk_clkevt, rate, MTU_MIN_RANGE);
230
231 nmdk_clkevt.max_delta_ns =
232 clockevent_delta2ns(0xffffffff, &nmdk_clkevt);
233 nmdk_clkevt.min_delta_ns =
234 clockevent_delta2ns(0x00000002, &nmdk_clkevt);
235 nmdk_clkevt.cpumask = cpumask_of(0);
236
237 /* Register irq and clockevents */
238 setup_irq(IRQ_MTU0, &nmdk_timer_irq); 220 setup_irq(IRQ_MTU0, &nmdk_timer_irq);
239 clockevents_register_device(&nmdk_clkevt); 221 nmdk_clkevt.cpumask = cpumask_of(0);
222 clockevents_config_and_register(&nmdk_clkevt, rate, 2, 0xffffffffU);
240} 223}
diff --git a/arch/arm/plat-versatile/Makefile b/arch/arm/plat-versatile/Makefile
index 69714db47c33..a5cb1945bdcc 100644
--- a/arch/arm/plat-versatile/Makefile
+++ b/arch/arm/plat-versatile/Makefile
@@ -1,5 +1,4 @@
1obj-y := clock.o 1obj-y := clock.o
2obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o
3obj-$(CONFIG_PLAT_VERSATILE_CLCD) += clcd.o 2obj-$(CONFIG_PLAT_VERSATILE_CLCD) += clcd.o
4obj-$(CONFIG_PLAT_VERSATILE_FPGA_IRQ) += fpga-irq.o 3obj-$(CONFIG_PLAT_VERSATILE_FPGA_IRQ) += fpga-irq.o
5obj-$(CONFIG_PLAT_VERSATILE_LEDS) += leds.o 4obj-$(CONFIG_PLAT_VERSATILE_LEDS) += leds.o
diff --git a/arch/arm/plat-versatile/localtimer.c b/arch/arm/plat-versatile/localtimer.c
deleted file mode 100644
index 0fb3961999b5..000000000000
--- a/arch/arm/plat-versatile/localtimer.c
+++ /dev/null
@@ -1,27 +0,0 @@
1/*
2 * linux/arch/arm/plat-versatile/localtimer.c
3 *
4 * Copyright (C) 2002 ARM Ltd.
5 * All Rights Reserved
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#include <linux/init.h>
12#include <linux/smp.h>
13#include <linux/clockchips.h>
14
15#include <asm/smp_twd.h>
16#include <asm/localtimer.h>
17#include <mach/irqs.h>
18
19/*
20 * Setup the local clock events for a CPU.
21 */
22int __cpuinit local_timer_setup(struct clock_event_device *evt)
23{
24 evt->irq = IRQ_LOCALTIMER;
25 twd_timer_setup(evt);
26 return 0;
27}