diff options
author | Arnd Bergmann <arnd@arndb.de> | 2013-04-08 12:34:19 -0400 |
---|---|---|
committer | Arnd Bergmann <arnd@arndb.de> | 2013-04-08 12:34:19 -0400 |
commit | 6b5606e0834bb173a8ce3505edec078f135e9f6c (patch) | |
tree | 9f3bdc09be01e14fb68368b1c111a04cc570518f /arch | |
parent | e9069cf8b74b50d804fd540a9fd1383504f4af93 (diff) | |
parent | 4f0f234fce1d263cc9881456352e8fd56ead0514 (diff) |
Merge branch 'zynq/clksrc/cleanup' of git://git.xilinx.com/linux-xlnx into next/drivers
From Michal Simek <michal.simek@xilinx.com>:
* 'zynq/clksrc/cleanup' of git://git.xilinx.com/linux-xlnx:
arm: zynq: Move timer to generic location
arm: zynq: Do not use xilinx specific function names
arm: zynq: Move timer to clocksource interface
arm: zynq: Use standard timer binding
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/Kconfig | 1 | ||||
-rw-r--r-- | arch/arm/boot/dts/zynq-7000.dtsi | 45 | ||||
-rw-r--r-- | arch/arm/boot/dts/zynq-zc702.dts | 10 | ||||
-rw-r--r-- | arch/arm/include/asm/smp_twd.h | 8 | ||||
-rw-r--r-- | arch/arm/kernel/smp_twd.c | 17 | ||||
-rw-r--r-- | arch/arm/mach-highbank/highbank.c | 5 | ||||
-rw-r--r-- | arch/arm/mach-imx/mach-imx6q.c | 5 | ||||
-rw-r--r-- | arch/arm/mach-omap2/timer.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-spear13xx/spear13xx.c | 4 | ||||
-rw-r--r-- | arch/arm/mach-ux500/timer.c | 3 | ||||
-rw-r--r-- | arch/arm/mach-vexpress/v2m.c | 6 | ||||
-rw-r--r-- | arch/arm/mach-zynq/Kconfig | 1 | ||||
-rw-r--r-- | arch/arm/mach-zynq/Makefile | 2 | ||||
-rw-r--r-- | arch/arm/mach-zynq/common.c | 3 | ||||
-rw-r--r-- | arch/arm/mach-zynq/common.h | 2 | ||||
-rw-r--r-- | arch/arm/mach-zynq/timer.c | 324 |
16 files changed, 27 insertions, 411 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index c6a82c74fcbb..eb91022b90ba 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
@@ -1598,6 +1598,7 @@ config HAVE_ARM_ARCH_TIMER | |||
1598 | config HAVE_ARM_TWD | 1598 | config HAVE_ARM_TWD |
1599 | bool | 1599 | bool |
1600 | depends on SMP | 1600 | depends on SMP |
1601 | select CLKSRC_OF if OF | ||
1601 | help | 1602 | help |
1602 | This options enables support for the ARM timer and watchdog unit | 1603 | This options enables support for the ARM timer and watchdog unit |
1603 | 1604 | ||
diff --git a/arch/arm/boot/dts/zynq-7000.dtsi b/arch/arm/boot/dts/zynq-7000.dtsi index 5914b5654591..51243db2e9e4 100644 --- a/arch/arm/boot/dts/zynq-7000.dtsi +++ b/arch/arm/boot/dts/zynq-7000.dtsi | |||
@@ -111,56 +111,23 @@ | |||
111 | }; | 111 | }; |
112 | 112 | ||
113 | ttc0: ttc0@f8001000 { | 113 | ttc0: ttc0@f8001000 { |
114 | #address-cells = <1>; | 114 | interrupt-parent = <&intc>; |
115 | #size-cells = <0>; | 115 | interrupts = < 0 10 4 0 11 4 0 12 4 >; |
116 | compatible = "xlnx,ttc"; | 116 | compatible = "cdns,ttc"; |
117 | reg = <0xF8001000 0x1000>; | 117 | reg = <0xF8001000 0x1000>; |
118 | clocks = <&cpu_clk 3>; | 118 | clocks = <&cpu_clk 3>; |
119 | clock-names = "cpu_1x"; | 119 | clock-names = "cpu_1x"; |
120 | clock-ranges; | 120 | clock-ranges; |
121 | |||
122 | ttc0_0: ttc0.0 { | ||
123 | status = "disabled"; | ||
124 | reg = <0>; | ||
125 | interrupts = <0 10 4>; | ||
126 | }; | ||
127 | ttc0_1: ttc0.1 { | ||
128 | status = "disabled"; | ||
129 | reg = <1>; | ||
130 | interrupts = <0 11 4>; | ||
131 | }; | ||
132 | ttc0_2: ttc0.2 { | ||
133 | status = "disabled"; | ||
134 | reg = <2>; | ||
135 | interrupts = <0 12 4>; | ||
136 | }; | ||
137 | }; | 121 | }; |
138 | 122 | ||
139 | ttc1: ttc1@f8002000 { | 123 | ttc1: ttc1@f8002000 { |
140 | #interrupt-parent = <&intc>; | 124 | interrupt-parent = <&intc>; |
141 | #address-cells = <1>; | 125 | interrupts = < 0 37 4 0 38 4 0 39 4 >; |
142 | #size-cells = <0>; | 126 | compatible = "cdns,ttc"; |
143 | compatible = "xlnx,ttc"; | ||
144 | reg = <0xF8002000 0x1000>; | 127 | reg = <0xF8002000 0x1000>; |
145 | clocks = <&cpu_clk 3>; | 128 | clocks = <&cpu_clk 3>; |
146 | clock-names = "cpu_1x"; | 129 | clock-names = "cpu_1x"; |
147 | clock-ranges; | 130 | clock-ranges; |
148 | |||
149 | ttc1_0: ttc1.0 { | ||
150 | status = "disabled"; | ||
151 | reg = <0>; | ||
152 | interrupts = <0 37 4>; | ||
153 | }; | ||
154 | ttc1_1: ttc1.1 { | ||
155 | status = "disabled"; | ||
156 | reg = <1>; | ||
157 | interrupts = <0 38 4>; | ||
158 | }; | ||
159 | ttc1_2: ttc1.2 { | ||
160 | status = "disabled"; | ||
161 | reg = <2>; | ||
162 | interrupts = <0 39 4>; | ||
163 | }; | ||
164 | }; | 131 | }; |
165 | }; | 132 | }; |
166 | }; | 133 | }; |
diff --git a/arch/arm/boot/dts/zynq-zc702.dts b/arch/arm/boot/dts/zynq-zc702.dts index c772942a399a..86f44d5b0265 100644 --- a/arch/arm/boot/dts/zynq-zc702.dts +++ b/arch/arm/boot/dts/zynq-zc702.dts | |||
@@ -32,13 +32,3 @@ | |||
32 | &ps_clk { | 32 | &ps_clk { |
33 | clock-frequency = <33333330>; | 33 | clock-frequency = <33333330>; |
34 | }; | 34 | }; |
35 | |||
36 | &ttc0_0 { | ||
37 | status = "ok"; | ||
38 | compatible = "xlnx,ttc-counter-clocksource"; | ||
39 | }; | ||
40 | |||
41 | &ttc0_1 { | ||
42 | status = "ok"; | ||
43 | compatible = "xlnx,ttc-counter-clockevent"; | ||
44 | }; | ||
diff --git a/arch/arm/include/asm/smp_twd.h b/arch/arm/include/asm/smp_twd.h index 0f01f4677bd2..7b2899c2f7fc 100644 --- a/arch/arm/include/asm/smp_twd.h +++ b/arch/arm/include/asm/smp_twd.h | |||
@@ -34,12 +34,4 @@ struct twd_local_timer name __initdata = { \ | |||
34 | 34 | ||
35 | int twd_local_timer_register(struct twd_local_timer *); | 35 | int twd_local_timer_register(struct twd_local_timer *); |
36 | 36 | ||
37 | #ifdef CONFIG_HAVE_ARM_TWD | ||
38 | void twd_local_timer_of_register(void); | ||
39 | #else | ||
40 | static inline void twd_local_timer_of_register(void) | ||
41 | { | ||
42 | } | ||
43 | #endif | ||
44 | |||
45 | #endif | 37 | #endif |
diff --git a/arch/arm/kernel/smp_twd.c b/arch/arm/kernel/smp_twd.c index 3f2565037480..90525d9d290b 100644 --- a/arch/arm/kernel/smp_twd.c +++ b/arch/arm/kernel/smp_twd.c | |||
@@ -362,25 +362,13 @@ int __init twd_local_timer_register(struct twd_local_timer *tlt) | |||
362 | } | 362 | } |
363 | 363 | ||
364 | #ifdef CONFIG_OF | 364 | #ifdef CONFIG_OF |
365 | const static struct of_device_id twd_of_match[] __initconst = { | 365 | static void __init twd_local_timer_of_register(struct device_node *np) |
366 | { .compatible = "arm,cortex-a9-twd-timer", }, | ||
367 | { .compatible = "arm,cortex-a5-twd-timer", }, | ||
368 | { .compatible = "arm,arm11mp-twd-timer", }, | ||
369 | { }, | ||
370 | }; | ||
371 | |||
372 | void __init twd_local_timer_of_register(void) | ||
373 | { | 366 | { |
374 | struct device_node *np; | ||
375 | int err; | 367 | int err; |
376 | 368 | ||
377 | if (!is_smp() || !setup_max_cpus) | 369 | if (!is_smp() || !setup_max_cpus) |
378 | return; | 370 | return; |
379 | 371 | ||
380 | np = of_find_matching_node(NULL, twd_of_match); | ||
381 | if (!np) | ||
382 | return; | ||
383 | |||
384 | twd_ppi = irq_of_parse_and_map(np, 0); | 372 | twd_ppi = irq_of_parse_and_map(np, 0); |
385 | if (!twd_ppi) { | 373 | if (!twd_ppi) { |
386 | err = -EINVAL; | 374 | err = -EINVAL; |
@@ -398,4 +386,7 @@ void __init twd_local_timer_of_register(void) | |||
398 | out: | 386 | out: |
399 | WARN(err, "twd_local_timer_of_register failed (%d)\n", err); | 387 | WARN(err, "twd_local_timer_of_register failed (%d)\n", err); |
400 | } | 388 | } |
389 | CLOCKSOURCE_OF_DECLARE(arm_twd_a9, "arm,cortex-a9-twd-timer", twd_local_timer_of_register); | ||
390 | CLOCKSOURCE_OF_DECLARE(arm_twd_a5, "arm,cortex-a5-twd-timer", twd_local_timer_of_register); | ||
391 | CLOCKSOURCE_OF_DECLARE(arm_twd_11mp, "arm,arm11mp-twd-timer", twd_local_timer_of_register); | ||
401 | #endif | 392 | #endif |
diff --git a/arch/arm/mach-highbank/highbank.c b/arch/arm/mach-highbank/highbank.c index a4f9f50247d4..76c1170b3528 100644 --- a/arch/arm/mach-highbank/highbank.c +++ b/arch/arm/mach-highbank/highbank.c | |||
@@ -32,7 +32,6 @@ | |||
32 | #include <asm/cacheflush.h> | 32 | #include <asm/cacheflush.h> |
33 | #include <asm/cputype.h> | 33 | #include <asm/cputype.h> |
34 | #include <asm/smp_plat.h> | 34 | #include <asm/smp_plat.h> |
35 | #include <asm/smp_twd.h> | ||
36 | #include <asm/hardware/arm_timer.h> | 35 | #include <asm/hardware/arm_timer.h> |
37 | #include <asm/hardware/timer-sp.h> | 36 | #include <asm/hardware/timer-sp.h> |
38 | #include <asm/hardware/cache-l2x0.h> | 37 | #include <asm/hardware/cache-l2x0.h> |
@@ -119,10 +118,10 @@ static void __init highbank_timer_init(void) | |||
119 | sp804_clocksource_and_sched_clock_init(timer_base + 0x20, "timer1"); | 118 | sp804_clocksource_and_sched_clock_init(timer_base + 0x20, "timer1"); |
120 | sp804_clockevents_init(timer_base, irq, "timer0"); | 119 | sp804_clockevents_init(timer_base, irq, "timer0"); |
121 | 120 | ||
122 | twd_local_timer_of_register(); | ||
123 | |||
124 | arch_timer_of_register(); | 121 | arch_timer_of_register(); |
125 | arch_timer_sched_clock_init(); | 122 | arch_timer_sched_clock_init(); |
123 | |||
124 | clocksource_of_init(); | ||
126 | } | 125 | } |
127 | 126 | ||
128 | static void highbank_power_off(void) | 127 | static void highbank_power_off(void) |
diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c index 9ffd103b27e4..b59ddcb57c78 100644 --- a/arch/arm/mach-imx/mach-imx6q.c +++ b/arch/arm/mach-imx/mach-imx6q.c | |||
@@ -12,6 +12,7 @@ | |||
12 | 12 | ||
13 | #include <linux/clk.h> | 13 | #include <linux/clk.h> |
14 | #include <linux/clkdev.h> | 14 | #include <linux/clkdev.h> |
15 | #include <linux/clocksource.h> | ||
15 | #include <linux/cpu.h> | 16 | #include <linux/cpu.h> |
16 | #include <linux/delay.h> | 17 | #include <linux/delay.h> |
17 | #include <linux/export.h> | 18 | #include <linux/export.h> |
@@ -28,11 +29,9 @@ | |||
28 | #include <linux/regmap.h> | 29 | #include <linux/regmap.h> |
29 | #include <linux/micrel_phy.h> | 30 | #include <linux/micrel_phy.h> |
30 | #include <linux/mfd/syscon.h> | 31 | #include <linux/mfd/syscon.h> |
31 | #include <asm/smp_twd.h> | ||
32 | #include <asm/hardware/cache-l2x0.h> | 32 | #include <asm/hardware/cache-l2x0.h> |
33 | #include <asm/mach/arch.h> | 33 | #include <asm/mach/arch.h> |
34 | #include <asm/mach/map.h> | 34 | #include <asm/mach/map.h> |
35 | #include <asm/mach/time.h> | ||
36 | #include <asm/system_misc.h> | 35 | #include <asm/system_misc.h> |
37 | 36 | ||
38 | #include "common.h" | 37 | #include "common.h" |
@@ -292,7 +291,7 @@ static void __init imx6q_init_irq(void) | |||
292 | static void __init imx6q_timer_init(void) | 291 | static void __init imx6q_timer_init(void) |
293 | { | 292 | { |
294 | mx6q_clocks_init(); | 293 | mx6q_clocks_init(); |
295 | twd_local_timer_of_register(); | 294 | clocksource_of_init(); |
296 | imx_print_silicon_rev("i.MX6Q", imx6q_revision()); | 295 | imx_print_silicon_rev("i.MX6Q", imx6q_revision()); |
297 | } | 296 | } |
298 | 297 | ||
diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c index 2bdd4cf17a8f..4fd80257c73e 100644 --- a/arch/arm/mach-omap2/timer.c +++ b/arch/arm/mach-omap2/timer.c | |||
@@ -597,7 +597,7 @@ void __init omap4_local_timer_init(void) | |||
597 | int err; | 597 | int err; |
598 | 598 | ||
599 | if (of_have_populated_dt()) { | 599 | if (of_have_populated_dt()) { |
600 | twd_local_timer_of_register(); | 600 | clocksource_of_init(); |
601 | return; | 601 | return; |
602 | } | 602 | } |
603 | 603 | ||
diff --git a/arch/arm/mach-spear13xx/spear13xx.c b/arch/arm/mach-spear13xx/spear13xx.c index c7d2b4a8d8cc..25a10191b021 100644 --- a/arch/arm/mach-spear13xx/spear13xx.c +++ b/arch/arm/mach-spear13xx/spear13xx.c | |||
@@ -15,12 +15,12 @@ | |||
15 | 15 | ||
16 | #include <linux/amba/pl022.h> | 16 | #include <linux/amba/pl022.h> |
17 | #include <linux/clk.h> | 17 | #include <linux/clk.h> |
18 | #include <linux/clocksource.h> | ||
18 | #include <linux/dw_dmac.h> | 19 | #include <linux/dw_dmac.h> |
19 | #include <linux/err.h> | 20 | #include <linux/err.h> |
20 | #include <linux/of.h> | 21 | #include <linux/of.h> |
21 | #include <asm/hardware/cache-l2x0.h> | 22 | #include <asm/hardware/cache-l2x0.h> |
22 | #include <asm/mach/map.h> | 23 | #include <asm/mach/map.h> |
23 | #include <asm/smp_twd.h> | ||
24 | #include <mach/dma.h> | 24 | #include <mach/dma.h> |
25 | #include <mach/generic.h> | 25 | #include <mach/generic.h> |
26 | #include <mach/spear.h> | 26 | #include <mach/spear.h> |
@@ -179,5 +179,5 @@ void __init spear13xx_timer_init(void) | |||
179 | clk_put(pclk); | 179 | clk_put(pclk); |
180 | 180 | ||
181 | spear_setup_of_timer(); | 181 | spear_setup_of_timer(); |
182 | twd_local_timer_of_register(); | 182 | clocksource_of_init(); |
183 | } | 183 | } |
diff --git a/arch/arm/mach-ux500/timer.c b/arch/arm/mach-ux500/timer.c index a6af0b8732ba..d07bbe7f04a6 100644 --- a/arch/arm/mach-ux500/timer.c +++ b/arch/arm/mach-ux500/timer.c | |||
@@ -7,6 +7,7 @@ | |||
7 | #include <linux/io.h> | 7 | #include <linux/io.h> |
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 | #include <linux/clocksource.h> | ||
10 | #include <linux/of.h> | 11 | #include <linux/of.h> |
11 | #include <linux/of_address.h> | 12 | #include <linux/of_address.h> |
12 | #include <linux/platform_data/clocksource-nomadik-mtu.h> | 13 | #include <linux/platform_data/clocksource-nomadik-mtu.h> |
@@ -32,7 +33,7 @@ static void __init ux500_twd_init(void) | |||
32 | twd_local_timer = &u8500_twd_local_timer; | 33 | twd_local_timer = &u8500_twd_local_timer; |
33 | 34 | ||
34 | if (of_have_populated_dt()) | 35 | if (of_have_populated_dt()) |
35 | twd_local_timer_of_register(); | 36 | clocksource_of_init(); |
36 | else { | 37 | else { |
37 | err = twd_local_timer_register(twd_local_timer); | 38 | err = twd_local_timer_register(twd_local_timer); |
38 | if (err) | 39 | if (err) |
diff --git a/arch/arm/mach-vexpress/v2m.c b/arch/arm/mach-vexpress/v2m.c index 915683cb67d6..d0ad78998cb6 100644 --- a/arch/arm/mach-vexpress/v2m.c +++ b/arch/arm/mach-vexpress/v2m.c | |||
@@ -5,6 +5,7 @@ | |||
5 | #include <linux/amba/bus.h> | 5 | #include <linux/amba/bus.h> |
6 | #include <linux/amba/mmci.h> | 6 | #include <linux/amba/mmci.h> |
7 | #include <linux/io.h> | 7 | #include <linux/io.h> |
8 | #include <linux/clocksource.h> | ||
8 | #include <linux/smp.h> | 9 | #include <linux/smp.h> |
9 | #include <linux/init.h> | 10 | #include <linux/init.h> |
10 | #include <linux/irqchip.h> | 11 | #include <linux/irqchip.h> |
@@ -25,7 +26,6 @@ | |||
25 | #include <asm/arch_timer.h> | 26 | #include <asm/arch_timer.h> |
26 | #include <asm/mach-types.h> | 27 | #include <asm/mach-types.h> |
27 | #include <asm/sizes.h> | 28 | #include <asm/sizes.h> |
28 | #include <asm/smp_twd.h> | ||
29 | #include <asm/mach/arch.h> | 29 | #include <asm/mach/arch.h> |
30 | #include <asm/mach/map.h> | 30 | #include <asm/mach/map.h> |
31 | #include <asm/mach/time.h> | 31 | #include <asm/mach/time.h> |
@@ -435,6 +435,7 @@ static void __init v2m_dt_timer_init(void) | |||
435 | 435 | ||
436 | vexpress_clk_of_init(); | 436 | vexpress_clk_of_init(); |
437 | 437 | ||
438 | clocksource_of_init(); | ||
438 | do { | 439 | do { |
439 | node = of_find_compatible_node(node, NULL, "arm,sp804"); | 440 | node = of_find_compatible_node(node, NULL, "arm,sp804"); |
440 | } while (node && vexpress_get_site_by_node(node) != VEXPRESS_SITE_MB); | 441 | } while (node && vexpress_get_site_by_node(node) != VEXPRESS_SITE_MB); |
@@ -445,8 +446,7 @@ static void __init v2m_dt_timer_init(void) | |||
445 | irq_of_parse_and_map(node, 0)); | 446 | irq_of_parse_and_map(node, 0)); |
446 | } | 447 | } |
447 | 448 | ||
448 | if (arch_timer_of_register() != 0) | 449 | arch_timer_of_register(); |
449 | twd_local_timer_of_register(); | ||
450 | 450 | ||
451 | if (arch_timer_sched_clock_init() != 0) | 451 | if (arch_timer_sched_clock_init() != 0) |
452 | versatile_sched_clock_init(vexpress_get_24mhz_clock_base(), | 452 | versatile_sched_clock_init(vexpress_get_24mhz_clock_base(), |
diff --git a/arch/arm/mach-zynq/Kconfig b/arch/arm/mach-zynq/Kconfig index adb6c0ea0e53..d70651e8b705 100644 --- a/arch/arm/mach-zynq/Kconfig +++ b/arch/arm/mach-zynq/Kconfig | |||
@@ -9,5 +9,6 @@ config ARCH_ZYNQ | |||
9 | select MIGHT_HAVE_CACHE_L2X0 | 9 | select MIGHT_HAVE_CACHE_L2X0 |
10 | select USE_OF | 10 | select USE_OF |
11 | select SPARSE_IRQ | 11 | select SPARSE_IRQ |
12 | select CADENCE_TTC_TIMER | ||
12 | help | 13 | help |
13 | Support for Xilinx Zynq ARM Cortex A9 Platform | 14 | Support for Xilinx Zynq ARM Cortex A9 Platform |
diff --git a/arch/arm/mach-zynq/Makefile b/arch/arm/mach-zynq/Makefile index 397268c1b250..320faedeb484 100644 --- a/arch/arm/mach-zynq/Makefile +++ b/arch/arm/mach-zynq/Makefile | |||
@@ -3,4 +3,4 @@ | |||
3 | # | 3 | # |
4 | 4 | ||
5 | # Common support | 5 | # Common support |
6 | obj-y := common.o timer.o | 6 | obj-y := common.o |
diff --git a/arch/arm/mach-zynq/common.c b/arch/arm/mach-zynq/common.c index 5c8983218183..68e0907de5d0 100644 --- a/arch/arm/mach-zynq/common.c +++ b/arch/arm/mach-zynq/common.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/platform_device.h> | 20 | #include <linux/platform_device.h> |
21 | #include <linux/clk.h> | 21 | #include <linux/clk.h> |
22 | #include <linux/clk/zynq.h> | 22 | #include <linux/clk/zynq.h> |
23 | #include <linux/clocksource.h> | ||
23 | #include <linux/of_address.h> | 24 | #include <linux/of_address.h> |
24 | #include <linux/of_irq.h> | 25 | #include <linux/of_irq.h> |
25 | #include <linux/of_platform.h> | 26 | #include <linux/of_platform.h> |
@@ -77,7 +78,7 @@ static void __init xilinx_zynq_timer_init(void) | |||
77 | 78 | ||
78 | xilinx_zynq_clocks_init(slcr); | 79 | xilinx_zynq_clocks_init(slcr); |
79 | 80 | ||
80 | xttcps_timer_init(); | 81 | clocksource_of_init(); |
81 | } | 82 | } |
82 | 83 | ||
83 | /** | 84 | /** |
diff --git a/arch/arm/mach-zynq/common.h b/arch/arm/mach-zynq/common.h index 8b4dbbaa01cf..5050bb10bb12 100644 --- a/arch/arm/mach-zynq/common.h +++ b/arch/arm/mach-zynq/common.h | |||
@@ -17,6 +17,4 @@ | |||
17 | #ifndef __MACH_ZYNQ_COMMON_H__ | 17 | #ifndef __MACH_ZYNQ_COMMON_H__ |
18 | #define __MACH_ZYNQ_COMMON_H__ | 18 | #define __MACH_ZYNQ_COMMON_H__ |
19 | 19 | ||
20 | void __init xttcps_timer_init(void); | ||
21 | |||
22 | #endif | 20 | #endif |
diff --git a/arch/arm/mach-zynq/timer.c b/arch/arm/mach-zynq/timer.c deleted file mode 100644 index f9fbc9c1e7a6..000000000000 --- a/arch/arm/mach-zynq/timer.c +++ /dev/null | |||
@@ -1,324 +0,0 @@ | |||
1 | /* | ||
2 | * This file contains driver for the Xilinx PS Timer Counter IP. | ||
3 | * | ||
4 | * Copyright (C) 2011 Xilinx | ||
5 | * | ||
6 | * based on arch/mips/kernel/time.c timer driver | ||
7 | * | ||
8 | * This software is licensed under the terms of the GNU General Public | ||
9 | * License version 2, as published by the Free Software Foundation, and | ||
10 | * may be copied, distributed, and modified under those terms. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | */ | ||
17 | |||
18 | #include <linux/interrupt.h> | ||
19 | #include <linux/clockchips.h> | ||
20 | #include <linux/of_address.h> | ||
21 | #include <linux/of_irq.h> | ||
22 | #include <linux/slab.h> | ||
23 | #include <linux/clk-provider.h> | ||
24 | #include "common.h" | ||
25 | |||
26 | /* | ||
27 | * Timer Register Offset Definitions of Timer 1, Increment base address by 4 | ||
28 | * and use same offsets for Timer 2 | ||
29 | */ | ||
30 | #define XTTCPS_CLK_CNTRL_OFFSET 0x00 /* Clock Control Reg, RW */ | ||
31 | #define XTTCPS_CNT_CNTRL_OFFSET 0x0C /* Counter Control Reg, RW */ | ||
32 | #define XTTCPS_COUNT_VAL_OFFSET 0x18 /* Counter Value Reg, RO */ | ||
33 | #define XTTCPS_INTR_VAL_OFFSET 0x24 /* Interval Count Reg, RW */ | ||
34 | #define XTTCPS_ISR_OFFSET 0x54 /* Interrupt Status Reg, RO */ | ||
35 | #define XTTCPS_IER_OFFSET 0x60 /* Interrupt Enable Reg, RW */ | ||
36 | |||
37 | #define XTTCPS_CNT_CNTRL_DISABLE_MASK 0x1 | ||
38 | |||
39 | /* | ||
40 | * Setup the timers to use pre-scaling, using a fixed value for now that will | ||
41 | * work across most input frequency, but it may need to be more dynamic | ||
42 | */ | ||
43 | #define PRESCALE_EXPONENT 11 /* 2 ^ PRESCALE_EXPONENT = PRESCALE */ | ||
44 | #define PRESCALE 2048 /* The exponent must match this */ | ||
45 | #define CLK_CNTRL_PRESCALE ((PRESCALE_EXPONENT - 1) << 1) | ||
46 | #define CLK_CNTRL_PRESCALE_EN 1 | ||
47 | #define CNT_CNTRL_RESET (1<<4) | ||
48 | |||
49 | /** | ||
50 | * struct xttcps_timer - This definition defines local timer structure | ||
51 | * | ||
52 | * @base_addr: Base address of timer | ||
53 | **/ | ||
54 | struct xttcps_timer { | ||
55 | void __iomem *base_addr; | ||
56 | }; | ||
57 | |||
58 | struct xttcps_timer_clocksource { | ||
59 | struct xttcps_timer xttc; | ||
60 | struct clocksource cs; | ||
61 | }; | ||
62 | |||
63 | #define to_xttcps_timer_clksrc(x) \ | ||
64 | container_of(x, struct xttcps_timer_clocksource, cs) | ||
65 | |||
66 | struct xttcps_timer_clockevent { | ||
67 | struct xttcps_timer xttc; | ||
68 | struct clock_event_device ce; | ||
69 | struct clk *clk; | ||
70 | }; | ||
71 | |||
72 | #define to_xttcps_timer_clkevent(x) \ | ||
73 | container_of(x, struct xttcps_timer_clockevent, ce) | ||
74 | |||
75 | /** | ||
76 | * xttcps_set_interval - Set the timer interval value | ||
77 | * | ||
78 | * @timer: Pointer to the timer instance | ||
79 | * @cycles: Timer interval ticks | ||
80 | **/ | ||
81 | static void xttcps_set_interval(struct xttcps_timer *timer, | ||
82 | unsigned long cycles) | ||
83 | { | ||
84 | u32 ctrl_reg; | ||
85 | |||
86 | /* Disable the counter, set the counter value and re-enable counter */ | ||
87 | ctrl_reg = __raw_readl(timer->base_addr + XTTCPS_CNT_CNTRL_OFFSET); | ||
88 | ctrl_reg |= XTTCPS_CNT_CNTRL_DISABLE_MASK; | ||
89 | __raw_writel(ctrl_reg, timer->base_addr + XTTCPS_CNT_CNTRL_OFFSET); | ||
90 | |||
91 | __raw_writel(cycles, timer->base_addr + XTTCPS_INTR_VAL_OFFSET); | ||
92 | |||
93 | /* | ||
94 | * Reset the counter (0x10) so that it starts from 0, one-shot | ||
95 | * mode makes this needed for timing to be right. | ||
96 | */ | ||
97 | ctrl_reg |= CNT_CNTRL_RESET; | ||
98 | ctrl_reg &= ~XTTCPS_CNT_CNTRL_DISABLE_MASK; | ||
99 | __raw_writel(ctrl_reg, timer->base_addr + XTTCPS_CNT_CNTRL_OFFSET); | ||
100 | } | ||
101 | |||
102 | /** | ||
103 | * xttcps_clock_event_interrupt - Clock event timer interrupt handler | ||
104 | * | ||
105 | * @irq: IRQ number of the Timer | ||
106 | * @dev_id: void pointer to the xttcps_timer instance | ||
107 | * | ||
108 | * returns: Always IRQ_HANDLED - success | ||
109 | **/ | ||
110 | static irqreturn_t xttcps_clock_event_interrupt(int irq, void *dev_id) | ||
111 | { | ||
112 | struct xttcps_timer_clockevent *xttce = dev_id; | ||
113 | struct xttcps_timer *timer = &xttce->xttc; | ||
114 | |||
115 | /* Acknowledge the interrupt and call event handler */ | ||
116 | __raw_readl(timer->base_addr + XTTCPS_ISR_OFFSET); | ||
117 | |||
118 | xttce->ce.event_handler(&xttce->ce); | ||
119 | |||
120 | return IRQ_HANDLED; | ||
121 | } | ||
122 | |||
123 | /** | ||
124 | * __xttc_clocksource_read - Reads the timer counter register | ||
125 | * | ||
126 | * returns: Current timer counter register value | ||
127 | **/ | ||
128 | static cycle_t __xttc_clocksource_read(struct clocksource *cs) | ||
129 | { | ||
130 | struct xttcps_timer *timer = &to_xttcps_timer_clksrc(cs)->xttc; | ||
131 | |||
132 | return (cycle_t)__raw_readl(timer->base_addr + | ||
133 | XTTCPS_COUNT_VAL_OFFSET); | ||
134 | } | ||
135 | |||
136 | /** | ||
137 | * xttcps_set_next_event - Sets the time interval for next event | ||
138 | * | ||
139 | * @cycles: Timer interval ticks | ||
140 | * @evt: Address of clock event instance | ||
141 | * | ||
142 | * returns: Always 0 - success | ||
143 | **/ | ||
144 | static int xttcps_set_next_event(unsigned long cycles, | ||
145 | struct clock_event_device *evt) | ||
146 | { | ||
147 | struct xttcps_timer_clockevent *xttce = to_xttcps_timer_clkevent(evt); | ||
148 | struct xttcps_timer *timer = &xttce->xttc; | ||
149 | |||
150 | xttcps_set_interval(timer, cycles); | ||
151 | return 0; | ||
152 | } | ||
153 | |||
154 | /** | ||
155 | * xttcps_set_mode - Sets the mode of timer | ||
156 | * | ||
157 | * @mode: Mode to be set | ||
158 | * @evt: Address of clock event instance | ||
159 | **/ | ||
160 | static void xttcps_set_mode(enum clock_event_mode mode, | ||
161 | struct clock_event_device *evt) | ||
162 | { | ||
163 | struct xttcps_timer_clockevent *xttce = to_xttcps_timer_clkevent(evt); | ||
164 | struct xttcps_timer *timer = &xttce->xttc; | ||
165 | u32 ctrl_reg; | ||
166 | |||
167 | switch (mode) { | ||
168 | case CLOCK_EVT_MODE_PERIODIC: | ||
169 | xttcps_set_interval(timer, | ||
170 | DIV_ROUND_CLOSEST(clk_get_rate(xttce->clk), | ||
171 | PRESCALE * HZ)); | ||
172 | break; | ||
173 | case CLOCK_EVT_MODE_ONESHOT: | ||
174 | case CLOCK_EVT_MODE_UNUSED: | ||
175 | case CLOCK_EVT_MODE_SHUTDOWN: | ||
176 | ctrl_reg = __raw_readl(timer->base_addr + | ||
177 | XTTCPS_CNT_CNTRL_OFFSET); | ||
178 | ctrl_reg |= XTTCPS_CNT_CNTRL_DISABLE_MASK; | ||
179 | __raw_writel(ctrl_reg, | ||
180 | timer->base_addr + XTTCPS_CNT_CNTRL_OFFSET); | ||
181 | break; | ||
182 | case CLOCK_EVT_MODE_RESUME: | ||
183 | ctrl_reg = __raw_readl(timer->base_addr + | ||
184 | XTTCPS_CNT_CNTRL_OFFSET); | ||
185 | ctrl_reg &= ~XTTCPS_CNT_CNTRL_DISABLE_MASK; | ||
186 | __raw_writel(ctrl_reg, | ||
187 | timer->base_addr + XTTCPS_CNT_CNTRL_OFFSET); | ||
188 | break; | ||
189 | } | ||
190 | } | ||
191 | |||
192 | static void __init zynq_ttc_setup_clocksource(struct device_node *np, | ||
193 | void __iomem *base) | ||
194 | { | ||
195 | struct xttcps_timer_clocksource *ttccs; | ||
196 | struct clk *clk; | ||
197 | int err; | ||
198 | u32 reg; | ||
199 | |||
200 | ttccs = kzalloc(sizeof(*ttccs), GFP_KERNEL); | ||
201 | if (WARN_ON(!ttccs)) | ||
202 | return; | ||
203 | |||
204 | err = of_property_read_u32(np, "reg", ®); | ||
205 | if (WARN_ON(err)) | ||
206 | return; | ||
207 | |||
208 | clk = of_clk_get_by_name(np, "cpu_1x"); | ||
209 | if (WARN_ON(IS_ERR(clk))) | ||
210 | return; | ||
211 | |||
212 | err = clk_prepare_enable(clk); | ||
213 | if (WARN_ON(err)) | ||
214 | return; | ||
215 | |||
216 | ttccs->xttc.base_addr = base + reg * 4; | ||
217 | |||
218 | ttccs->cs.name = np->name; | ||
219 | ttccs->cs.rating = 200; | ||
220 | ttccs->cs.read = __xttc_clocksource_read; | ||
221 | ttccs->cs.mask = CLOCKSOURCE_MASK(16); | ||
222 | ttccs->cs.flags = CLOCK_SOURCE_IS_CONTINUOUS; | ||
223 | |||
224 | __raw_writel(0x0, ttccs->xttc.base_addr + XTTCPS_IER_OFFSET); | ||
225 | __raw_writel(CLK_CNTRL_PRESCALE | CLK_CNTRL_PRESCALE_EN, | ||
226 | ttccs->xttc.base_addr + XTTCPS_CLK_CNTRL_OFFSET); | ||
227 | __raw_writel(CNT_CNTRL_RESET, | ||
228 | ttccs->xttc.base_addr + XTTCPS_CNT_CNTRL_OFFSET); | ||
229 | |||
230 | err = clocksource_register_hz(&ttccs->cs, clk_get_rate(clk) / PRESCALE); | ||
231 | if (WARN_ON(err)) | ||
232 | return; | ||
233 | } | ||
234 | |||
235 | static void __init zynq_ttc_setup_clockevent(struct device_node *np, | ||
236 | void __iomem *base) | ||
237 | { | ||
238 | struct xttcps_timer_clockevent *ttcce; | ||
239 | int err, irq; | ||
240 | u32 reg; | ||
241 | |||
242 | ttcce = kzalloc(sizeof(*ttcce), GFP_KERNEL); | ||
243 | if (WARN_ON(!ttcce)) | ||
244 | return; | ||
245 | |||
246 | err = of_property_read_u32(np, "reg", ®); | ||
247 | if (WARN_ON(err)) | ||
248 | return; | ||
249 | |||
250 | ttcce->xttc.base_addr = base + reg * 4; | ||
251 | |||
252 | ttcce->clk = of_clk_get_by_name(np, "cpu_1x"); | ||
253 | if (WARN_ON(IS_ERR(ttcce->clk))) | ||
254 | return; | ||
255 | |||
256 | err = clk_prepare_enable(ttcce->clk); | ||
257 | if (WARN_ON(err)) | ||
258 | return; | ||
259 | |||
260 | irq = irq_of_parse_and_map(np, 0); | ||
261 | if (WARN_ON(!irq)) | ||
262 | return; | ||
263 | |||
264 | ttcce->ce.name = np->name; | ||
265 | ttcce->ce.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT; | ||
266 | ttcce->ce.set_next_event = xttcps_set_next_event; | ||
267 | ttcce->ce.set_mode = xttcps_set_mode; | ||
268 | ttcce->ce.rating = 200; | ||
269 | ttcce->ce.irq = irq; | ||
270 | ttcce->ce.cpumask = cpu_possible_mask; | ||
271 | |||
272 | __raw_writel(0x23, ttcce->xttc.base_addr + XTTCPS_CNT_CNTRL_OFFSET); | ||
273 | __raw_writel(CLK_CNTRL_PRESCALE | CLK_CNTRL_PRESCALE_EN, | ||
274 | ttcce->xttc.base_addr + XTTCPS_CLK_CNTRL_OFFSET); | ||
275 | __raw_writel(0x1, ttcce->xttc.base_addr + XTTCPS_IER_OFFSET); | ||
276 | |||
277 | err = request_irq(irq, xttcps_clock_event_interrupt, IRQF_TIMER, | ||
278 | np->name, ttcce); | ||
279 | if (WARN_ON(err)) | ||
280 | return; | ||
281 | |||
282 | clockevents_config_and_register(&ttcce->ce, | ||
283 | clk_get_rate(ttcce->clk) / PRESCALE, | ||
284 | 1, 0xfffe); | ||
285 | } | ||
286 | |||
287 | static const __initconst struct of_device_id zynq_ttc_match[] = { | ||
288 | { .compatible = "xlnx,ttc-counter-clocksource", | ||
289 | .data = zynq_ttc_setup_clocksource, }, | ||
290 | { .compatible = "xlnx,ttc-counter-clockevent", | ||
291 | .data = zynq_ttc_setup_clockevent, }, | ||
292 | {} | ||
293 | }; | ||
294 | |||
295 | /** | ||
296 | * xttcps_timer_init - Initialize the timer | ||
297 | * | ||
298 | * Initializes the timer hardware and register the clock source and clock event | ||
299 | * timers with Linux kernal timer framework | ||
300 | **/ | ||
301 | void __init xttcps_timer_init(void) | ||
302 | { | ||
303 | struct device_node *np; | ||
304 | |||
305 | for_each_compatible_node(np, NULL, "xlnx,ttc") { | ||
306 | struct device_node *np_chld; | ||
307 | void __iomem *base; | ||
308 | |||
309 | base = of_iomap(np, 0); | ||
310 | if (WARN_ON(!base)) | ||
311 | return; | ||
312 | |||
313 | for_each_available_child_of_node(np, np_chld) { | ||
314 | int (*cb)(struct device_node *np, void __iomem *base); | ||
315 | const struct of_device_id *match; | ||
316 | |||
317 | match = of_match_node(zynq_ttc_match, np_chld); | ||
318 | if (match) { | ||
319 | cb = match->data; | ||
320 | cb(np_chld, base); | ||
321 | } | ||
322 | } | ||
323 | } | ||
324 | } | ||