diff options
author | Dinh Nguyen <dinguyen@altera.com> | 2012-07-11 16:13:16 -0400 |
---|---|---|
committer | Arnd Bergmann <arnd@arndb.de> | 2012-07-12 11:26:09 -0400 |
commit | cfda590178a16e2b5edb09e131460b3e64819807 (patch) | |
tree | 7104a9bb75d101dcdc82c331e9cdd075eab702dc | |
parent | bd0a521e88aa7a06ae7aabaed7ae196ed4ad867a (diff) |
clocksource: dw_apb_timer: Add common DTS glue for dw_apb_timer
Make a common device tree glue for clocksource/dw_apb_timer.
Move mach-picoxcell/time.c to be a generic device tree application
of the dw_apb_timer.
Configure mach-picoxcell to use the dw_apb_timer_of device tree
implementation in drivers/clocksource.
Signed-off-by: Pavel Machek <pavel@denx.de>
Signed-off-by: Dinh Nguyen <dinguyen@altera.com>
Acked-by: Jamie Iles <jamie@jamieiles.com>
Acked-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
-rw-r--r-- | Documentation/devicetree/bindings/rtc/dw-apb.txt | 25 | ||||
-rw-r--r-- | arch/arm/Kconfig | 1 | ||||
-rw-r--r-- | arch/arm/mach-picoxcell/Makefile | 1 | ||||
-rw-r--r-- | arch/arm/mach-picoxcell/common.c | 3 | ||||
-rw-r--r-- | arch/arm/mach-picoxcell/common.h | 2 | ||||
-rw-r--r-- | drivers/clocksource/Kconfig | 3 | ||||
-rw-r--r-- | drivers/clocksource/Makefile | 1 | ||||
-rw-r--r-- | drivers/clocksource/dw_apb_timer_of.c (renamed from arch/arm/mach-picoxcell/time.c) | 52 |
8 files changed, 64 insertions, 24 deletions
diff --git a/Documentation/devicetree/bindings/rtc/dw-apb.txt b/Documentation/devicetree/bindings/rtc/dw-apb.txt new file mode 100644 index 000000000000..93e2b0f048e6 --- /dev/null +++ b/Documentation/devicetree/bindings/rtc/dw-apb.txt | |||
@@ -0,0 +1,25 @@ | |||
1 | * Designware APB timer | ||
2 | |||
3 | Required properties: | ||
4 | - compatible: "snps,dw-apb-timer-sp" or "snps,dw-apb-timer-osc" | ||
5 | - reg: physical base address of the controller and length of memory mapped | ||
6 | region. | ||
7 | - interrupts: IRQ line for the timer. | ||
8 | - clock-frequency: The frequency in HZ of the timer. | ||
9 | - clock-freq: For backwards compatibility with picoxcell | ||
10 | |||
11 | Example: | ||
12 | |||
13 | timer1: timer@ffc09000 { | ||
14 | compatible = "snps,dw-apb-timer-sp"; | ||
15 | interrupts = <0 168 4>; | ||
16 | clock-frequency = <200000000>; | ||
17 | reg = <0xffc09000 0x1000>; | ||
18 | }; | ||
19 | |||
20 | timer2: timer@ffd00000 { | ||
21 | compatible = "snps,dw-apb-timer-osc"; | ||
22 | interrupts = <0 169 4>; | ||
23 | clock-frequency = <200000000>; | ||
24 | reg = <0xffd00000 0x1000>; | ||
25 | }; | ||
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index a91009c61870..57eb6ef7f48d 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
@@ -658,6 +658,7 @@ config ARCH_PICOXCELL | |||
658 | select ARM_VIC | 658 | select ARM_VIC |
659 | select CPU_V6K | 659 | select CPU_V6K |
660 | select DW_APB_TIMER | 660 | select DW_APB_TIMER |
661 | select DW_APB_TIMER_OF | ||
661 | select GENERIC_CLOCKEVENTS | 662 | select GENERIC_CLOCKEVENTS |
662 | select GENERIC_GPIO | 663 | select GENERIC_GPIO |
663 | select HAVE_TCM | 664 | select HAVE_TCM |
diff --git a/arch/arm/mach-picoxcell/Makefile b/arch/arm/mach-picoxcell/Makefile index e5ec4a8d9bcb..8e39f80fce19 100644 --- a/arch/arm/mach-picoxcell/Makefile +++ b/arch/arm/mach-picoxcell/Makefile | |||
@@ -1,2 +1 @@ | |||
1 | obj-y := common.o | obj-y := common.o | |
2 | obj-y += time.o | ||
diff --git a/arch/arm/mach-picoxcell/common.c b/arch/arm/mach-picoxcell/common.c index a2e8ae8b5821..8f9a0b47a7fa 100644 --- a/arch/arm/mach-picoxcell/common.c +++ b/arch/arm/mach-picoxcell/common.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/of_address.h> | 14 | #include <linux/of_address.h> |
15 | #include <linux/of_irq.h> | 15 | #include <linux/of_irq.h> |
16 | #include <linux/of_platform.h> | 16 | #include <linux/of_platform.h> |
17 | #include <linux/dw_apb_timer.h> | ||
17 | 18 | ||
18 | #include <asm/mach/arch.h> | 19 | #include <asm/mach/arch.h> |
19 | #include <asm/hardware/vic.h> | 20 | #include <asm/hardware/vic.h> |
@@ -97,7 +98,7 @@ DT_MACHINE_START(PICOXCELL, "Picochip picoXcell") | |||
97 | .nr_irqs = NR_IRQS_LEGACY, | 98 | .nr_irqs = NR_IRQS_LEGACY, |
98 | .init_irq = picoxcell_init_irq, | 99 | .init_irq = picoxcell_init_irq, |
99 | .handle_irq = vic_handle_irq, | 100 | .handle_irq = vic_handle_irq, |
100 | .timer = &picoxcell_timer, | 101 | .timer = &dw_apb_timer, |
101 | .init_machine = picoxcell_init_machine, | 102 | .init_machine = picoxcell_init_machine, |
102 | .dt_compat = picoxcell_dt_match, | 103 | .dt_compat = picoxcell_dt_match, |
103 | .restart = picoxcell_wdt_restart, | 104 | .restart = picoxcell_wdt_restart, |
diff --git a/arch/arm/mach-picoxcell/common.h b/arch/arm/mach-picoxcell/common.h index 83d55ab956a4..a65cb02f84c8 100644 --- a/arch/arm/mach-picoxcell/common.h +++ b/arch/arm/mach-picoxcell/common.h | |||
@@ -12,6 +12,6 @@ | |||
12 | 12 | ||
13 | #include <asm/mach/time.h> | 13 | #include <asm/mach/time.h> |
14 | 14 | ||
15 | extern struct sys_timer picoxcell_timer; | 15 | extern struct sys_timer dw_apb_timer; |
16 | 16 | ||
17 | #endif /* __PICOXCELL_COMMON_H__ */ | 17 | #endif /* __PICOXCELL_COMMON_H__ */ |
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index 99c6b203e6cd..e62bc7e9d49b 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig | |||
@@ -16,6 +16,9 @@ config CLKSRC_MMIO | |||
16 | config DW_APB_TIMER | 16 | config DW_APB_TIMER |
17 | bool | 17 | bool |
18 | 18 | ||
19 | config DW_APB_TIMER_OF | ||
20 | bool | ||
21 | |||
19 | config CLKSRC_DBX500_PRCMU | 22 | config CLKSRC_DBX500_PRCMU |
20 | bool "Clocksource PRCMU Timer" | 23 | bool "Clocksource PRCMU Timer" |
21 | depends on UX500_SOC_DB8500 | 24 | depends on UX500_SOC_DB8500 |
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile index dd3e661a124d..2cdaf7d1019f 100644 --- a/drivers/clocksource/Makefile +++ b/drivers/clocksource/Makefile | |||
@@ -10,4 +10,5 @@ obj-$(CONFIG_EM_TIMER_STI) += em_sti.o | |||
10 | obj-$(CONFIG_CLKBLD_I8253) += i8253.o | 10 | obj-$(CONFIG_CLKBLD_I8253) += i8253.o |
11 | obj-$(CONFIG_CLKSRC_MMIO) += mmio.o | 11 | obj-$(CONFIG_CLKSRC_MMIO) += mmio.o |
12 | obj-$(CONFIG_DW_APB_TIMER) += dw_apb_timer.o | 12 | obj-$(CONFIG_DW_APB_TIMER) += dw_apb_timer.o |
13 | obj-$(CONFIG_DW_APB_TIMER_OF) += dw_apb_timer_of.o | ||
13 | obj-$(CONFIG_CLKSRC_DBX500_PRCMU) += clksrc-dbx500-prcmu.o \ No newline at end of file | 14 | obj-$(CONFIG_CLKSRC_DBX500_PRCMU) += clksrc-dbx500-prcmu.o \ No newline at end of file |
diff --git a/arch/arm/mach-picoxcell/time.c b/drivers/clocksource/dw_apb_timer_of.c index 2ecba6743b8e..f7dba5b79b44 100644 --- a/arch/arm/mach-picoxcell/time.c +++ b/drivers/clocksource/dw_apb_timer_of.c | |||
@@ -1,11 +1,20 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2012 Altera Corporation | ||
2 | * Copyright (c) 2011 Picochip Ltd., Jamie Iles | 3 | * Copyright (c) 2011 Picochip Ltd., Jamie Iles |
3 | * | 4 | * |
5 | * Modified from mach-picoxcell/time.c | ||
6 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
5 | * it under the terms of the GNU General Public License version 2 as | 8 | * it under the terms of the GNU General Public License version 2 as |
6 | * published by the Free Software Foundation. | 9 | * published by the Free Software Foundation. |
7 | * | 10 | * |
8 | * All enquiries to support@picochip.com | 11 | * This program is distributed in the hope that it will be useful, |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
9 | */ | 18 | */ |
10 | #include <linux/dw_apb_timer.h> | 19 | #include <linux/dw_apb_timer.h> |
11 | #include <linux/of.h> | 20 | #include <linux/of.h> |
@@ -15,8 +24,6 @@ | |||
15 | #include <asm/mach/time.h> | 24 | #include <asm/mach/time.h> |
16 | #include <asm/sched_clock.h> | 25 | #include <asm/sched_clock.h> |
17 | 26 | ||
18 | #include "common.h" | ||
19 | |||
20 | static void timer_get_base_and_rate(struct device_node *np, | 27 | static void timer_get_base_and_rate(struct device_node *np, |
21 | void __iomem **base, u32 *rate) | 28 | void __iomem **base, u32 *rate) |
22 | { | 29 | { |
@@ -25,11 +32,12 @@ static void timer_get_base_and_rate(struct device_node *np, | |||
25 | if (!*base) | 32 | if (!*base) |
26 | panic("Unable to map regs for %s", np->name); | 33 | panic("Unable to map regs for %s", np->name); |
27 | 34 | ||
28 | if (of_property_read_u32(np, "clock-freq", rate)) | 35 | if (of_property_read_u32(np, "clock-freq", rate) && |
29 | panic("No clock-freq property for %s", np->name); | 36 | of_property_read_u32(np, "clock-frequency", rate)) |
37 | panic("No clock-frequency property for %s", np->name); | ||
30 | } | 38 | } |
31 | 39 | ||
32 | static void picoxcell_add_clockevent(struct device_node *event_timer) | 40 | static void add_clockevent(struct device_node *event_timer) |
33 | { | 41 | { |
34 | void __iomem *iobase; | 42 | void __iomem *iobase; |
35 | struct dw_apb_clock_event_device *ced; | 43 | struct dw_apb_clock_event_device *ced; |
@@ -49,7 +57,7 @@ static void picoxcell_add_clockevent(struct device_node *event_timer) | |||
49 | dw_apb_clockevent_register(ced); | 57 | dw_apb_clockevent_register(ced); |
50 | } | 58 | } |
51 | 59 | ||
52 | static void picoxcell_add_clocksource(struct device_node *source_timer) | 60 | static void add_clocksource(struct device_node *source_timer) |
53 | { | 61 | { |
54 | void __iomem *iobase; | 62 | void __iomem *iobase; |
55 | struct dw_apb_clocksource *cs; | 63 | struct dw_apb_clocksource *cs; |
@@ -67,55 +75,57 @@ static void picoxcell_add_clocksource(struct device_node *source_timer) | |||
67 | 75 | ||
68 | static void __iomem *sched_io_base; | 76 | static void __iomem *sched_io_base; |
69 | 77 | ||
70 | static u32 picoxcell_read_sched_clock(void) | 78 | static u32 read_sched_clock(void) |
71 | { | 79 | { |
72 | return __raw_readl(sched_io_base); | 80 | return __raw_readl(sched_io_base); |
73 | } | 81 | } |
74 | 82 | ||
75 | static const struct of_device_id picoxcell_rtc_ids[] __initconst = { | 83 | static const struct of_device_id sptimer_ids[] __initconst = { |
76 | { .compatible = "picochip,pc3x2-rtc" }, | 84 | { .compatible = "picochip,pc3x2-rtc" }, |
85 | { .compatible = "snps,dw-apb-timer-sp" }, | ||
77 | { /* Sentinel */ }, | 86 | { /* Sentinel */ }, |
78 | }; | 87 | }; |
79 | 88 | ||
80 | static void picoxcell_init_sched_clock(void) | 89 | static void init_sched_clock(void) |
81 | { | 90 | { |
82 | struct device_node *sched_timer; | 91 | struct device_node *sched_timer; |
83 | u32 rate; | 92 | u32 rate; |
84 | 93 | ||
85 | sched_timer = of_find_matching_node(NULL, picoxcell_rtc_ids); | 94 | sched_timer = of_find_matching_node(NULL, sptimer_ids); |
86 | if (!sched_timer) | 95 | if (!sched_timer) |
87 | panic("No RTC for sched clock to use"); | 96 | panic("No RTC for sched clock to use"); |
88 | 97 | ||
89 | timer_get_base_and_rate(sched_timer, &sched_io_base, &rate); | 98 | timer_get_base_and_rate(sched_timer, &sched_io_base, &rate); |
90 | of_node_put(sched_timer); | 99 | of_node_put(sched_timer); |
91 | 100 | ||
92 | setup_sched_clock(picoxcell_read_sched_clock, 32, rate); | 101 | setup_sched_clock(read_sched_clock, 32, rate); |
93 | } | 102 | } |
94 | 103 | ||
95 | static const struct of_device_id picoxcell_timer_ids[] __initconst = { | 104 | static const struct of_device_id osctimer_ids[] __initconst = { |
96 | { .compatible = "picochip,pc3x2-timer" }, | 105 | { .compatible = "picochip,pc3x2-timer" }, |
106 | { .compatible = "snps,dw-apb-timer-osc" }, | ||
97 | {}, | 107 | {}, |
98 | }; | 108 | }; |
99 | 109 | ||
100 | static void __init picoxcell_timer_init(void) | 110 | static void __init timer_init(void) |
101 | { | 111 | { |
102 | struct device_node *event_timer, *source_timer; | 112 | struct device_node *event_timer, *source_timer; |
103 | 113 | ||
104 | event_timer = of_find_matching_node(NULL, picoxcell_timer_ids); | 114 | event_timer = of_find_matching_node(NULL, osctimer_ids); |
105 | if (!event_timer) | 115 | if (!event_timer) |
106 | panic("No timer for clockevent"); | 116 | panic("No timer for clockevent"); |
107 | picoxcell_add_clockevent(event_timer); | 117 | add_clockevent(event_timer); |
108 | 118 | ||
109 | source_timer = of_find_matching_node(event_timer, picoxcell_timer_ids); | 119 | source_timer = of_find_matching_node(event_timer, osctimer_ids); |
110 | if (!source_timer) | 120 | if (!source_timer) |
111 | panic("No timer for clocksource"); | 121 | panic("No timer for clocksource"); |
112 | picoxcell_add_clocksource(source_timer); | 122 | add_clocksource(source_timer); |
113 | 123 | ||
114 | of_node_put(source_timer); | 124 | of_node_put(source_timer); |
115 | 125 | ||
116 | picoxcell_init_sched_clock(); | 126 | init_sched_clock(); |
117 | } | 127 | } |
118 | 128 | ||
119 | struct sys_timer picoxcell_timer = { | 129 | struct sys_timer dw_apb_timer = { |
120 | .init = picoxcell_timer_init, | 130 | .init = timer_init, |
121 | }; | 131 | }; |