diff options
-rw-r--r-- | Documentation/devicetree/bindings/arm/versatile-sysreg.txt | 10 | ||||
-rw-r--r-- | Documentation/devicetree/bindings/timer/digicolor-timer.txt | 18 | ||||
-rw-r--r-- | Documentation/devicetree/bindings/timer/rockchip,rk3288-timer.txt | 18 | ||||
-rw-r--r-- | MAINTAINERS | 2 | ||||
-rw-r--r-- | arch/arm/boot/dts/versatile-ab.dts | 5 | ||||
-rw-r--r-- | arch/arm/mach-rockchip/Kconfig | 1 | ||||
-rw-r--r-- | drivers/clocksource/Kconfig | 17 | ||||
-rw-r--r-- | drivers/clocksource/Makefile | 5 | ||||
-rw-r--r-- | drivers/clocksource/asm9260_timer.c | 220 | ||||
-rw-r--r-- | drivers/clocksource/rockchip_timer.c | 180 | ||||
-rw-r--r-- | drivers/clocksource/timer-atlas7.c (renamed from drivers/clocksource/timer-marco.c) | 15 | ||||
-rw-r--r-- | drivers/clocksource/timer-digicolor.c | 199 | ||||
-rw-r--r-- | drivers/clocksource/versatile.c | 4 |
13 files changed, 683 insertions, 11 deletions
diff --git a/Documentation/devicetree/bindings/arm/versatile-sysreg.txt b/Documentation/devicetree/bindings/arm/versatile-sysreg.txt new file mode 100644 index 000000000000..a4f15262d717 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/versatile-sysreg.txt | |||
@@ -0,0 +1,10 @@ | |||
1 | ARM Versatile system registers | ||
2 | -------------------------------------- | ||
3 | |||
4 | This is a system control registers block, providing multiple low level | ||
5 | platform functions like board detection and identification, software | ||
6 | interrupt generation, MMC and NOR Flash control etc. | ||
7 | |||
8 | Required node properties: | ||
9 | - compatible value : = "arm,versatile-sysreg", "syscon" | ||
10 | - reg : physical base address and the size of the registers window | ||
diff --git a/Documentation/devicetree/bindings/timer/digicolor-timer.txt b/Documentation/devicetree/bindings/timer/digicolor-timer.txt new file mode 100644 index 000000000000..d1b659bbc29f --- /dev/null +++ b/Documentation/devicetree/bindings/timer/digicolor-timer.txt | |||
@@ -0,0 +1,18 @@ | |||
1 | Conexant Digicolor SoCs Timer Controller | ||
2 | |||
3 | Required properties: | ||
4 | |||
5 | - compatible : should be "cnxt,cx92755-timer" | ||
6 | - reg : Specifies base physical address and size of the "Agent Communication" | ||
7 | timer registers | ||
8 | - interrupts : Contains 8 interrupts, one for each timer | ||
9 | - clocks: phandle to the main clock | ||
10 | |||
11 | Example: | ||
12 | |||
13 | timer@f0000fc0 { | ||
14 | compatible = "cnxt,cx92755-timer"; | ||
15 | reg = <0xf0000fc0 0x40>; | ||
16 | interrupts = <19>, <31>, <34>, <35>, <52>, <53>, <54>, <55>; | ||
17 | clocks = <&main_clk>; | ||
18 | }; | ||
diff --git a/Documentation/devicetree/bindings/timer/rockchip,rk3288-timer.txt b/Documentation/devicetree/bindings/timer/rockchip,rk3288-timer.txt new file mode 100644 index 000000000000..87f0b0042bae --- /dev/null +++ b/Documentation/devicetree/bindings/timer/rockchip,rk3288-timer.txt | |||
@@ -0,0 +1,18 @@ | |||
1 | Rockchip rk3288 timer | ||
2 | |||
3 | Required properties: | ||
4 | - compatible: shall be "rockchip,rk3288-timer" | ||
5 | - reg: base address of the timer register starting with TIMERS CONTROL register | ||
6 | - interrupts: should contain the interrupts for Timer0 | ||
7 | - clocks : must contain an entry for each entry in clock-names | ||
8 | - clock-names : must include the following entries: | ||
9 | "timer", "pclk" | ||
10 | |||
11 | Example: | ||
12 | timer: timer@ff810000 { | ||
13 | compatible = "rockchip,rk3288-timer"; | ||
14 | reg = <0xff810000 0x20>; | ||
15 | interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>; | ||
16 | clocks = <&xin24m>, <&cru PCLK_TIMER>; | ||
17 | clock-names = "timer", "pclk"; | ||
18 | }; | ||
diff --git a/MAINTAINERS b/MAINTAINERS index 348f5c16ef50..b663e3590bd4 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -974,7 +974,7 @@ S: Maintained | |||
974 | F: arch/arm/mach-prima2/ | 974 | F: arch/arm/mach-prima2/ |
975 | F: drivers/clk/sirf/ | 975 | F: drivers/clk/sirf/ |
976 | F: drivers/clocksource/timer-prima2.c | 976 | F: drivers/clocksource/timer-prima2.c |
977 | F: drivers/clocksource/timer-marco.c | 977 | F: drivers/clocksource/timer-atlas7.c |
978 | N: [^a-z]sirf | 978 | N: [^a-z]sirf |
979 | 979 | ||
980 | ARM/EBSA110 MACHINE SUPPORT | 980 | ARM/EBSA110 MACHINE SUPPORT |
diff --git a/arch/arm/boot/dts/versatile-ab.dts b/arch/arm/boot/dts/versatile-ab.dts index 27d0d9c8adf3..01f40197ea13 100644 --- a/arch/arm/boot/dts/versatile-ab.dts +++ b/arch/arm/boot/dts/versatile-ab.dts | |||
@@ -252,6 +252,11 @@ | |||
252 | #size-cells = <1>; | 252 | #size-cells = <1>; |
253 | ranges = <0 0x10000000 0x10000>; | 253 | ranges = <0 0x10000000 0x10000>; |
254 | 254 | ||
255 | sysreg@0 { | ||
256 | compatible = "arm,versatile-sysreg", "syscon"; | ||
257 | reg = <0x00000 0x1000>; | ||
258 | }; | ||
259 | |||
255 | aaci@4000 { | 260 | aaci@4000 { |
256 | compatible = "arm,primecell"; | 261 | compatible = "arm,primecell"; |
257 | reg = <0x4000 0x1000>; | 262 | reg = <0x4000 0x1000>; |
diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig index ac5803cac98d..5078932c1683 100644 --- a/arch/arm/mach-rockchip/Kconfig +++ b/arch/arm/mach-rockchip/Kconfig | |||
@@ -11,6 +11,7 @@ config ARCH_ROCKCHIP | |||
11 | select HAVE_ARM_SCU if SMP | 11 | select HAVE_ARM_SCU if SMP |
12 | select HAVE_ARM_TWD if SMP | 12 | select HAVE_ARM_TWD if SMP |
13 | select DW_APB_TIMER_OF | 13 | select DW_APB_TIMER_OF |
14 | select ROCKCHIP_TIMER | ||
14 | select ARM_GLOBAL_TIMER | 15 | select ARM_GLOBAL_TIMER |
15 | select CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK | 16 | select CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK |
16 | help | 17 | help |
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index 8a1479fc6479..717f40e875fc 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig | |||
@@ -18,6 +18,9 @@ config CLKBLD_I8253 | |||
18 | config CLKSRC_MMIO | 18 | config CLKSRC_MMIO |
19 | bool | 19 | bool |
20 | 20 | ||
21 | config DIGICOLOR_TIMER | ||
22 | bool | ||
23 | |||
21 | config DW_APB_TIMER | 24 | config DW_APB_TIMER |
22 | bool | 25 | bool |
23 | 26 | ||
@@ -26,6 +29,10 @@ config DW_APB_TIMER_OF | |||
26 | select DW_APB_TIMER | 29 | select DW_APB_TIMER |
27 | select CLKSRC_OF | 30 | select CLKSRC_OF |
28 | 31 | ||
32 | config ROCKCHIP_TIMER | ||
33 | bool | ||
34 | select CLKSRC_OF | ||
35 | |||
29 | config ARMADA_370_XP_TIMER | 36 | config ARMADA_370_XP_TIMER |
30 | bool | 37 | bool |
31 | select CLKSRC_OF | 38 | select CLKSRC_OF |
@@ -236,4 +243,14 @@ config CLKSRC_PXA | |||
236 | This enables OST0 support available on PXA and SA-11x0 | 243 | This enables OST0 support available on PXA and SA-11x0 |
237 | platforms. | 244 | platforms. |
238 | 245 | ||
246 | config ASM9260_TIMER | ||
247 | bool "Alphascale ASM9260 timer driver" | ||
248 | depends on GENERIC_CLOCKEVENTS | ||
249 | select CLKSRC_MMIO | ||
250 | select CLKSRC_OF | ||
251 | default y if MACH_ASM9260 | ||
252 | help | ||
253 | This enables build of a clocksource and clockevent driver for | ||
254 | the 32-bit System Timer hardware available on a Alphascale ASM9260. | ||
255 | |||
239 | endmenu | 256 | endmenu |
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile index aa526f4bd3cf..3359121570c7 100644 --- a/drivers/clocksource/Makefile +++ b/drivers/clocksource/Makefile | |||
@@ -10,15 +10,17 @@ obj-$(CONFIG_SH_TIMER_TMU) += sh_tmu.o | |||
10 | obj-$(CONFIG_EM_TIMER_STI) += em_sti.o | 10 | obj-$(CONFIG_EM_TIMER_STI) += em_sti.o |
11 | obj-$(CONFIG_CLKBLD_I8253) += i8253.o | 11 | obj-$(CONFIG_CLKBLD_I8253) += i8253.o |
12 | obj-$(CONFIG_CLKSRC_MMIO) += mmio.o | 12 | obj-$(CONFIG_CLKSRC_MMIO) += mmio.o |
13 | obj-$(CONFIG_DIGICOLOR_TIMER) += timer-digicolor.o | ||
13 | obj-$(CONFIG_DW_APB_TIMER) += dw_apb_timer.o | 14 | obj-$(CONFIG_DW_APB_TIMER) += dw_apb_timer.o |
14 | obj-$(CONFIG_DW_APB_TIMER_OF) += dw_apb_timer_of.o | 15 | obj-$(CONFIG_DW_APB_TIMER_OF) += dw_apb_timer_of.o |
16 | obj-$(CONFIG_ROCKCHIP_TIMER) += rockchip_timer.o | ||
15 | obj-$(CONFIG_CLKSRC_NOMADIK_MTU) += nomadik-mtu.o | 17 | obj-$(CONFIG_CLKSRC_NOMADIK_MTU) += nomadik-mtu.o |
16 | obj-$(CONFIG_CLKSRC_DBX500_PRCMU) += clksrc-dbx500-prcmu.o | 18 | obj-$(CONFIG_CLKSRC_DBX500_PRCMU) += clksrc-dbx500-prcmu.o |
17 | obj-$(CONFIG_ARMADA_370_XP_TIMER) += time-armada-370-xp.o | 19 | obj-$(CONFIG_ARMADA_370_XP_TIMER) += time-armada-370-xp.o |
18 | obj-$(CONFIG_ORION_TIMER) += time-orion.o | 20 | obj-$(CONFIG_ORION_TIMER) += time-orion.o |
19 | obj-$(CONFIG_ARCH_BCM2835) += bcm2835_timer.o | 21 | obj-$(CONFIG_ARCH_BCM2835) += bcm2835_timer.o |
20 | obj-$(CONFIG_ARCH_CLPS711X) += clps711x-timer.o | 22 | obj-$(CONFIG_ARCH_CLPS711X) += clps711x-timer.o |
21 | obj-$(CONFIG_ARCH_MARCO) += timer-marco.o | 23 | obj-$(CONFIG_ARCH_ATLAS7) += timer-atlas7.o |
22 | obj-$(CONFIG_ARCH_MOXART) += moxart_timer.o | 24 | obj-$(CONFIG_ARCH_MOXART) += moxart_timer.o |
23 | obj-$(CONFIG_ARCH_MXS) += mxs_timer.o | 25 | obj-$(CONFIG_ARCH_MXS) += mxs_timer.o |
24 | obj-$(CONFIG_CLKSRC_PXA) += pxa_timer.o | 26 | obj-$(CONFIG_CLKSRC_PXA) += pxa_timer.o |
@@ -48,3 +50,4 @@ obj-$(CONFIG_ARCH_KEYSTONE) += timer-keystone.o | |||
48 | obj-$(CONFIG_ARCH_INTEGRATOR_AP) += timer-integrator-ap.o | 50 | obj-$(CONFIG_ARCH_INTEGRATOR_AP) += timer-integrator-ap.o |
49 | obj-$(CONFIG_CLKSRC_VERSATILE) += versatile.o | 51 | obj-$(CONFIG_CLKSRC_VERSATILE) += versatile.o |
50 | obj-$(CONFIG_CLKSRC_MIPS_GIC) += mips-gic-timer.o | 52 | obj-$(CONFIG_CLKSRC_MIPS_GIC) += mips-gic-timer.o |
53 | obj-$(CONFIG_ASM9260_TIMER) += asm9260_timer.o | ||
diff --git a/drivers/clocksource/asm9260_timer.c b/drivers/clocksource/asm9260_timer.c new file mode 100644 index 000000000000..2c9c993727c8 --- /dev/null +++ b/drivers/clocksource/asm9260_timer.c | |||
@@ -0,0 +1,220 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014 Oleksij Rempel <linux@rempel-privat.de> | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation; either version 2 | ||
7 | * of the License, or (at your option) any later version. | ||
8 | */ | ||
9 | |||
10 | #include <linux/kernel.h> | ||
11 | #include <linux/init.h> | ||
12 | #include <linux/interrupt.h> | ||
13 | #include <linux/sched.h> | ||
14 | #include <linux/clk.h> | ||
15 | #include <linux/clocksource.h> | ||
16 | #include <linux/clockchips.h> | ||
17 | #include <linux/io.h> | ||
18 | #include <linux/of.h> | ||
19 | #include <linux/of_address.h> | ||
20 | #include <linux/of_irq.h> | ||
21 | #include <linux/bitops.h> | ||
22 | |||
23 | #define DRIVER_NAME "asm9260-timer" | ||
24 | |||
25 | /* | ||
26 | * this device provide 4 offsets for each register: | ||
27 | * 0x0 - plain read write mode | ||
28 | * 0x4 - set mode, OR logic. | ||
29 | * 0x8 - clr mode, XOR logic. | ||
30 | * 0xc - togle mode. | ||
31 | */ | ||
32 | #define SET_REG 4 | ||
33 | #define CLR_REG 8 | ||
34 | |||
35 | #define HW_IR 0x0000 /* RW. Interrupt */ | ||
36 | #define BM_IR_CR0 BIT(4) | ||
37 | #define BM_IR_MR3 BIT(3) | ||
38 | #define BM_IR_MR2 BIT(2) | ||
39 | #define BM_IR_MR1 BIT(1) | ||
40 | #define BM_IR_MR0 BIT(0) | ||
41 | |||
42 | #define HW_TCR 0x0010 /* RW. Timer controller */ | ||
43 | /* BM_C*_RST | ||
44 | * Timer Counter and the Prescale Counter are synchronously reset on the | ||
45 | * next positive edge of PCLK. The counters remain reset until TCR[1] is | ||
46 | * returned to zero. */ | ||
47 | #define BM_C3_RST BIT(7) | ||
48 | #define BM_C2_RST BIT(6) | ||
49 | #define BM_C1_RST BIT(5) | ||
50 | #define BM_C0_RST BIT(4) | ||
51 | /* BM_C*_EN | ||
52 | * 1 - Timer Counter and Prescale Counter are enabled for counting | ||
53 | * 0 - counters are disabled */ | ||
54 | #define BM_C3_EN BIT(3) | ||
55 | #define BM_C2_EN BIT(2) | ||
56 | #define BM_C1_EN BIT(1) | ||
57 | #define BM_C0_EN BIT(0) | ||
58 | |||
59 | #define HW_DIR 0x0020 /* RW. Direction? */ | ||
60 | /* 00 - count up | ||
61 | * 01 - count down | ||
62 | * 10 - ?? 2^n/2 */ | ||
63 | #define BM_DIR_COUNT_UP 0 | ||
64 | #define BM_DIR_COUNT_DOWN 1 | ||
65 | #define BM_DIR0_SHIFT 0 | ||
66 | #define BM_DIR1_SHIFT 4 | ||
67 | #define BM_DIR2_SHIFT 8 | ||
68 | #define BM_DIR3_SHIFT 12 | ||
69 | #define BM_DIR_DEFAULT (BM_DIR_COUNT_UP << BM_DIR0_SHIFT | \ | ||
70 | BM_DIR_COUNT_UP << BM_DIR1_SHIFT | \ | ||
71 | BM_DIR_COUNT_UP << BM_DIR2_SHIFT | \ | ||
72 | BM_DIR_COUNT_UP << BM_DIR3_SHIFT) | ||
73 | |||
74 | #define HW_TC0 0x0030 /* RO. Timer counter 0 */ | ||
75 | /* HW_TC*. Timer counter owerflow (0xffff.ffff to 0x0000.0000) do not generate | ||
76 | * interrupt. This registers can be used to detect overflow */ | ||
77 | #define HW_TC1 0x0040 | ||
78 | #define HW_TC2 0x0050 | ||
79 | #define HW_TC3 0x0060 | ||
80 | |||
81 | #define HW_PR 0x0070 /* RW. prescaler */ | ||
82 | #define BM_PR_DISABLE 0 | ||
83 | #define HW_PC 0x0080 /* RO. Prescaler counter */ | ||
84 | #define HW_MCR 0x0090 /* RW. Match control */ | ||
85 | /* enable interrupt on match */ | ||
86 | #define BM_MCR_INT_EN(n) (1 << (n * 3 + 0)) | ||
87 | /* enable TC reset on match */ | ||
88 | #define BM_MCR_RES_EN(n) (1 << (n * 3 + 1)) | ||
89 | /* enable stop TC on match */ | ||
90 | #define BM_MCR_STOP_EN(n) (1 << (n * 3 + 2)) | ||
91 | |||
92 | #define HW_MR0 0x00a0 /* RW. Match reg */ | ||
93 | #define HW_MR1 0x00b0 | ||
94 | #define HW_MR2 0x00C0 | ||
95 | #define HW_MR3 0x00D0 | ||
96 | |||
97 | #define HW_CTCR 0x0180 /* Counter control */ | ||
98 | #define BM_CTCR0_SHIFT 0 | ||
99 | #define BM_CTCR1_SHIFT 2 | ||
100 | #define BM_CTCR2_SHIFT 4 | ||
101 | #define BM_CTCR3_SHIFT 6 | ||
102 | #define BM_CTCR_TM 0 /* Timer mode. Every rising PCLK edge. */ | ||
103 | #define BM_CTCR_DEFAULT (BM_CTCR_TM << BM_CTCR0_SHIFT | \ | ||
104 | BM_CTCR_TM << BM_CTCR1_SHIFT | \ | ||
105 | BM_CTCR_TM << BM_CTCR2_SHIFT | \ | ||
106 | BM_CTCR_TM << BM_CTCR3_SHIFT) | ||
107 | |||
108 | static struct asm9260_timer_priv { | ||
109 | void __iomem *base; | ||
110 | unsigned long ticks_per_jiffy; | ||
111 | } priv; | ||
112 | |||
113 | static int asm9260_timer_set_next_event(unsigned long delta, | ||
114 | struct clock_event_device *evt) | ||
115 | { | ||
116 | /* configure match count for TC0 */ | ||
117 | writel_relaxed(delta, priv.base + HW_MR0); | ||
118 | /* enable TC0 */ | ||
119 | writel_relaxed(BM_C0_EN, priv.base + HW_TCR + SET_REG); | ||
120 | return 0; | ||
121 | } | ||
122 | |||
123 | static void asm9260_timer_set_mode(enum clock_event_mode mode, | ||
124 | struct clock_event_device *evt) | ||
125 | { | ||
126 | /* stop timer0 */ | ||
127 | writel_relaxed(BM_C0_EN, priv.base + HW_TCR + CLR_REG); | ||
128 | |||
129 | switch (mode) { | ||
130 | case CLOCK_EVT_MODE_PERIODIC: | ||
131 | /* disable reset and stop on match */ | ||
132 | writel_relaxed(BM_MCR_RES_EN(0) | BM_MCR_STOP_EN(0), | ||
133 | priv.base + HW_MCR + CLR_REG); | ||
134 | /* configure match count for TC0 */ | ||
135 | writel_relaxed(priv.ticks_per_jiffy, priv.base + HW_MR0); | ||
136 | /* enable TC0 */ | ||
137 | writel_relaxed(BM_C0_EN, priv.base + HW_TCR + SET_REG); | ||
138 | break; | ||
139 | case CLOCK_EVT_MODE_ONESHOT: | ||
140 | /* enable reset and stop on match */ | ||
141 | writel_relaxed(BM_MCR_RES_EN(0) | BM_MCR_STOP_EN(0), | ||
142 | priv.base + HW_MCR + SET_REG); | ||
143 | break; | ||
144 | default: | ||
145 | break; | ||
146 | } | ||
147 | } | ||
148 | |||
149 | static struct clock_event_device event_dev = { | ||
150 | .name = DRIVER_NAME, | ||
151 | .rating = 200, | ||
152 | .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, | ||
153 | .set_next_event = asm9260_timer_set_next_event, | ||
154 | .set_mode = asm9260_timer_set_mode, | ||
155 | }; | ||
156 | |||
157 | static irqreturn_t asm9260_timer_interrupt(int irq, void *dev_id) | ||
158 | { | ||
159 | struct clock_event_device *evt = dev_id; | ||
160 | |||
161 | evt->event_handler(evt); | ||
162 | |||
163 | writel_relaxed(BM_IR_MR0, priv.base + HW_IR); | ||
164 | |||
165 | return IRQ_HANDLED; | ||
166 | } | ||
167 | |||
168 | /* | ||
169 | * --------------------------------------------------------------------------- | ||
170 | * Timer initialization | ||
171 | * --------------------------------------------------------------------------- | ||
172 | */ | ||
173 | static void __init asm9260_timer_init(struct device_node *np) | ||
174 | { | ||
175 | int irq; | ||
176 | struct clk *clk; | ||
177 | int ret; | ||
178 | unsigned long rate; | ||
179 | |||
180 | priv.base = of_io_request_and_map(np, 0, np->name); | ||
181 | if (!priv.base) | ||
182 | panic("%s: unable to map resource", np->name); | ||
183 | |||
184 | clk = of_clk_get(np, 0); | ||
185 | |||
186 | ret = clk_prepare_enable(clk); | ||
187 | if (ret) | ||
188 | panic("Failed to enable clk!\n"); | ||
189 | |||
190 | irq = irq_of_parse_and_map(np, 0); | ||
191 | ret = request_irq(irq, asm9260_timer_interrupt, IRQF_TIMER, | ||
192 | DRIVER_NAME, &event_dev); | ||
193 | if (ret) | ||
194 | panic("Failed to setup irq!\n"); | ||
195 | |||
196 | /* set all timers for count-up */ | ||
197 | writel_relaxed(BM_DIR_DEFAULT, priv.base + HW_DIR); | ||
198 | /* disable divider */ | ||
199 | writel_relaxed(BM_PR_DISABLE, priv.base + HW_PR); | ||
200 | /* make sure all timers use every rising PCLK edge. */ | ||
201 | writel_relaxed(BM_CTCR_DEFAULT, priv.base + HW_CTCR); | ||
202 | /* enable interrupt for TC0 and clean setting for all other lines */ | ||
203 | writel_relaxed(BM_MCR_INT_EN(0) , priv.base + HW_MCR); | ||
204 | |||
205 | rate = clk_get_rate(clk); | ||
206 | clocksource_mmio_init(priv.base + HW_TC1, DRIVER_NAME, rate, | ||
207 | 200, 32, clocksource_mmio_readl_up); | ||
208 | |||
209 | /* Seems like we can't use counter without match register even if | ||
210 | * actions for MR are disabled. So, set MR to max value. */ | ||
211 | writel_relaxed(0xffffffff, priv.base + HW_MR1); | ||
212 | /* enable TC1 */ | ||
213 | writel_relaxed(BM_C1_EN, priv.base + HW_TCR + SET_REG); | ||
214 | |||
215 | priv.ticks_per_jiffy = DIV_ROUND_CLOSEST(rate, HZ); | ||
216 | event_dev.cpumask = cpumask_of(0); | ||
217 | clockevents_config_and_register(&event_dev, rate, 0x2c00, 0xfffffffe); | ||
218 | } | ||
219 | CLOCKSOURCE_OF_DECLARE(asm9260_timer, "alphascale,asm9260-timer", | ||
220 | asm9260_timer_init); | ||
diff --git a/drivers/clocksource/rockchip_timer.c b/drivers/clocksource/rockchip_timer.c new file mode 100644 index 000000000000..a35993bafb20 --- /dev/null +++ b/drivers/clocksource/rockchip_timer.c | |||
@@ -0,0 +1,180 @@ | |||
1 | /* | ||
2 | * Rockchip timer support | ||
3 | * | ||
4 | * Copyright (C) Daniel Lezcano <daniel.lezcano@linaro.org> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | #include <linux/clk.h> | ||
11 | #include <linux/clockchips.h> | ||
12 | #include <linux/init.h> | ||
13 | #include <linux/interrupt.h> | ||
14 | #include <linux/of.h> | ||
15 | #include <linux/of_address.h> | ||
16 | #include <linux/of_irq.h> | ||
17 | |||
18 | #define TIMER_NAME "rk_timer" | ||
19 | |||
20 | #define TIMER_LOAD_COUNT0 0x00 | ||
21 | #define TIMER_LOAD_COUNT1 0x04 | ||
22 | #define TIMER_CONTROL_REG 0x10 | ||
23 | #define TIMER_INT_STATUS 0x18 | ||
24 | |||
25 | #define TIMER_DISABLE 0x0 | ||
26 | #define TIMER_ENABLE 0x1 | ||
27 | #define TIMER_MODE_FREE_RUNNING (0 << 1) | ||
28 | #define TIMER_MODE_USER_DEFINED_COUNT (1 << 1) | ||
29 | #define TIMER_INT_UNMASK (1 << 2) | ||
30 | |||
31 | struct bc_timer { | ||
32 | struct clock_event_device ce; | ||
33 | void __iomem *base; | ||
34 | u32 freq; | ||
35 | }; | ||
36 | |||
37 | static struct bc_timer bc_timer; | ||
38 | |||
39 | static inline struct bc_timer *rk_timer(struct clock_event_device *ce) | ||
40 | { | ||
41 | return container_of(ce, struct bc_timer, ce); | ||
42 | } | ||
43 | |||
44 | static inline void __iomem *rk_base(struct clock_event_device *ce) | ||
45 | { | ||
46 | return rk_timer(ce)->base; | ||
47 | } | ||
48 | |||
49 | static inline void rk_timer_disable(struct clock_event_device *ce) | ||
50 | { | ||
51 | writel_relaxed(TIMER_DISABLE, rk_base(ce) + TIMER_CONTROL_REG); | ||
52 | dsb(); | ||
53 | } | ||
54 | |||
55 | static inline void rk_timer_enable(struct clock_event_device *ce, u32 flags) | ||
56 | { | ||
57 | writel_relaxed(TIMER_ENABLE | TIMER_INT_UNMASK | flags, | ||
58 | rk_base(ce) + TIMER_CONTROL_REG); | ||
59 | dsb(); | ||
60 | } | ||
61 | |||
62 | static void rk_timer_update_counter(unsigned long cycles, | ||
63 | struct clock_event_device *ce) | ||
64 | { | ||
65 | writel_relaxed(cycles, rk_base(ce) + TIMER_LOAD_COUNT0); | ||
66 | writel_relaxed(0, rk_base(ce) + TIMER_LOAD_COUNT1); | ||
67 | dsb(); | ||
68 | } | ||
69 | |||
70 | static void rk_timer_interrupt_clear(struct clock_event_device *ce) | ||
71 | { | ||
72 | writel_relaxed(1, rk_base(ce) + TIMER_INT_STATUS); | ||
73 | dsb(); | ||
74 | } | ||
75 | |||
76 | static inline int rk_timer_set_next_event(unsigned long cycles, | ||
77 | struct clock_event_device *ce) | ||
78 | { | ||
79 | rk_timer_disable(ce); | ||
80 | rk_timer_update_counter(cycles, ce); | ||
81 | rk_timer_enable(ce, TIMER_MODE_USER_DEFINED_COUNT); | ||
82 | return 0; | ||
83 | } | ||
84 | |||
85 | static inline void rk_timer_set_mode(enum clock_event_mode mode, | ||
86 | struct clock_event_device *ce) | ||
87 | { | ||
88 | switch (mode) { | ||
89 | case CLOCK_EVT_MODE_PERIODIC: | ||
90 | rk_timer_disable(ce); | ||
91 | rk_timer_update_counter(rk_timer(ce)->freq / HZ - 1, ce); | ||
92 | rk_timer_enable(ce, TIMER_MODE_FREE_RUNNING); | ||
93 | break; | ||
94 | case CLOCK_EVT_MODE_ONESHOT: | ||
95 | case CLOCK_EVT_MODE_RESUME: | ||
96 | break; | ||
97 | case CLOCK_EVT_MODE_UNUSED: | ||
98 | case CLOCK_EVT_MODE_SHUTDOWN: | ||
99 | rk_timer_disable(ce); | ||
100 | break; | ||
101 | } | ||
102 | } | ||
103 | |||
104 | static irqreturn_t rk_timer_interrupt(int irq, void *dev_id) | ||
105 | { | ||
106 | struct clock_event_device *ce = dev_id; | ||
107 | |||
108 | rk_timer_interrupt_clear(ce); | ||
109 | |||
110 | if (ce->mode == CLOCK_EVT_MODE_ONESHOT) | ||
111 | rk_timer_disable(ce); | ||
112 | |||
113 | ce->event_handler(ce); | ||
114 | |||
115 | return IRQ_HANDLED; | ||
116 | } | ||
117 | |||
118 | static void __init rk_timer_init(struct device_node *np) | ||
119 | { | ||
120 | struct clock_event_device *ce = &bc_timer.ce; | ||
121 | struct clk *timer_clk; | ||
122 | struct clk *pclk; | ||
123 | int ret, irq; | ||
124 | |||
125 | bc_timer.base = of_iomap(np, 0); | ||
126 | if (!bc_timer.base) { | ||
127 | pr_err("Failed to get base address for '%s'\n", TIMER_NAME); | ||
128 | return; | ||
129 | } | ||
130 | |||
131 | pclk = of_clk_get_by_name(np, "pclk"); | ||
132 | if (IS_ERR(pclk)) { | ||
133 | pr_err("Failed to get pclk for '%s'\n", TIMER_NAME); | ||
134 | return; | ||
135 | } | ||
136 | |||
137 | if (clk_prepare_enable(pclk)) { | ||
138 | pr_err("Failed to enable pclk for '%s'\n", TIMER_NAME); | ||
139 | return; | ||
140 | } | ||
141 | |||
142 | timer_clk = of_clk_get_by_name(np, "timer"); | ||
143 | if (IS_ERR(timer_clk)) { | ||
144 | pr_err("Failed to get timer clock for '%s'\n", TIMER_NAME); | ||
145 | return; | ||
146 | } | ||
147 | |||
148 | if (clk_prepare_enable(timer_clk)) { | ||
149 | pr_err("Failed to enable timer clock\n"); | ||
150 | return; | ||
151 | } | ||
152 | |||
153 | bc_timer.freq = clk_get_rate(timer_clk); | ||
154 | |||
155 | irq = irq_of_parse_and_map(np, 0); | ||
156 | if (irq == NO_IRQ) { | ||
157 | pr_err("Failed to map interrupts for '%s'\n", TIMER_NAME); | ||
158 | return; | ||
159 | } | ||
160 | |||
161 | ce->name = TIMER_NAME; | ||
162 | ce->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT; | ||
163 | ce->set_next_event = rk_timer_set_next_event; | ||
164 | ce->set_mode = rk_timer_set_mode; | ||
165 | ce->irq = irq; | ||
166 | ce->cpumask = cpumask_of(0); | ||
167 | ce->rating = 250; | ||
168 | |||
169 | rk_timer_interrupt_clear(ce); | ||
170 | rk_timer_disable(ce); | ||
171 | |||
172 | ret = request_irq(irq, rk_timer_interrupt, IRQF_TIMER, TIMER_NAME, ce); | ||
173 | if (ret) { | ||
174 | pr_err("Failed to initialize '%s': %d\n", TIMER_NAME, ret); | ||
175 | return; | ||
176 | } | ||
177 | |||
178 | clockevents_config_and_register(ce, bc_timer.freq, 1, UINT_MAX); | ||
179 | } | ||
180 | CLOCKSOURCE_OF_DECLARE(rk_timer, "rockchip,rk3288-timer", rk_timer_init); | ||
diff --git a/drivers/clocksource/timer-marco.c b/drivers/clocksource/timer-atlas7.c index 361a789d4bee..60f9de3438b0 100644 --- a/drivers/clocksource/timer-marco.c +++ b/drivers/clocksource/timer-atlas7.c | |||
@@ -38,7 +38,7 @@ | |||
38 | 38 | ||
39 | #define SIRFSOC_TIMER_REG_CNT 6 | 39 | #define SIRFSOC_TIMER_REG_CNT 6 |
40 | 40 | ||
41 | static unsigned long marco_timer_rate; | 41 | static unsigned long atlas7_timer_rate; |
42 | 42 | ||
43 | static const u32 sirfsoc_timer_reg_list[SIRFSOC_TIMER_REG_CNT] = { | 43 | static const u32 sirfsoc_timer_reg_list[SIRFSOC_TIMER_REG_CNT] = { |
44 | SIRFSOC_TIMER_WATCHDOG_EN, | 44 | SIRFSOC_TIMER_WATCHDOG_EN, |
@@ -195,7 +195,7 @@ static int sirfsoc_local_timer_setup(struct clock_event_device *ce) | |||
195 | ce->rating = 200; | 195 | ce->rating = 200; |
196 | ce->set_mode = sirfsoc_timer_set_mode; | 196 | ce->set_mode = sirfsoc_timer_set_mode; |
197 | ce->set_next_event = sirfsoc_timer_set_next_event; | 197 | ce->set_next_event = sirfsoc_timer_set_next_event; |
198 | clockevents_calc_mult_shift(ce, marco_timer_rate, 60); | 198 | clockevents_calc_mult_shift(ce, atlas7_timer_rate, 60); |
199 | ce->max_delta_ns = clockevent_delta2ns(-2, ce); | 199 | ce->max_delta_ns = clockevent_delta2ns(-2, ce); |
200 | ce->min_delta_ns = clockevent_delta2ns(2, ce); | 200 | ce->min_delta_ns = clockevent_delta2ns(2, ce); |
201 | ce->cpumask = cpumask_of(cpu); | 201 | ce->cpumask = cpumask_of(cpu); |
@@ -255,9 +255,8 @@ static void __init sirfsoc_clockevent_init(void) | |||
255 | } | 255 | } |
256 | 256 | ||
257 | /* initialize the kernel jiffy timer source */ | 257 | /* initialize the kernel jiffy timer source */ |
258 | static void __init sirfsoc_marco_timer_init(struct device_node *np) | 258 | static void __init sirfsoc_atlas7_timer_init(struct device_node *np) |
259 | { | 259 | { |
260 | u32 timer_div; | ||
261 | struct clk *clk; | 260 | struct clk *clk; |
262 | 261 | ||
263 | clk = of_clk_get(np, 0); | 262 | clk = of_clk_get(np, 0); |
@@ -265,7 +264,7 @@ static void __init sirfsoc_marco_timer_init(struct device_node *np) | |||
265 | 264 | ||
266 | BUG_ON(clk_prepare_enable(clk)); | 265 | BUG_ON(clk_prepare_enable(clk)); |
267 | 266 | ||
268 | marco_timer_rate = clk_get_rate(clk); | 267 | atlas7_timer_rate = clk_get_rate(clk); |
269 | 268 | ||
270 | /* timer dividers: 0, not divided */ | 269 | /* timer dividers: 0, not divided */ |
271 | writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_64COUNTER_CTRL); | 270 | writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_64COUNTER_CTRL); |
@@ -283,7 +282,7 @@ static void __init sirfsoc_marco_timer_init(struct device_node *np) | |||
283 | /* Clear all interrupts */ | 282 | /* Clear all interrupts */ |
284 | writel_relaxed(0xFFFF, sirfsoc_timer_base + SIRFSOC_TIMER_INTR_STATUS); | 283 | writel_relaxed(0xFFFF, sirfsoc_timer_base + SIRFSOC_TIMER_INTR_STATUS); |
285 | 284 | ||
286 | BUG_ON(clocksource_register_hz(&sirfsoc_clocksource, marco_timer_rate)); | 285 | BUG_ON(clocksource_register_hz(&sirfsoc_clocksource, atlas7_timer_rate)); |
287 | 286 | ||
288 | sirfsoc_clockevent_init(); | 287 | sirfsoc_clockevent_init(); |
289 | } | 288 | } |
@@ -302,6 +301,6 @@ static void __init sirfsoc_of_timer_init(struct device_node *np) | |||
302 | if (!sirfsoc_timer1_irq.irq) | 301 | if (!sirfsoc_timer1_irq.irq) |
303 | panic("No irq passed for timer1 via DT\n"); | 302 | panic("No irq passed for timer1 via DT\n"); |
304 | 303 | ||
305 | sirfsoc_marco_timer_init(np); | 304 | sirfsoc_atlas7_timer_init(np); |
306 | } | 305 | } |
307 | CLOCKSOURCE_OF_DECLARE(sirfsoc_marco_timer, "sirf,marco-tick", sirfsoc_of_timer_init ); | 306 | CLOCKSOURCE_OF_DECLARE(sirfsoc_atlas7_timer, "sirf,atlas7-tick", sirfsoc_of_timer_init); |
diff --git a/drivers/clocksource/timer-digicolor.c b/drivers/clocksource/timer-digicolor.c new file mode 100644 index 000000000000..7f8388cfa810 --- /dev/null +++ b/drivers/clocksource/timer-digicolor.c | |||
@@ -0,0 +1,199 @@ | |||
1 | /* | ||
2 | * Conexant Digicolor timer driver | ||
3 | * | ||
4 | * Author: Baruch Siach <baruch@tkos.co.il> | ||
5 | * | ||
6 | * Copyright (C) 2014 Paradox Innovation Ltd. | ||
7 | * | ||
8 | * Based on: | ||
9 | * Allwinner SoCs hstimer driver | ||
10 | * | ||
11 | * Copyright (C) 2013 Maxime Ripard | ||
12 | * | ||
13 | * Maxime Ripard <maxime.ripard@free-electrons.com> | ||
14 | * | ||
15 | * This file is licensed under the terms of the GNU General Public | ||
16 | * License version 2. This program is licensed "as is" without any | ||
17 | * warranty of any kind, whether express or implied. | ||
18 | */ | ||
19 | |||
20 | /* | ||
21 | * Conexant Digicolor SoCs have 8 configurable timers, named from "Timer A" to | ||
22 | * "Timer H". Timer A is the only one with watchdog support, so it is dedicated | ||
23 | * to the watchdog driver. This driver uses Timer B for sched_clock(), and | ||
24 | * Timer C for clockevents. | ||
25 | */ | ||
26 | |||
27 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
28 | |||
29 | #include <linux/clk.h> | ||
30 | #include <linux/clockchips.h> | ||
31 | #include <linux/interrupt.h> | ||
32 | #include <linux/irq.h> | ||
33 | #include <linux/irqreturn.h> | ||
34 | #include <linux/sched_clock.h> | ||
35 | #include <linux/of.h> | ||
36 | #include <linux/of_address.h> | ||
37 | #include <linux/of_irq.h> | ||
38 | |||
39 | enum { | ||
40 | TIMER_A, | ||
41 | TIMER_B, | ||
42 | TIMER_C, | ||
43 | TIMER_D, | ||
44 | TIMER_E, | ||
45 | TIMER_F, | ||
46 | TIMER_G, | ||
47 | TIMER_H, | ||
48 | }; | ||
49 | |||
50 | #define CONTROL(t) ((t)*8) | ||
51 | #define COUNT(t) ((t)*8 + 4) | ||
52 | |||
53 | #define CONTROL_DISABLE 0 | ||
54 | #define CONTROL_ENABLE BIT(0) | ||
55 | #define CONTROL_MODE(m) ((m) << 4) | ||
56 | #define CONTROL_MODE_ONESHOT CONTROL_MODE(1) | ||
57 | #define CONTROL_MODE_PERIODIC CONTROL_MODE(2) | ||
58 | |||
59 | struct digicolor_timer { | ||
60 | struct clock_event_device ce; | ||
61 | void __iomem *base; | ||
62 | u32 ticks_per_jiffy; | ||
63 | int timer_id; /* one of TIMER_* */ | ||
64 | }; | ||
65 | |||
66 | struct digicolor_timer *dc_timer(struct clock_event_device *ce) | ||
67 | { | ||
68 | return container_of(ce, struct digicolor_timer, ce); | ||
69 | } | ||
70 | |||
71 | static inline void dc_timer_disable(struct clock_event_device *ce) | ||
72 | { | ||
73 | struct digicolor_timer *dt = dc_timer(ce); | ||
74 | writeb(CONTROL_DISABLE, dt->base + CONTROL(dt->timer_id)); | ||
75 | } | ||
76 | |||
77 | static inline void dc_timer_enable(struct clock_event_device *ce, u32 mode) | ||
78 | { | ||
79 | struct digicolor_timer *dt = dc_timer(ce); | ||
80 | writeb(CONTROL_ENABLE | mode, dt->base + CONTROL(dt->timer_id)); | ||
81 | } | ||
82 | |||
83 | static inline void dc_timer_set_count(struct clock_event_device *ce, | ||
84 | unsigned long count) | ||
85 | { | ||
86 | struct digicolor_timer *dt = dc_timer(ce); | ||
87 | writel(count, dt->base + COUNT(dt->timer_id)); | ||
88 | } | ||
89 | |||
90 | static void digicolor_clkevt_mode(enum clock_event_mode mode, | ||
91 | struct clock_event_device *ce) | ||
92 | { | ||
93 | struct digicolor_timer *dt = dc_timer(ce); | ||
94 | |||
95 | switch (mode) { | ||
96 | case CLOCK_EVT_MODE_PERIODIC: | ||
97 | dc_timer_disable(ce); | ||
98 | dc_timer_set_count(ce, dt->ticks_per_jiffy); | ||
99 | dc_timer_enable(ce, CONTROL_MODE_PERIODIC); | ||
100 | break; | ||
101 | case CLOCK_EVT_MODE_ONESHOT: | ||
102 | dc_timer_disable(ce); | ||
103 | dc_timer_enable(ce, CONTROL_MODE_ONESHOT); | ||
104 | break; | ||
105 | case CLOCK_EVT_MODE_UNUSED: | ||
106 | case CLOCK_EVT_MODE_SHUTDOWN: | ||
107 | default: | ||
108 | dc_timer_disable(ce); | ||
109 | break; | ||
110 | } | ||
111 | } | ||
112 | |||
113 | static int digicolor_clkevt_next_event(unsigned long evt, | ||
114 | struct clock_event_device *ce) | ||
115 | { | ||
116 | dc_timer_disable(ce); | ||
117 | dc_timer_set_count(ce, evt); | ||
118 | dc_timer_enable(ce, CONTROL_MODE_ONESHOT); | ||
119 | |||
120 | return 0; | ||
121 | } | ||
122 | |||
123 | static struct digicolor_timer dc_timer_dev = { | ||
124 | .ce = { | ||
125 | .name = "digicolor_tick", | ||
126 | .rating = 340, | ||
127 | .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, | ||
128 | .set_mode = digicolor_clkevt_mode, | ||
129 | .set_next_event = digicolor_clkevt_next_event, | ||
130 | }, | ||
131 | .timer_id = TIMER_C, | ||
132 | }; | ||
133 | |||
134 | static irqreturn_t digicolor_timer_interrupt(int irq, void *dev_id) | ||
135 | { | ||
136 | struct clock_event_device *evt = dev_id; | ||
137 | |||
138 | evt->event_handler(evt); | ||
139 | |||
140 | return IRQ_HANDLED; | ||
141 | } | ||
142 | |||
143 | static u64 digicolor_timer_sched_read(void) | ||
144 | { | ||
145 | return ~readl(dc_timer_dev.base + COUNT(TIMER_B)); | ||
146 | } | ||
147 | |||
148 | static void __init digicolor_timer_init(struct device_node *node) | ||
149 | { | ||
150 | unsigned long rate; | ||
151 | struct clk *clk; | ||
152 | int ret, irq; | ||
153 | |||
154 | /* | ||
155 | * timer registers are shared with the watchdog timer; | ||
156 | * don't map exclusively | ||
157 | */ | ||
158 | dc_timer_dev.base = of_iomap(node, 0); | ||
159 | if (!dc_timer_dev.base) { | ||
160 | pr_err("Can't map registers"); | ||
161 | return; | ||
162 | } | ||
163 | |||
164 | irq = irq_of_parse_and_map(node, dc_timer_dev.timer_id); | ||
165 | if (irq <= 0) { | ||
166 | pr_err("Can't parse IRQ"); | ||
167 | return; | ||
168 | } | ||
169 | |||
170 | clk = of_clk_get(node, 0); | ||
171 | if (IS_ERR(clk)) { | ||
172 | pr_err("Can't get timer clock"); | ||
173 | return; | ||
174 | } | ||
175 | clk_prepare_enable(clk); | ||
176 | rate = clk_get_rate(clk); | ||
177 | dc_timer_dev.ticks_per_jiffy = DIV_ROUND_UP(rate, HZ); | ||
178 | |||
179 | writeb(CONTROL_DISABLE, dc_timer_dev.base + CONTROL(TIMER_B)); | ||
180 | writel(UINT_MAX, dc_timer_dev.base + COUNT(TIMER_B)); | ||
181 | writeb(CONTROL_ENABLE, dc_timer_dev.base + CONTROL(TIMER_B)); | ||
182 | |||
183 | sched_clock_register(digicolor_timer_sched_read, 32, rate); | ||
184 | clocksource_mmio_init(dc_timer_dev.base + COUNT(TIMER_B), node->name, | ||
185 | rate, 340, 32, clocksource_mmio_readl_down); | ||
186 | |||
187 | ret = request_irq(irq, digicolor_timer_interrupt, | ||
188 | IRQF_TIMER | IRQF_IRQPOLL, "digicolor_timerC", | ||
189 | &dc_timer_dev.ce); | ||
190 | if (ret) | ||
191 | pr_warn("request of timer irq %d failed (%d)\n", irq, ret); | ||
192 | |||
193 | dc_timer_dev.ce.cpumask = cpu_possible_mask; | ||
194 | dc_timer_dev.ce.irq = irq; | ||
195 | |||
196 | clockevents_config_and_register(&dc_timer_dev.ce, rate, 0, 0xffffffff); | ||
197 | } | ||
198 | CLOCKSOURCE_OF_DECLARE(conexant_digicolor, "cnxt,cx92755-timer", | ||
199 | digicolor_timer_init); | ||
diff --git a/drivers/clocksource/versatile.c b/drivers/clocksource/versatile.c index 2798e7492234..0a26d3dde6c0 100644 --- a/drivers/clocksource/versatile.c +++ b/drivers/clocksource/versatile.c | |||
@@ -36,5 +36,7 @@ static void __init versatile_sched_clock_init(struct device_node *node) | |||
36 | 36 | ||
37 | sched_clock_register(versatile_sys_24mhz_read, 32, 24000000); | 37 | sched_clock_register(versatile_sys_24mhz_read, 32, 24000000); |
38 | } | 38 | } |
39 | CLOCKSOURCE_OF_DECLARE(versatile, "arm,vexpress-sysreg", | 39 | CLOCKSOURCE_OF_DECLARE(vexpress, "arm,vexpress-sysreg", |
40 | versatile_sched_clock_init); | ||
41 | CLOCKSOURCE_OF_DECLARE(versatile, "arm,versatile-sysreg", | ||
40 | versatile_sched_clock_init); | 42 | versatile_sched_clock_init); |