diff options
author | John Stultz <john.stultz@linaro.org> | 2013-09-26 15:05:54 -0400 |
---|---|---|
committer | John Stultz <john.stultz@linaro.org> | 2013-09-26 15:05:54 -0400 |
commit | 17deb9c2db01c7813611291d251d8c7dbdfd3c9d (patch) | |
tree | 6e023c0be7c64de84dd51a671eb09c5c82b56615 /drivers/clocksource | |
parent | f4e6e1ea19737077d958f2bc6c196eb579d97544 (diff) | |
parent | 389e067032fbb96e439abafae848dd447e4cafb4 (diff) |
Merge remote-tracking branch 'tip/timers/core' into fordlezcano/3.13/sched-clock64-conversion
Update to tip/timers/core and resolve minor conflict.
Conflicts:
drivers/clocksource/samsung_pwm_timer.c
Signed-off-by: John Stultz <john.stultz@linaro.org>
Diffstat (limited to 'drivers/clocksource')
-rw-r--r-- | drivers/clocksource/Kconfig | 1 | ||||
-rw-r--r-- | drivers/clocksource/Makefile | 1 | ||||
-rw-r--r-- | drivers/clocksource/acpi_pm.c | 4 | ||||
-rw-r--r-- | drivers/clocksource/arm_arch_timer.c | 453 | ||||
-rw-r--r-- | drivers/clocksource/arm_global_timer.c | 8 | ||||
-rw-r--r-- | drivers/clocksource/bcm_kona_timer.c | 8 | ||||
-rw-r--r-- | drivers/clocksource/cadence_ttc_timer.c | 13 | ||||
-rw-r--r-- | drivers/clocksource/dummy_timer.c | 6 | ||||
-rw-r--r-- | drivers/clocksource/em_sti.c | 49 | ||||
-rw-r--r-- | drivers/clocksource/exynos_mct.c | 60 | ||||
-rw-r--r-- | drivers/clocksource/metag_generic.c | 6 | ||||
-rw-r--r-- | drivers/clocksource/moxart_timer.c | 165 | ||||
-rw-r--r-- | drivers/clocksource/nomadik-mtu.c | 3 | ||||
-rw-r--r-- | drivers/clocksource/samsung_pwm_timer.c | 120 | ||||
-rw-r--r-- | drivers/clocksource/sh_cmt.c | 50 | ||||
-rw-r--r-- | drivers/clocksource/sun4i_timer.c | 110 | ||||
-rw-r--r-- | drivers/clocksource/time-armada-370-xp.c | 225 | ||||
-rw-r--r-- | drivers/clocksource/time-orion.c | 2 | ||||
-rw-r--r-- | drivers/clocksource/timer-marco.c | 100 |
19 files changed, 994 insertions, 390 deletions
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index b7b9b040a89b..41c69469ce20 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig | |||
@@ -99,7 +99,6 @@ config CLKSRC_EXYNOS_MCT | |||
99 | 99 | ||
100 | config CLKSRC_SAMSUNG_PWM | 100 | config CLKSRC_SAMSUNG_PWM |
101 | bool | 101 | bool |
102 | select CLKSRC_MMIO | ||
103 | help | 102 | help |
104 | This is a new clocksource driver for the PWM timer found in | 103 | This is a new clocksource driver for the PWM timer found in |
105 | Samsung S3C, S5P and Exynos SoCs, replacing an earlier driver | 104 | Samsung S3C, S5P and Exynos SoCs, replacing an earlier driver |
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile index 8b00c5cebfa4..704d6d342adc 100644 --- a/drivers/clocksource/Makefile +++ b/drivers/clocksource/Makefile | |||
@@ -18,6 +18,7 @@ obj-$(CONFIG_ARMADA_370_XP_TIMER) += time-armada-370-xp.o | |||
18 | obj-$(CONFIG_ORION_TIMER) += time-orion.o | 18 | obj-$(CONFIG_ORION_TIMER) += time-orion.o |
19 | obj-$(CONFIG_ARCH_BCM2835) += bcm2835_timer.o | 19 | obj-$(CONFIG_ARCH_BCM2835) += bcm2835_timer.o |
20 | obj-$(CONFIG_ARCH_MARCO) += timer-marco.o | 20 | obj-$(CONFIG_ARCH_MARCO) += timer-marco.o |
21 | obj-$(CONFIG_ARCH_MOXART) += moxart_timer.o | ||
21 | obj-$(CONFIG_ARCH_MXS) += mxs_timer.o | 22 | obj-$(CONFIG_ARCH_MXS) += mxs_timer.o |
22 | obj-$(CONFIG_ARCH_PRIMA2) += timer-prima2.o | 23 | obj-$(CONFIG_ARCH_PRIMA2) += timer-prima2.o |
23 | obj-$(CONFIG_SUN4I_TIMER) += sun4i_timer.o | 24 | obj-$(CONFIG_SUN4I_TIMER) += sun4i_timer.o |
diff --git a/drivers/clocksource/acpi_pm.c b/drivers/clocksource/acpi_pm.c index 6efe4d1ab3aa..6eab88985670 100644 --- a/drivers/clocksource/acpi_pm.c +++ b/drivers/clocksource/acpi_pm.c | |||
@@ -200,14 +200,14 @@ static int __init init_acpi_pm_clocksource(void) | |||
200 | if ((value2 < value1) && ((value2) < 0xFFF)) | 200 | if ((value2 < value1) && ((value2) < 0xFFF)) |
201 | break; | 201 | break; |
202 | printk(KERN_INFO "PM-Timer had inconsistent results:" | 202 | printk(KERN_INFO "PM-Timer had inconsistent results:" |
203 | " 0x%#llx, 0x%#llx - aborting.\n", | 203 | " %#llx, %#llx - aborting.\n", |
204 | value1, value2); | 204 | value1, value2); |
205 | pmtmr_ioport = 0; | 205 | pmtmr_ioport = 0; |
206 | return -EINVAL; | 206 | return -EINVAL; |
207 | } | 207 | } |
208 | if (i == ACPI_PM_READ_CHECKS) { | 208 | if (i == ACPI_PM_READ_CHECKS) { |
209 | printk(KERN_INFO "PM-Timer failed consistency check " | 209 | printk(KERN_INFO "PM-Timer failed consistency check " |
210 | " (0x%#llx) - aborting.\n", value1); | 210 | " (%#llx) - aborting.\n", value1); |
211 | pmtmr_ioport = 0; | 211 | pmtmr_ioport = 0; |
212 | return -ENODEV; | 212 | return -ENODEV; |
213 | } | 213 | } |
diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c index 053d846ab5b1..fbd9ccd5e114 100644 --- a/drivers/clocksource/arm_arch_timer.c +++ b/drivers/clocksource/arm_arch_timer.c | |||
@@ -16,13 +16,39 @@ | |||
16 | #include <linux/clockchips.h> | 16 | #include <linux/clockchips.h> |
17 | #include <linux/interrupt.h> | 17 | #include <linux/interrupt.h> |
18 | #include <linux/of_irq.h> | 18 | #include <linux/of_irq.h> |
19 | #include <linux/of_address.h> | ||
19 | #include <linux/io.h> | 20 | #include <linux/io.h> |
21 | #include <linux/slab.h> | ||
20 | 22 | ||
21 | #include <asm/arch_timer.h> | 23 | #include <asm/arch_timer.h> |
22 | #include <asm/virt.h> | 24 | #include <asm/virt.h> |
23 | 25 | ||
24 | #include <clocksource/arm_arch_timer.h> | 26 | #include <clocksource/arm_arch_timer.h> |
25 | 27 | ||
28 | #define CNTTIDR 0x08 | ||
29 | #define CNTTIDR_VIRT(n) (BIT(1) << ((n) * 4)) | ||
30 | |||
31 | #define CNTVCT_LO 0x08 | ||
32 | #define CNTVCT_HI 0x0c | ||
33 | #define CNTFRQ 0x10 | ||
34 | #define CNTP_TVAL 0x28 | ||
35 | #define CNTP_CTL 0x2c | ||
36 | #define CNTV_TVAL 0x38 | ||
37 | #define CNTV_CTL 0x3c | ||
38 | |||
39 | #define ARCH_CP15_TIMER BIT(0) | ||
40 | #define ARCH_MEM_TIMER BIT(1) | ||
41 | static unsigned arch_timers_present __initdata; | ||
42 | |||
43 | static void __iomem *arch_counter_base; | ||
44 | |||
45 | struct arch_timer { | ||
46 | void __iomem *base; | ||
47 | struct clock_event_device evt; | ||
48 | }; | ||
49 | |||
50 | #define to_arch_timer(e) container_of(e, struct arch_timer, evt) | ||
51 | |||
26 | static u32 arch_timer_rate; | 52 | static u32 arch_timer_rate; |
27 | 53 | ||
28 | enum ppi_nr { | 54 | enum ppi_nr { |
@@ -38,19 +64,83 @@ static int arch_timer_ppi[MAX_TIMER_PPI]; | |||
38 | static struct clock_event_device __percpu *arch_timer_evt; | 64 | static struct clock_event_device __percpu *arch_timer_evt; |
39 | 65 | ||
40 | static bool arch_timer_use_virtual = true; | 66 | static bool arch_timer_use_virtual = true; |
67 | static bool arch_timer_mem_use_virtual; | ||
41 | 68 | ||
42 | /* | 69 | /* |
43 | * Architected system timer support. | 70 | * Architected system timer support. |
44 | */ | 71 | */ |
45 | 72 | ||
46 | static inline irqreturn_t timer_handler(const int access, | 73 | static __always_inline |
74 | void arch_timer_reg_write(int access, enum arch_timer_reg reg, u32 val, | ||
75 | struct clock_event_device *clk) | ||
76 | { | ||
77 | if (access == ARCH_TIMER_MEM_PHYS_ACCESS) { | ||
78 | struct arch_timer *timer = to_arch_timer(clk); | ||
79 | switch (reg) { | ||
80 | case ARCH_TIMER_REG_CTRL: | ||
81 | writel_relaxed(val, timer->base + CNTP_CTL); | ||
82 | break; | ||
83 | case ARCH_TIMER_REG_TVAL: | ||
84 | writel_relaxed(val, timer->base + CNTP_TVAL); | ||
85 | break; | ||
86 | } | ||
87 | } else if (access == ARCH_TIMER_MEM_VIRT_ACCESS) { | ||
88 | struct arch_timer *timer = to_arch_timer(clk); | ||
89 | switch (reg) { | ||
90 | case ARCH_TIMER_REG_CTRL: | ||
91 | writel_relaxed(val, timer->base + CNTV_CTL); | ||
92 | break; | ||
93 | case ARCH_TIMER_REG_TVAL: | ||
94 | writel_relaxed(val, timer->base + CNTV_TVAL); | ||
95 | break; | ||
96 | } | ||
97 | } else { | ||
98 | arch_timer_reg_write_cp15(access, reg, val); | ||
99 | } | ||
100 | } | ||
101 | |||
102 | static __always_inline | ||
103 | u32 arch_timer_reg_read(int access, enum arch_timer_reg reg, | ||
104 | struct clock_event_device *clk) | ||
105 | { | ||
106 | u32 val; | ||
107 | |||
108 | if (access == ARCH_TIMER_MEM_PHYS_ACCESS) { | ||
109 | struct arch_timer *timer = to_arch_timer(clk); | ||
110 | switch (reg) { | ||
111 | case ARCH_TIMER_REG_CTRL: | ||
112 | val = readl_relaxed(timer->base + CNTP_CTL); | ||
113 | break; | ||
114 | case ARCH_TIMER_REG_TVAL: | ||
115 | val = readl_relaxed(timer->base + CNTP_TVAL); | ||
116 | break; | ||
117 | } | ||
118 | } else if (access == ARCH_TIMER_MEM_VIRT_ACCESS) { | ||
119 | struct arch_timer *timer = to_arch_timer(clk); | ||
120 | switch (reg) { | ||
121 | case ARCH_TIMER_REG_CTRL: | ||
122 | val = readl_relaxed(timer->base + CNTV_CTL); | ||
123 | break; | ||
124 | case ARCH_TIMER_REG_TVAL: | ||
125 | val = readl_relaxed(timer->base + CNTV_TVAL); | ||
126 | break; | ||
127 | } | ||
128 | } else { | ||
129 | val = arch_timer_reg_read_cp15(access, reg); | ||
130 | } | ||
131 | |||
132 | return val; | ||
133 | } | ||
134 | |||
135 | static __always_inline irqreturn_t timer_handler(const int access, | ||
47 | struct clock_event_device *evt) | 136 | struct clock_event_device *evt) |
48 | { | 137 | { |
49 | unsigned long ctrl; | 138 | unsigned long ctrl; |
50 | ctrl = arch_timer_reg_read(access, ARCH_TIMER_REG_CTRL); | 139 | |
140 | ctrl = arch_timer_reg_read(access, ARCH_TIMER_REG_CTRL, evt); | ||
51 | if (ctrl & ARCH_TIMER_CTRL_IT_STAT) { | 141 | if (ctrl & ARCH_TIMER_CTRL_IT_STAT) { |
52 | ctrl |= ARCH_TIMER_CTRL_IT_MASK; | 142 | ctrl |= ARCH_TIMER_CTRL_IT_MASK; |
53 | arch_timer_reg_write(access, ARCH_TIMER_REG_CTRL, ctrl); | 143 | arch_timer_reg_write(access, ARCH_TIMER_REG_CTRL, ctrl, evt); |
54 | evt->event_handler(evt); | 144 | evt->event_handler(evt); |
55 | return IRQ_HANDLED; | 145 | return IRQ_HANDLED; |
56 | } | 146 | } |
@@ -72,15 +162,30 @@ static irqreturn_t arch_timer_handler_phys(int irq, void *dev_id) | |||
72 | return timer_handler(ARCH_TIMER_PHYS_ACCESS, evt); | 162 | return timer_handler(ARCH_TIMER_PHYS_ACCESS, evt); |
73 | } | 163 | } |
74 | 164 | ||
75 | static inline void timer_set_mode(const int access, int mode) | 165 | static irqreturn_t arch_timer_handler_phys_mem(int irq, void *dev_id) |
166 | { | ||
167 | struct clock_event_device *evt = dev_id; | ||
168 | |||
169 | return timer_handler(ARCH_TIMER_MEM_PHYS_ACCESS, evt); | ||
170 | } | ||
171 | |||
172 | static irqreturn_t arch_timer_handler_virt_mem(int irq, void *dev_id) | ||
173 | { | ||
174 | struct clock_event_device *evt = dev_id; | ||
175 | |||
176 | return timer_handler(ARCH_TIMER_MEM_VIRT_ACCESS, evt); | ||
177 | } | ||
178 | |||
179 | static __always_inline void timer_set_mode(const int access, int mode, | ||
180 | struct clock_event_device *clk) | ||
76 | { | 181 | { |
77 | unsigned long ctrl; | 182 | unsigned long ctrl; |
78 | switch (mode) { | 183 | switch (mode) { |
79 | case CLOCK_EVT_MODE_UNUSED: | 184 | case CLOCK_EVT_MODE_UNUSED: |
80 | case CLOCK_EVT_MODE_SHUTDOWN: | 185 | case CLOCK_EVT_MODE_SHUTDOWN: |
81 | ctrl = arch_timer_reg_read(access, ARCH_TIMER_REG_CTRL); | 186 | ctrl = arch_timer_reg_read(access, ARCH_TIMER_REG_CTRL, clk); |
82 | ctrl &= ~ARCH_TIMER_CTRL_ENABLE; | 187 | ctrl &= ~ARCH_TIMER_CTRL_ENABLE; |
83 | arch_timer_reg_write(access, ARCH_TIMER_REG_CTRL, ctrl); | 188 | arch_timer_reg_write(access, ARCH_TIMER_REG_CTRL, ctrl, clk); |
84 | break; | 189 | break; |
85 | default: | 190 | default: |
86 | break; | 191 | break; |
@@ -90,60 +195,108 @@ static inline void timer_set_mode(const int access, int mode) | |||
90 | static void arch_timer_set_mode_virt(enum clock_event_mode mode, | 195 | static void arch_timer_set_mode_virt(enum clock_event_mode mode, |
91 | struct clock_event_device *clk) | 196 | struct clock_event_device *clk) |
92 | { | 197 | { |
93 | timer_set_mode(ARCH_TIMER_VIRT_ACCESS, mode); | 198 | timer_set_mode(ARCH_TIMER_VIRT_ACCESS, mode, clk); |
94 | } | 199 | } |
95 | 200 | ||
96 | static void arch_timer_set_mode_phys(enum clock_event_mode mode, | 201 | static void arch_timer_set_mode_phys(enum clock_event_mode mode, |
97 | struct clock_event_device *clk) | 202 | struct clock_event_device *clk) |
98 | { | 203 | { |
99 | timer_set_mode(ARCH_TIMER_PHYS_ACCESS, mode); | 204 | timer_set_mode(ARCH_TIMER_PHYS_ACCESS, mode, clk); |
205 | } | ||
206 | |||
207 | static void arch_timer_set_mode_virt_mem(enum clock_event_mode mode, | ||
208 | struct clock_event_device *clk) | ||
209 | { | ||
210 | timer_set_mode(ARCH_TIMER_MEM_VIRT_ACCESS, mode, clk); | ||
100 | } | 211 | } |
101 | 212 | ||
102 | static inline void set_next_event(const int access, unsigned long evt) | 213 | static void arch_timer_set_mode_phys_mem(enum clock_event_mode mode, |
214 | struct clock_event_device *clk) | ||
215 | { | ||
216 | timer_set_mode(ARCH_TIMER_MEM_PHYS_ACCESS, mode, clk); | ||
217 | } | ||
218 | |||
219 | static __always_inline void set_next_event(const int access, unsigned long evt, | ||
220 | struct clock_event_device *clk) | ||
103 | { | 221 | { |
104 | unsigned long ctrl; | 222 | unsigned long ctrl; |
105 | ctrl = arch_timer_reg_read(access, ARCH_TIMER_REG_CTRL); | 223 | ctrl = arch_timer_reg_read(access, ARCH_TIMER_REG_CTRL, clk); |
106 | ctrl |= ARCH_TIMER_CTRL_ENABLE; | 224 | ctrl |= ARCH_TIMER_CTRL_ENABLE; |
107 | ctrl &= ~ARCH_TIMER_CTRL_IT_MASK; | 225 | ctrl &= ~ARCH_TIMER_CTRL_IT_MASK; |
108 | arch_timer_reg_write(access, ARCH_TIMER_REG_TVAL, evt); | 226 | arch_timer_reg_write(access, ARCH_TIMER_REG_TVAL, evt, clk); |
109 | arch_timer_reg_write(access, ARCH_TIMER_REG_CTRL, ctrl); | 227 | arch_timer_reg_write(access, ARCH_TIMER_REG_CTRL, ctrl, clk); |
110 | } | 228 | } |
111 | 229 | ||
112 | static int arch_timer_set_next_event_virt(unsigned long evt, | 230 | static int arch_timer_set_next_event_virt(unsigned long evt, |
113 | struct clock_event_device *unused) | 231 | struct clock_event_device *clk) |
114 | { | 232 | { |
115 | set_next_event(ARCH_TIMER_VIRT_ACCESS, evt); | 233 | set_next_event(ARCH_TIMER_VIRT_ACCESS, evt, clk); |
116 | return 0; | 234 | return 0; |
117 | } | 235 | } |
118 | 236 | ||
119 | static int arch_timer_set_next_event_phys(unsigned long evt, | 237 | static int arch_timer_set_next_event_phys(unsigned long evt, |
120 | struct clock_event_device *unused) | 238 | struct clock_event_device *clk) |
121 | { | 239 | { |
122 | set_next_event(ARCH_TIMER_PHYS_ACCESS, evt); | 240 | set_next_event(ARCH_TIMER_PHYS_ACCESS, evt, clk); |
123 | return 0; | 241 | return 0; |
124 | } | 242 | } |
125 | 243 | ||
126 | static int __cpuinit arch_timer_setup(struct clock_event_device *clk) | 244 | static int arch_timer_set_next_event_virt_mem(unsigned long evt, |
245 | struct clock_event_device *clk) | ||
127 | { | 246 | { |
128 | clk->features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_C3STOP; | 247 | set_next_event(ARCH_TIMER_MEM_VIRT_ACCESS, evt, clk); |
129 | clk->name = "arch_sys_timer"; | 248 | return 0; |
130 | clk->rating = 450; | 249 | } |
131 | if (arch_timer_use_virtual) { | 250 | |
132 | clk->irq = arch_timer_ppi[VIRT_PPI]; | 251 | static int arch_timer_set_next_event_phys_mem(unsigned long evt, |
133 | clk->set_mode = arch_timer_set_mode_virt; | 252 | struct clock_event_device *clk) |
134 | clk->set_next_event = arch_timer_set_next_event_virt; | 253 | { |
254 | set_next_event(ARCH_TIMER_MEM_PHYS_ACCESS, evt, clk); | ||
255 | return 0; | ||
256 | } | ||
257 | |||
258 | static void __arch_timer_setup(unsigned type, | ||
259 | struct clock_event_device *clk) | ||
260 | { | ||
261 | clk->features = CLOCK_EVT_FEAT_ONESHOT; | ||
262 | |||
263 | if (type == ARCH_CP15_TIMER) { | ||
264 | clk->features |= CLOCK_EVT_FEAT_C3STOP; | ||
265 | clk->name = "arch_sys_timer"; | ||
266 | clk->rating = 450; | ||
267 | clk->cpumask = cpumask_of(smp_processor_id()); | ||
268 | if (arch_timer_use_virtual) { | ||
269 | clk->irq = arch_timer_ppi[VIRT_PPI]; | ||
270 | clk->set_mode = arch_timer_set_mode_virt; | ||
271 | clk->set_next_event = arch_timer_set_next_event_virt; | ||
272 | } else { | ||
273 | clk->irq = arch_timer_ppi[PHYS_SECURE_PPI]; | ||
274 | clk->set_mode = arch_timer_set_mode_phys; | ||
275 | clk->set_next_event = arch_timer_set_next_event_phys; | ||
276 | } | ||
135 | } else { | 277 | } else { |
136 | clk->irq = arch_timer_ppi[PHYS_SECURE_PPI]; | 278 | clk->name = "arch_mem_timer"; |
137 | clk->set_mode = arch_timer_set_mode_phys; | 279 | clk->rating = 400; |
138 | clk->set_next_event = arch_timer_set_next_event_phys; | 280 | clk->cpumask = cpu_all_mask; |
281 | if (arch_timer_mem_use_virtual) { | ||
282 | clk->set_mode = arch_timer_set_mode_virt_mem; | ||
283 | clk->set_next_event = | ||
284 | arch_timer_set_next_event_virt_mem; | ||
285 | } else { | ||
286 | clk->set_mode = arch_timer_set_mode_phys_mem; | ||
287 | clk->set_next_event = | ||
288 | arch_timer_set_next_event_phys_mem; | ||
289 | } | ||
139 | } | 290 | } |
140 | 291 | ||
141 | clk->cpumask = cpumask_of(smp_processor_id()); | 292 | clk->set_mode(CLOCK_EVT_MODE_SHUTDOWN, clk); |
142 | 293 | ||
143 | clk->set_mode(CLOCK_EVT_MODE_SHUTDOWN, NULL); | 294 | clockevents_config_and_register(clk, arch_timer_rate, 0xf, 0x7fffffff); |
295 | } | ||
144 | 296 | ||
145 | clockevents_config_and_register(clk, arch_timer_rate, | 297 | static int arch_timer_setup(struct clock_event_device *clk) |
146 | 0xf, 0x7fffffff); | 298 | { |
299 | __arch_timer_setup(ARCH_CP15_TIMER, clk); | ||
147 | 300 | ||
148 | if (arch_timer_use_virtual) | 301 | if (arch_timer_use_virtual) |
149 | enable_percpu_irq(arch_timer_ppi[VIRT_PPI], 0); | 302 | enable_percpu_irq(arch_timer_ppi[VIRT_PPI], 0); |
@@ -158,27 +311,41 @@ static int __cpuinit arch_timer_setup(struct clock_event_device *clk) | |||
158 | return 0; | 311 | return 0; |
159 | } | 312 | } |
160 | 313 | ||
161 | static int arch_timer_available(void) | 314 | static void |
315 | arch_timer_detect_rate(void __iomem *cntbase, struct device_node *np) | ||
162 | { | 316 | { |
163 | u32 freq; | 317 | /* Who has more than one independent system counter? */ |
164 | 318 | if (arch_timer_rate) | |
165 | if (arch_timer_rate == 0) { | 319 | return; |
166 | freq = arch_timer_get_cntfrq(); | ||
167 | |||
168 | /* Check the timer frequency. */ | ||
169 | if (freq == 0) { | ||
170 | pr_warn("Architected timer frequency not available\n"); | ||
171 | return -EINVAL; | ||
172 | } | ||
173 | 320 | ||
174 | arch_timer_rate = freq; | 321 | /* Try to determine the frequency from the device tree or CNTFRQ */ |
322 | if (of_property_read_u32(np, "clock-frequency", &arch_timer_rate)) { | ||
323 | if (cntbase) | ||
324 | arch_timer_rate = readl_relaxed(cntbase + CNTFRQ); | ||
325 | else | ||
326 | arch_timer_rate = arch_timer_get_cntfrq(); | ||
175 | } | 327 | } |
176 | 328 | ||
177 | pr_info_once("Architected local timer running at %lu.%02luMHz (%s).\n", | 329 | /* Check the timer frequency. */ |
330 | if (arch_timer_rate == 0) | ||
331 | pr_warn("Architected timer frequency not available\n"); | ||
332 | } | ||
333 | |||
334 | static void arch_timer_banner(unsigned type) | ||
335 | { | ||
336 | pr_info("Architected %s%s%s timer(s) running at %lu.%02luMHz (%s%s%s).\n", | ||
337 | type & ARCH_CP15_TIMER ? "cp15" : "", | ||
338 | type == (ARCH_CP15_TIMER | ARCH_MEM_TIMER) ? " and " : "", | ||
339 | type & ARCH_MEM_TIMER ? "mmio" : "", | ||
178 | (unsigned long)arch_timer_rate / 1000000, | 340 | (unsigned long)arch_timer_rate / 1000000, |
179 | (unsigned long)(arch_timer_rate / 10000) % 100, | 341 | (unsigned long)(arch_timer_rate / 10000) % 100, |
180 | arch_timer_use_virtual ? "virt" : "phys"); | 342 | type & ARCH_CP15_TIMER ? |
181 | return 0; | 343 | arch_timer_use_virtual ? "virt" : "phys" : |
344 | "", | ||
345 | type == (ARCH_CP15_TIMER | ARCH_MEM_TIMER) ? "/" : "", | ||
346 | type & ARCH_MEM_TIMER ? | ||
347 | arch_timer_mem_use_virtual ? "virt" : "phys" : | ||
348 | ""); | ||
182 | } | 349 | } |
183 | 350 | ||
184 | u32 arch_timer_get_rate(void) | 351 | u32 arch_timer_get_rate(void) |
@@ -186,19 +353,35 @@ u32 arch_timer_get_rate(void) | |||
186 | return arch_timer_rate; | 353 | return arch_timer_rate; |
187 | } | 354 | } |
188 | 355 | ||
189 | u64 arch_timer_read_counter(void) | 356 | static u64 arch_counter_get_cntvct_mem(void) |
190 | { | 357 | { |
191 | return arch_counter_get_cntvct(); | 358 | u32 vct_lo, vct_hi, tmp_hi; |
359 | |||
360 | do { | ||
361 | vct_hi = readl_relaxed(arch_counter_base + CNTVCT_HI); | ||
362 | vct_lo = readl_relaxed(arch_counter_base + CNTVCT_LO); | ||
363 | tmp_hi = readl_relaxed(arch_counter_base + CNTVCT_HI); | ||
364 | } while (vct_hi != tmp_hi); | ||
365 | |||
366 | return ((u64) vct_hi << 32) | vct_lo; | ||
192 | } | 367 | } |
193 | 368 | ||
369 | /* | ||
370 | * Default to cp15 based access because arm64 uses this function for | ||
371 | * sched_clock() before DT is probed and the cp15 method is guaranteed | ||
372 | * to exist on arm64. arm doesn't use this before DT is probed so even | ||
373 | * if we don't have the cp15 accessors we won't have a problem. | ||
374 | */ | ||
375 | u64 (*arch_timer_read_counter)(void) = arch_counter_get_cntvct; | ||
376 | |||
194 | static cycle_t arch_counter_read(struct clocksource *cs) | 377 | static cycle_t arch_counter_read(struct clocksource *cs) |
195 | { | 378 | { |
196 | return arch_counter_get_cntvct(); | 379 | return arch_timer_read_counter(); |
197 | } | 380 | } |
198 | 381 | ||
199 | static cycle_t arch_counter_read_cc(const struct cyclecounter *cc) | 382 | static cycle_t arch_counter_read_cc(const struct cyclecounter *cc) |
200 | { | 383 | { |
201 | return arch_counter_get_cntvct(); | 384 | return arch_timer_read_counter(); |
202 | } | 385 | } |
203 | 386 | ||
204 | static struct clocksource clocksource_counter = { | 387 | static struct clocksource clocksource_counter = { |
@@ -221,7 +404,24 @@ struct timecounter *arch_timer_get_timecounter(void) | |||
221 | return &timecounter; | 404 | return &timecounter; |
222 | } | 405 | } |
223 | 406 | ||
224 | static void __cpuinit arch_timer_stop(struct clock_event_device *clk) | 407 | static void __init arch_counter_register(unsigned type) |
408 | { | ||
409 | u64 start_count; | ||
410 | |||
411 | /* Register the CP15 based counter if we have one */ | ||
412 | if (type & ARCH_CP15_TIMER) | ||
413 | arch_timer_read_counter = arch_counter_get_cntvct; | ||
414 | else | ||
415 | arch_timer_read_counter = arch_counter_get_cntvct_mem; | ||
416 | |||
417 | start_count = arch_timer_read_counter(); | ||
418 | clocksource_register_hz(&clocksource_counter, arch_timer_rate); | ||
419 | cyclecounter.mult = clocksource_counter.mult; | ||
420 | cyclecounter.shift = clocksource_counter.shift; | ||
421 | timecounter_init(&timecounter, &cyclecounter, start_count); | ||
422 | } | ||
423 | |||
424 | static void arch_timer_stop(struct clock_event_device *clk) | ||
225 | { | 425 | { |
226 | pr_debug("arch_timer_teardown disable IRQ%d cpu #%d\n", | 426 | pr_debug("arch_timer_teardown disable IRQ%d cpu #%d\n", |
227 | clk->irq, smp_processor_id()); | 427 | clk->irq, smp_processor_id()); |
@@ -237,7 +437,7 @@ static void __cpuinit arch_timer_stop(struct clock_event_device *clk) | |||
237 | clk->set_mode(CLOCK_EVT_MODE_UNUSED, clk); | 437 | clk->set_mode(CLOCK_EVT_MODE_UNUSED, clk); |
238 | } | 438 | } |
239 | 439 | ||
240 | static int __cpuinit arch_timer_cpu_notify(struct notifier_block *self, | 440 | static int arch_timer_cpu_notify(struct notifier_block *self, |
241 | unsigned long action, void *hcpu) | 441 | unsigned long action, void *hcpu) |
242 | { | 442 | { |
243 | /* | 443 | /* |
@@ -256,7 +456,7 @@ static int __cpuinit arch_timer_cpu_notify(struct notifier_block *self, | |||
256 | return NOTIFY_OK; | 456 | return NOTIFY_OK; |
257 | } | 457 | } |
258 | 458 | ||
259 | static struct notifier_block arch_timer_cpu_nb __cpuinitdata = { | 459 | static struct notifier_block arch_timer_cpu_nb = { |
260 | .notifier_call = arch_timer_cpu_notify, | 460 | .notifier_call = arch_timer_cpu_notify, |
261 | }; | 461 | }; |
262 | 462 | ||
@@ -265,22 +465,12 @@ static int __init arch_timer_register(void) | |||
265 | int err; | 465 | int err; |
266 | int ppi; | 466 | int ppi; |
267 | 467 | ||
268 | err = arch_timer_available(); | ||
269 | if (err) | ||
270 | goto out; | ||
271 | |||
272 | arch_timer_evt = alloc_percpu(struct clock_event_device); | 468 | arch_timer_evt = alloc_percpu(struct clock_event_device); |
273 | if (!arch_timer_evt) { | 469 | if (!arch_timer_evt) { |
274 | err = -ENOMEM; | 470 | err = -ENOMEM; |
275 | goto out; | 471 | goto out; |
276 | } | 472 | } |
277 | 473 | ||
278 | clocksource_register_hz(&clocksource_counter, arch_timer_rate); | ||
279 | cyclecounter.mult = clocksource_counter.mult; | ||
280 | cyclecounter.shift = clocksource_counter.shift; | ||
281 | timecounter_init(&timecounter, &cyclecounter, | ||
282 | arch_counter_get_cntvct()); | ||
283 | |||
284 | if (arch_timer_use_virtual) { | 474 | if (arch_timer_use_virtual) { |
285 | ppi = arch_timer_ppi[VIRT_PPI]; | 475 | ppi = arch_timer_ppi[VIRT_PPI]; |
286 | err = request_percpu_irq(ppi, arch_timer_handler_virt, | 476 | err = request_percpu_irq(ppi, arch_timer_handler_virt, |
@@ -331,24 +521,77 @@ out: | |||
331 | return err; | 521 | return err; |
332 | } | 522 | } |
333 | 523 | ||
524 | static int __init arch_timer_mem_register(void __iomem *base, unsigned int irq) | ||
525 | { | ||
526 | int ret; | ||
527 | irq_handler_t func; | ||
528 | struct arch_timer *t; | ||
529 | |||
530 | t = kzalloc(sizeof(*t), GFP_KERNEL); | ||
531 | if (!t) | ||
532 | return -ENOMEM; | ||
533 | |||
534 | t->base = base; | ||
535 | t->evt.irq = irq; | ||
536 | __arch_timer_setup(ARCH_MEM_TIMER, &t->evt); | ||
537 | |||
538 | if (arch_timer_mem_use_virtual) | ||
539 | func = arch_timer_handler_virt_mem; | ||
540 | else | ||
541 | func = arch_timer_handler_phys_mem; | ||
542 | |||
543 | ret = request_irq(irq, func, IRQF_TIMER, "arch_mem_timer", &t->evt); | ||
544 | if (ret) { | ||
545 | pr_err("arch_timer: Failed to request mem timer irq\n"); | ||
546 | kfree(t); | ||
547 | } | ||
548 | |||
549 | return ret; | ||
550 | } | ||
551 | |||
552 | static const struct of_device_id arch_timer_of_match[] __initconst = { | ||
553 | { .compatible = "arm,armv7-timer", }, | ||
554 | { .compatible = "arm,armv8-timer", }, | ||
555 | {}, | ||
556 | }; | ||
557 | |||
558 | static const struct of_device_id arch_timer_mem_of_match[] __initconst = { | ||
559 | { .compatible = "arm,armv7-timer-mem", }, | ||
560 | {}, | ||
561 | }; | ||
562 | |||
563 | static void __init arch_timer_common_init(void) | ||
564 | { | ||
565 | unsigned mask = ARCH_CP15_TIMER | ARCH_MEM_TIMER; | ||
566 | |||
567 | /* Wait until both nodes are probed if we have two timers */ | ||
568 | if ((arch_timers_present & mask) != mask) { | ||
569 | if (of_find_matching_node(NULL, arch_timer_mem_of_match) && | ||
570 | !(arch_timers_present & ARCH_MEM_TIMER)) | ||
571 | return; | ||
572 | if (of_find_matching_node(NULL, arch_timer_of_match) && | ||
573 | !(arch_timers_present & ARCH_CP15_TIMER)) | ||
574 | return; | ||
575 | } | ||
576 | |||
577 | arch_timer_banner(arch_timers_present); | ||
578 | arch_counter_register(arch_timers_present); | ||
579 | arch_timer_arch_init(); | ||
580 | } | ||
581 | |||
334 | static void __init arch_timer_init(struct device_node *np) | 582 | static void __init arch_timer_init(struct device_node *np) |
335 | { | 583 | { |
336 | u32 freq; | ||
337 | int i; | 584 | int i; |
338 | 585 | ||
339 | if (arch_timer_get_rate()) { | 586 | if (arch_timers_present & ARCH_CP15_TIMER) { |
340 | pr_warn("arch_timer: multiple nodes in dt, skipping\n"); | 587 | pr_warn("arch_timer: multiple nodes in dt, skipping\n"); |
341 | return; | 588 | return; |
342 | } | 589 | } |
343 | 590 | ||
344 | /* Try to determine the frequency from the device tree or CNTFRQ */ | 591 | arch_timers_present |= ARCH_CP15_TIMER; |
345 | if (!of_property_read_u32(np, "clock-frequency", &freq)) | ||
346 | arch_timer_rate = freq; | ||
347 | |||
348 | for (i = PHYS_SECURE_PPI; i < MAX_TIMER_PPI; i++) | 592 | for (i = PHYS_SECURE_PPI; i < MAX_TIMER_PPI; i++) |
349 | arch_timer_ppi[i] = irq_of_parse_and_map(np, i); | 593 | arch_timer_ppi[i] = irq_of_parse_and_map(np, i); |
350 | 594 | arch_timer_detect_rate(NULL, np); | |
351 | of_node_put(np); | ||
352 | 595 | ||
353 | /* | 596 | /* |
354 | * If HYP mode is available, we know that the physical timer | 597 | * If HYP mode is available, we know that the physical timer |
@@ -369,7 +612,73 @@ static void __init arch_timer_init(struct device_node *np) | |||
369 | } | 612 | } |
370 | 613 | ||
371 | arch_timer_register(); | 614 | arch_timer_register(); |
372 | arch_timer_arch_init(); | 615 | arch_timer_common_init(); |
373 | } | 616 | } |
374 | CLOCKSOURCE_OF_DECLARE(armv7_arch_timer, "arm,armv7-timer", arch_timer_init); | 617 | CLOCKSOURCE_OF_DECLARE(armv7_arch_timer, "arm,armv7-timer", arch_timer_init); |
375 | CLOCKSOURCE_OF_DECLARE(armv8_arch_timer, "arm,armv8-timer", arch_timer_init); | 618 | CLOCKSOURCE_OF_DECLARE(armv8_arch_timer, "arm,armv8-timer", arch_timer_init); |
619 | |||
620 | static void __init arch_timer_mem_init(struct device_node *np) | ||
621 | { | ||
622 | struct device_node *frame, *best_frame = NULL; | ||
623 | void __iomem *cntctlbase, *base; | ||
624 | unsigned int irq; | ||
625 | u32 cnttidr; | ||
626 | |||
627 | arch_timers_present |= ARCH_MEM_TIMER; | ||
628 | cntctlbase = of_iomap(np, 0); | ||
629 | if (!cntctlbase) { | ||
630 | pr_err("arch_timer: Can't find CNTCTLBase\n"); | ||
631 | return; | ||
632 | } | ||
633 | |||
634 | cnttidr = readl_relaxed(cntctlbase + CNTTIDR); | ||
635 | iounmap(cntctlbase); | ||
636 | |||
637 | /* | ||
638 | * Try to find a virtual capable frame. Otherwise fall back to a | ||
639 | * physical capable frame. | ||
640 | */ | ||
641 | for_each_available_child_of_node(np, frame) { | ||
642 | int n; | ||
643 | |||
644 | if (of_property_read_u32(frame, "frame-number", &n)) { | ||
645 | pr_err("arch_timer: Missing frame-number\n"); | ||
646 | of_node_put(best_frame); | ||
647 | of_node_put(frame); | ||
648 | return; | ||
649 | } | ||
650 | |||
651 | if (cnttidr & CNTTIDR_VIRT(n)) { | ||
652 | of_node_put(best_frame); | ||
653 | best_frame = frame; | ||
654 | arch_timer_mem_use_virtual = true; | ||
655 | break; | ||
656 | } | ||
657 | of_node_put(best_frame); | ||
658 | best_frame = of_node_get(frame); | ||
659 | } | ||
660 | |||
661 | base = arch_counter_base = of_iomap(best_frame, 0); | ||
662 | if (!base) { | ||
663 | pr_err("arch_timer: Can't map frame's registers\n"); | ||
664 | of_node_put(best_frame); | ||
665 | return; | ||
666 | } | ||
667 | |||
668 | if (arch_timer_mem_use_virtual) | ||
669 | irq = irq_of_parse_and_map(best_frame, 1); | ||
670 | else | ||
671 | irq = irq_of_parse_and_map(best_frame, 0); | ||
672 | of_node_put(best_frame); | ||
673 | if (!irq) { | ||
674 | pr_err("arch_timer: Frame missing %s irq", | ||
675 | arch_timer_mem_use_virtual ? "virt" : "phys"); | ||
676 | return; | ||
677 | } | ||
678 | |||
679 | arch_timer_detect_rate(base, np); | ||
680 | arch_timer_mem_register(base, irq); | ||
681 | arch_timer_common_init(); | ||
682 | } | ||
683 | CLOCKSOURCE_OF_DECLARE(armv7_arch_timer_mem, "arm,armv7-timer-mem", | ||
684 | arch_timer_mem_init); | ||
diff --git a/drivers/clocksource/arm_global_timer.c b/drivers/clocksource/arm_global_timer.c index db8afc7427a6..b66c1f36066c 100644 --- a/drivers/clocksource/arm_global_timer.c +++ b/drivers/clocksource/arm_global_timer.c | |||
@@ -164,7 +164,7 @@ static irqreturn_t gt_clockevent_interrupt(int irq, void *dev_id) | |||
164 | return IRQ_HANDLED; | 164 | return IRQ_HANDLED; |
165 | } | 165 | } |
166 | 166 | ||
167 | static int __cpuinit gt_clockevents_init(struct clock_event_device *clk) | 167 | static int gt_clockevents_init(struct clock_event_device *clk) |
168 | { | 168 | { |
169 | int cpu = smp_processor_id(); | 169 | int cpu = smp_processor_id(); |
170 | 170 | ||
@@ -221,8 +221,8 @@ static void __init gt_clocksource_init(void) | |||
221 | clocksource_register_hz(>_clocksource, gt_clk_rate); | 221 | clocksource_register_hz(>_clocksource, gt_clk_rate); |
222 | } | 222 | } |
223 | 223 | ||
224 | static int __cpuinit gt_cpu_notify(struct notifier_block *self, | 224 | static int gt_cpu_notify(struct notifier_block *self, unsigned long action, |
225 | unsigned long action, void *hcpu) | 225 | void *hcpu) |
226 | { | 226 | { |
227 | switch (action & ~CPU_TASKS_FROZEN) { | 227 | switch (action & ~CPU_TASKS_FROZEN) { |
228 | case CPU_STARTING: | 228 | case CPU_STARTING: |
@@ -235,7 +235,7 @@ static int __cpuinit gt_cpu_notify(struct notifier_block *self, | |||
235 | 235 | ||
236 | return NOTIFY_OK; | 236 | return NOTIFY_OK; |
237 | } | 237 | } |
238 | static struct notifier_block gt_cpu_nb __cpuinitdata = { | 238 | static struct notifier_block gt_cpu_nb = { |
239 | .notifier_call = gt_cpu_notify, | 239 | .notifier_call = gt_cpu_notify, |
240 | }; | 240 | }; |
241 | 241 | ||
diff --git a/drivers/clocksource/bcm_kona_timer.c b/drivers/clocksource/bcm_kona_timer.c index ba3d85904c9a..0d7d8c3ed6b2 100644 --- a/drivers/clocksource/bcm_kona_timer.c +++ b/drivers/clocksource/bcm_kona_timer.c | |||
@@ -99,7 +99,8 @@ kona_timer_get_counter(void *timer_base, uint32_t *msw, uint32_t *lsw) | |||
99 | } | 99 | } |
100 | 100 | ||
101 | static const struct of_device_id bcm_timer_ids[] __initconst = { | 101 | static const struct of_device_id bcm_timer_ids[] __initconst = { |
102 | {.compatible = "bcm,kona-timer"}, | 102 | {.compatible = "brcm,kona-timer"}, |
103 | {.compatible = "bcm,kona-timer"}, /* deprecated name */ | ||
103 | {}, | 104 | {}, |
104 | }; | 105 | }; |
105 | 106 | ||
@@ -201,4 +202,9 @@ static void __init kona_timer_init(struct device_node *node) | |||
201 | kona_timer_set_next_event((arch_timer_rate / HZ), NULL); | 202 | kona_timer_set_next_event((arch_timer_rate / HZ), NULL); |
202 | } | 203 | } |
203 | 204 | ||
205 | CLOCKSOURCE_OF_DECLARE(brcm_kona, "brcm,kona-timer", kona_timer_init); | ||
206 | /* | ||
207 | * bcm,kona-timer is deprecated by brcm,kona-timer | ||
208 | * being kept here for driver compatibility | ||
209 | */ | ||
204 | CLOCKSOURCE_OF_DECLARE(bcm_kona, "bcm,kona-timer", kona_timer_init); | 210 | CLOCKSOURCE_OF_DECLARE(bcm_kona, "bcm,kona-timer", kona_timer_init); |
diff --git a/drivers/clocksource/cadence_ttc_timer.c b/drivers/clocksource/cadence_ttc_timer.c index 4cbe28c74631..b2bb3a4bc205 100644 --- a/drivers/clocksource/cadence_ttc_timer.c +++ b/drivers/clocksource/cadence_ttc_timer.c | |||
@@ -21,7 +21,7 @@ | |||
21 | #include <linux/of_address.h> | 21 | #include <linux/of_address.h> |
22 | #include <linux/of_irq.h> | 22 | #include <linux/of_irq.h> |
23 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
24 | #include <linux/clk-provider.h> | 24 | #include <linux/sched_clock.h> |
25 | 25 | ||
26 | /* | 26 | /* |
27 | * This driver configures the 2 16-bit count-up timers as follows: | 27 | * This driver configures the 2 16-bit count-up timers as follows: |
@@ -95,6 +95,8 @@ struct ttc_timer_clockevent { | |||
95 | #define to_ttc_timer_clkevent(x) \ | 95 | #define to_ttc_timer_clkevent(x) \ |
96 | container_of(x, struct ttc_timer_clockevent, ce) | 96 | container_of(x, struct ttc_timer_clockevent, ce) |
97 | 97 | ||
98 | static void __iomem *ttc_sched_clock_val_reg; | ||
99 | |||
98 | /** | 100 | /** |
99 | * ttc_set_interval - Set the timer interval value | 101 | * ttc_set_interval - Set the timer interval value |
100 | * | 102 | * |
@@ -156,6 +158,11 @@ static cycle_t __ttc_clocksource_read(struct clocksource *cs) | |||
156 | TTC_COUNT_VAL_OFFSET); | 158 | TTC_COUNT_VAL_OFFSET); |
157 | } | 159 | } |
158 | 160 | ||
161 | static u32 notrace ttc_sched_clock_read(void) | ||
162 | { | ||
163 | return __raw_readl(ttc_sched_clock_val_reg); | ||
164 | } | ||
165 | |||
159 | /** | 166 | /** |
160 | * ttc_set_next_event - Sets the time interval for next event | 167 | * ttc_set_next_event - Sets the time interval for next event |
161 | * | 168 | * |
@@ -297,6 +304,10 @@ static void __init ttc_setup_clocksource(struct clk *clk, void __iomem *base) | |||
297 | kfree(ttccs); | 304 | kfree(ttccs); |
298 | return; | 305 | return; |
299 | } | 306 | } |
307 | |||
308 | ttc_sched_clock_val_reg = base + TTC_COUNT_VAL_OFFSET; | ||
309 | setup_sched_clock(ttc_sched_clock_read, 16, | ||
310 | clk_get_rate(ttccs->ttc.clk) / PRESCALE); | ||
300 | } | 311 | } |
301 | 312 | ||
302 | static int ttc_rate_change_clockevent_cb(struct notifier_block *nb, | 313 | static int ttc_rate_change_clockevent_cb(struct notifier_block *nb, |
diff --git a/drivers/clocksource/dummy_timer.c b/drivers/clocksource/dummy_timer.c index 1f55f9620338..b3eb582d6a6f 100644 --- a/drivers/clocksource/dummy_timer.c +++ b/drivers/clocksource/dummy_timer.c | |||
@@ -25,7 +25,7 @@ static void dummy_timer_set_mode(enum clock_event_mode mode, | |||
25 | */ | 25 | */ |
26 | } | 26 | } |
27 | 27 | ||
28 | static void __cpuinit dummy_timer_setup(void) | 28 | static void dummy_timer_setup(void) |
29 | { | 29 | { |
30 | int cpu = smp_processor_id(); | 30 | int cpu = smp_processor_id(); |
31 | struct clock_event_device *evt = __this_cpu_ptr(&dummy_timer_evt); | 31 | struct clock_event_device *evt = __this_cpu_ptr(&dummy_timer_evt); |
@@ -41,7 +41,7 @@ static void __cpuinit dummy_timer_setup(void) | |||
41 | clockevents_register_device(evt); | 41 | clockevents_register_device(evt); |
42 | } | 42 | } |
43 | 43 | ||
44 | static int __cpuinit dummy_timer_cpu_notify(struct notifier_block *self, | 44 | static int dummy_timer_cpu_notify(struct notifier_block *self, |
45 | unsigned long action, void *hcpu) | 45 | unsigned long action, void *hcpu) |
46 | { | 46 | { |
47 | if ((action & ~CPU_TASKS_FROZEN) == CPU_STARTING) | 47 | if ((action & ~CPU_TASKS_FROZEN) == CPU_STARTING) |
@@ -50,7 +50,7 @@ static int __cpuinit dummy_timer_cpu_notify(struct notifier_block *self, | |||
50 | return NOTIFY_OK; | 50 | return NOTIFY_OK; |
51 | } | 51 | } |
52 | 52 | ||
53 | static struct notifier_block dummy_timer_cpu_nb __cpuinitdata = { | 53 | static struct notifier_block dummy_timer_cpu_nb = { |
54 | .notifier_call = dummy_timer_cpu_notify, | 54 | .notifier_call = dummy_timer_cpu_notify, |
55 | }; | 55 | }; |
56 | 56 | ||
diff --git a/drivers/clocksource/em_sti.c b/drivers/clocksource/em_sti.c index 4329a29a5310..b9c81b7c3a3b 100644 --- a/drivers/clocksource/em_sti.c +++ b/drivers/clocksource/em_sti.c | |||
@@ -315,68 +315,47 @@ static int em_sti_probe(struct platform_device *pdev) | |||
315 | { | 315 | { |
316 | struct em_sti_priv *p; | 316 | struct em_sti_priv *p; |
317 | struct resource *res; | 317 | struct resource *res; |
318 | int irq, ret; | 318 | int irq; |
319 | 319 | ||
320 | p = kzalloc(sizeof(*p), GFP_KERNEL); | 320 | p = devm_kzalloc(&pdev->dev, sizeof(*p), GFP_KERNEL); |
321 | if (p == NULL) { | 321 | if (p == NULL) { |
322 | dev_err(&pdev->dev, "failed to allocate driver data\n"); | 322 | dev_err(&pdev->dev, "failed to allocate driver data\n"); |
323 | ret = -ENOMEM; | 323 | return -ENOMEM; |
324 | goto err0; | ||
325 | } | 324 | } |
326 | 325 | ||
327 | p->pdev = pdev; | 326 | p->pdev = pdev; |
328 | platform_set_drvdata(pdev, p); | 327 | platform_set_drvdata(pdev, p); |
329 | 328 | ||
330 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
331 | if (!res) { | ||
332 | dev_err(&pdev->dev, "failed to get I/O memory\n"); | ||
333 | ret = -EINVAL; | ||
334 | goto err0; | ||
335 | } | ||
336 | |||
337 | irq = platform_get_irq(pdev, 0); | 329 | irq = platform_get_irq(pdev, 0); |
338 | if (irq < 0) { | 330 | if (irq < 0) { |
339 | dev_err(&pdev->dev, "failed to get irq\n"); | 331 | dev_err(&pdev->dev, "failed to get irq\n"); |
340 | ret = -EINVAL; | 332 | return -EINVAL; |
341 | goto err0; | ||
342 | } | 333 | } |
343 | 334 | ||
344 | /* map memory, let base point to the STI instance */ | 335 | /* map memory, let base point to the STI instance */ |
345 | p->base = ioremap_nocache(res->start, resource_size(res)); | 336 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
346 | if (p->base == NULL) { | 337 | p->base = devm_ioremap_resource(&pdev->dev, res); |
347 | dev_err(&pdev->dev, "failed to remap I/O memory\n"); | 338 | if (IS_ERR(p->base)) |
348 | ret = -ENXIO; | 339 | return PTR_ERR(p->base); |
349 | goto err0; | ||
350 | } | ||
351 | 340 | ||
352 | /* get hold of clock */ | 341 | /* get hold of clock */ |
353 | p->clk = clk_get(&pdev->dev, "sclk"); | 342 | p->clk = devm_clk_get(&pdev->dev, "sclk"); |
354 | if (IS_ERR(p->clk)) { | 343 | if (IS_ERR(p->clk)) { |
355 | dev_err(&pdev->dev, "cannot get clock\n"); | 344 | dev_err(&pdev->dev, "cannot get clock\n"); |
356 | ret = PTR_ERR(p->clk); | 345 | return PTR_ERR(p->clk); |
357 | goto err1; | ||
358 | } | 346 | } |
359 | 347 | ||
360 | if (request_irq(irq, em_sti_interrupt, | 348 | if (devm_request_irq(&pdev->dev, irq, em_sti_interrupt, |
361 | IRQF_TIMER | IRQF_IRQPOLL | IRQF_NOBALANCING, | 349 | IRQF_TIMER | IRQF_IRQPOLL | IRQF_NOBALANCING, |
362 | dev_name(&pdev->dev), p)) { | 350 | dev_name(&pdev->dev), p)) { |
363 | dev_err(&pdev->dev, "failed to request low IRQ\n"); | 351 | dev_err(&pdev->dev, "failed to request low IRQ\n"); |
364 | ret = -ENOENT; | 352 | return -ENOENT; |
365 | goto err2; | ||
366 | } | 353 | } |
367 | 354 | ||
368 | raw_spin_lock_init(&p->lock); | 355 | raw_spin_lock_init(&p->lock); |
369 | em_sti_register_clockevent(p); | 356 | em_sti_register_clockevent(p); |
370 | em_sti_register_clocksource(p); | 357 | em_sti_register_clocksource(p); |
371 | return 0; | 358 | return 0; |
372 | |||
373 | err2: | ||
374 | clk_put(p->clk); | ||
375 | err1: | ||
376 | iounmap(p->base); | ||
377 | err0: | ||
378 | kfree(p); | ||
379 | return ret; | ||
380 | } | 359 | } |
381 | 360 | ||
382 | static int em_sti_remove(struct platform_device *pdev) | 361 | static int em_sti_remove(struct platform_device *pdev) |
diff --git a/drivers/clocksource/exynos_mct.c b/drivers/clocksource/exynos_mct.c index a70480409ea5..5b34768f4d7c 100644 --- a/drivers/clocksource/exynos_mct.c +++ b/drivers/clocksource/exynos_mct.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/err.h> | 16 | #include <linux/err.h> |
17 | #include <linux/clk.h> | 17 | #include <linux/clk.h> |
18 | #include <linux/clockchips.h> | 18 | #include <linux/clockchips.h> |
19 | #include <linux/cpu.h> | ||
19 | #include <linux/platform_device.h> | 20 | #include <linux/platform_device.h> |
20 | #include <linux/delay.h> | 21 | #include <linux/delay.h> |
21 | #include <linux/percpu.h> | 22 | #include <linux/percpu.h> |
@@ -24,7 +25,6 @@ | |||
24 | #include <linux/of_address.h> | 25 | #include <linux/of_address.h> |
25 | #include <linux/clocksource.h> | 26 | #include <linux/clocksource.h> |
26 | 27 | ||
27 | #include <asm/localtimer.h> | ||
28 | #include <asm/mach/time.h> | 28 | #include <asm/mach/time.h> |
29 | 29 | ||
30 | #define EXYNOS4_MCTREG(x) (x) | 30 | #define EXYNOS4_MCTREG(x) (x) |
@@ -80,7 +80,7 @@ static unsigned int mct_int_type; | |||
80 | static int mct_irqs[MCT_NR_IRQS]; | 80 | static int mct_irqs[MCT_NR_IRQS]; |
81 | 81 | ||
82 | struct mct_clock_event_device { | 82 | struct mct_clock_event_device { |
83 | struct clock_event_device *evt; | 83 | struct clock_event_device evt; |
84 | unsigned long base; | 84 | unsigned long base; |
85 | char name[10]; | 85 | char name[10]; |
86 | }; | 86 | }; |
@@ -295,8 +295,6 @@ static void exynos4_clockevent_init(void) | |||
295 | setup_irq(mct_irqs[MCT_G0_IRQ], &mct_comp_event_irq); | 295 | setup_irq(mct_irqs[MCT_G0_IRQ], &mct_comp_event_irq); |
296 | } | 296 | } |
297 | 297 | ||
298 | #ifdef CONFIG_LOCAL_TIMERS | ||
299 | |||
300 | static DEFINE_PER_CPU(struct mct_clock_event_device, percpu_mct_tick); | 298 | static DEFINE_PER_CPU(struct mct_clock_event_device, percpu_mct_tick); |
301 | 299 | ||
302 | /* Clock event handling */ | 300 | /* Clock event handling */ |
@@ -369,7 +367,7 @@ static inline void exynos4_tick_set_mode(enum clock_event_mode mode, | |||
369 | 367 | ||
370 | static int exynos4_mct_tick_clear(struct mct_clock_event_device *mevt) | 368 | static int exynos4_mct_tick_clear(struct mct_clock_event_device *mevt) |
371 | { | 369 | { |
372 | struct clock_event_device *evt = mevt->evt; | 370 | struct clock_event_device *evt = &mevt->evt; |
373 | 371 | ||
374 | /* | 372 | /* |
375 | * This is for supporting oneshot mode. | 373 | * This is for supporting oneshot mode. |
@@ -391,7 +389,7 @@ static int exynos4_mct_tick_clear(struct mct_clock_event_device *mevt) | |||
391 | static irqreturn_t exynos4_mct_tick_isr(int irq, void *dev_id) | 389 | static irqreturn_t exynos4_mct_tick_isr(int irq, void *dev_id) |
392 | { | 390 | { |
393 | struct mct_clock_event_device *mevt = dev_id; | 391 | struct mct_clock_event_device *mevt = dev_id; |
394 | struct clock_event_device *evt = mevt->evt; | 392 | struct clock_event_device *evt = &mevt->evt; |
395 | 393 | ||
396 | exynos4_mct_tick_clear(mevt); | 394 | exynos4_mct_tick_clear(mevt); |
397 | 395 | ||
@@ -400,13 +398,12 @@ static irqreturn_t exynos4_mct_tick_isr(int irq, void *dev_id) | |||
400 | return IRQ_HANDLED; | 398 | return IRQ_HANDLED; |
401 | } | 399 | } |
402 | 400 | ||
403 | static int __cpuinit exynos4_local_timer_setup(struct clock_event_device *evt) | 401 | static int exynos4_local_timer_setup(struct clock_event_device *evt) |
404 | { | 402 | { |
405 | struct mct_clock_event_device *mevt; | 403 | struct mct_clock_event_device *mevt; |
406 | unsigned int cpu = smp_processor_id(); | 404 | unsigned int cpu = smp_processor_id(); |
407 | 405 | ||
408 | mevt = this_cpu_ptr(&percpu_mct_tick); | 406 | mevt = container_of(evt, struct mct_clock_event_device, evt); |
409 | mevt->evt = evt; | ||
410 | 407 | ||
411 | mevt->base = EXYNOS4_MCT_L_BASE(cpu); | 408 | mevt->base = EXYNOS4_MCT_L_BASE(cpu); |
412 | sprintf(mevt->name, "mct_tick%d", cpu); | 409 | sprintf(mevt->name, "mct_tick%d", cpu); |
@@ -448,14 +445,37 @@ static void exynos4_local_timer_stop(struct clock_event_device *evt) | |||
448 | disable_percpu_irq(mct_irqs[MCT_L0_IRQ]); | 445 | disable_percpu_irq(mct_irqs[MCT_L0_IRQ]); |
449 | } | 446 | } |
450 | 447 | ||
451 | static struct local_timer_ops exynos4_mct_tick_ops __cpuinitdata = { | 448 | static int exynos4_mct_cpu_notify(struct notifier_block *self, |
452 | .setup = exynos4_local_timer_setup, | 449 | unsigned long action, void *hcpu) |
453 | .stop = exynos4_local_timer_stop, | 450 | { |
451 | struct mct_clock_event_device *mevt; | ||
452 | |||
453 | /* | ||
454 | * Grab cpu pointer in each case to avoid spurious | ||
455 | * preemptible warnings | ||
456 | */ | ||
457 | switch (action & ~CPU_TASKS_FROZEN) { | ||
458 | case CPU_STARTING: | ||
459 | mevt = this_cpu_ptr(&percpu_mct_tick); | ||
460 | exynos4_local_timer_setup(&mevt->evt); | ||
461 | break; | ||
462 | case CPU_DYING: | ||
463 | mevt = this_cpu_ptr(&percpu_mct_tick); | ||
464 | exynos4_local_timer_stop(&mevt->evt); | ||
465 | break; | ||
466 | } | ||
467 | |||
468 | return NOTIFY_OK; | ||
469 | } | ||
470 | |||
471 | static struct notifier_block exynos4_mct_cpu_nb = { | ||
472 | .notifier_call = exynos4_mct_cpu_notify, | ||
454 | }; | 473 | }; |
455 | #endif /* CONFIG_LOCAL_TIMERS */ | ||
456 | 474 | ||
457 | static void __init exynos4_timer_resources(struct device_node *np, void __iomem *base) | 475 | static void __init exynos4_timer_resources(struct device_node *np, void __iomem *base) |
458 | { | 476 | { |
477 | int err; | ||
478 | struct mct_clock_event_device *mevt = this_cpu_ptr(&percpu_mct_tick); | ||
459 | struct clk *mct_clk, *tick_clk; | 479 | struct clk *mct_clk, *tick_clk; |
460 | 480 | ||
461 | tick_clk = np ? of_clk_get_by_name(np, "fin_pll") : | 481 | tick_clk = np ? of_clk_get_by_name(np, "fin_pll") : |
@@ -473,9 +493,7 @@ static void __init exynos4_timer_resources(struct device_node *np, void __iomem | |||
473 | if (!reg_base) | 493 | if (!reg_base) |
474 | panic("%s: unable to ioremap mct address space\n", __func__); | 494 | panic("%s: unable to ioremap mct address space\n", __func__); |
475 | 495 | ||
476 | #ifdef CONFIG_LOCAL_TIMERS | ||
477 | if (mct_int_type == MCT_INT_PPI) { | 496 | if (mct_int_type == MCT_INT_PPI) { |
478 | int err; | ||
479 | 497 | ||
480 | err = request_percpu_irq(mct_irqs[MCT_L0_IRQ], | 498 | err = request_percpu_irq(mct_irqs[MCT_L0_IRQ], |
481 | exynos4_mct_tick_isr, "MCT", | 499 | exynos4_mct_tick_isr, "MCT", |
@@ -484,8 +502,16 @@ static void __init exynos4_timer_resources(struct device_node *np, void __iomem | |||
484 | mct_irqs[MCT_L0_IRQ], err); | 502 | mct_irqs[MCT_L0_IRQ], err); |
485 | } | 503 | } |
486 | 504 | ||
487 | local_timer_register(&exynos4_mct_tick_ops); | 505 | err = register_cpu_notifier(&exynos4_mct_cpu_nb); |
488 | #endif /* CONFIG_LOCAL_TIMERS */ | 506 | if (err) |
507 | goto out_irq; | ||
508 | |||
509 | /* Immediately configure the timer on the boot CPU */ | ||
510 | exynos4_local_timer_setup(&mevt->evt); | ||
511 | return; | ||
512 | |||
513 | out_irq: | ||
514 | free_percpu_irq(mct_irqs[MCT_L0_IRQ], &percpu_mct_tick); | ||
489 | } | 515 | } |
490 | 516 | ||
491 | void __init mct_init(void __iomem *base, int irq_g0, int irq_l0, int irq_l1) | 517 | void __init mct_init(void __iomem *base, int irq_g0, int irq_l0, int irq_l1) |
diff --git a/drivers/clocksource/metag_generic.c b/drivers/clocksource/metag_generic.c index 6722f0e2fe40..9e4db41abe3c 100644 --- a/drivers/clocksource/metag_generic.c +++ b/drivers/clocksource/metag_generic.c | |||
@@ -109,7 +109,7 @@ unsigned long long sched_clock(void) | |||
109 | return ticks << HARDWARE_TO_NS_SHIFT; | 109 | return ticks << HARDWARE_TO_NS_SHIFT; |
110 | } | 110 | } |
111 | 111 | ||
112 | static void __cpuinit arch_timer_setup(unsigned int cpu) | 112 | static void arch_timer_setup(unsigned int cpu) |
113 | { | 113 | { |
114 | unsigned int txdivtime; | 114 | unsigned int txdivtime; |
115 | struct clock_event_device *clk = &per_cpu(local_clockevent, cpu); | 115 | struct clock_event_device *clk = &per_cpu(local_clockevent, cpu); |
@@ -154,7 +154,7 @@ static void __cpuinit arch_timer_setup(unsigned int cpu) | |||
154 | } | 154 | } |
155 | } | 155 | } |
156 | 156 | ||
157 | static int __cpuinit arch_timer_cpu_notify(struct notifier_block *self, | 157 | static int arch_timer_cpu_notify(struct notifier_block *self, |
158 | unsigned long action, void *hcpu) | 158 | unsigned long action, void *hcpu) |
159 | { | 159 | { |
160 | int cpu = (long)hcpu; | 160 | int cpu = (long)hcpu; |
@@ -169,7 +169,7 @@ static int __cpuinit arch_timer_cpu_notify(struct notifier_block *self, | |||
169 | return NOTIFY_OK; | 169 | return NOTIFY_OK; |
170 | } | 170 | } |
171 | 171 | ||
172 | static struct notifier_block __cpuinitdata arch_timer_cpu_nb = { | 172 | static struct notifier_block arch_timer_cpu_nb = { |
173 | .notifier_call = arch_timer_cpu_notify, | 173 | .notifier_call = arch_timer_cpu_notify, |
174 | }; | 174 | }; |
175 | 175 | ||
diff --git a/drivers/clocksource/moxart_timer.c b/drivers/clocksource/moxart_timer.c new file mode 100644 index 000000000000..5eb2c35932b1 --- /dev/null +++ b/drivers/clocksource/moxart_timer.c | |||
@@ -0,0 +1,165 @@ | |||
1 | /* | ||
2 | * MOXA ART SoCs timer handling. | ||
3 | * | ||
4 | * Copyright (C) 2013 Jonas Jensen | ||
5 | * | ||
6 | * Jonas Jensen <jonas.jensen@gmail.com> | ||
7 | * | ||
8 | * This file is licensed under the terms of the GNU General Public | ||
9 | * License version 2. This program is licensed "as is" without any | ||
10 | * warranty of any kind, whether express or implied. | ||
11 | */ | ||
12 | |||
13 | #include <linux/clk.h> | ||
14 | #include <linux/clockchips.h> | ||
15 | #include <linux/interrupt.h> | ||
16 | #include <linux/irq.h> | ||
17 | #include <linux/irqreturn.h> | ||
18 | #include <linux/of.h> | ||
19 | #include <linux/of_address.h> | ||
20 | #include <linux/of_irq.h> | ||
21 | #include <linux/io.h> | ||
22 | #include <linux/clocksource.h> | ||
23 | #include <linux/bitops.h> | ||
24 | |||
25 | #define TIMER1_BASE 0x00 | ||
26 | #define TIMER2_BASE 0x10 | ||
27 | #define TIMER3_BASE 0x20 | ||
28 | |||
29 | #define REG_COUNT 0x0 /* writable */ | ||
30 | #define REG_LOAD 0x4 | ||
31 | #define REG_MATCH1 0x8 | ||
32 | #define REG_MATCH2 0xC | ||
33 | |||
34 | #define TIMER_CR 0x30 | ||
35 | #define TIMER_INTR_STATE 0x34 | ||
36 | #define TIMER_INTR_MASK 0x38 | ||
37 | |||
38 | /* | ||
39 | * TIMER_CR flags: | ||
40 | * | ||
41 | * TIMEREG_CR_*_CLOCK 0: PCLK, 1: EXT1CLK | ||
42 | * TIMEREG_CR_*_INT overflow interrupt enable bit | ||
43 | */ | ||
44 | #define TIMEREG_CR_1_ENABLE BIT(0) | ||
45 | #define TIMEREG_CR_1_CLOCK BIT(1) | ||
46 | #define TIMEREG_CR_1_INT BIT(2) | ||
47 | #define TIMEREG_CR_2_ENABLE BIT(3) | ||
48 | #define TIMEREG_CR_2_CLOCK BIT(4) | ||
49 | #define TIMEREG_CR_2_INT BIT(5) | ||
50 | #define TIMEREG_CR_3_ENABLE BIT(6) | ||
51 | #define TIMEREG_CR_3_CLOCK BIT(7) | ||
52 | #define TIMEREG_CR_3_INT BIT(8) | ||
53 | #define TIMEREG_CR_COUNT_UP BIT(9) | ||
54 | |||
55 | #define TIMER1_ENABLE (TIMEREG_CR_2_ENABLE | TIMEREG_CR_1_ENABLE) | ||
56 | #define TIMER1_DISABLE (TIMEREG_CR_2_ENABLE) | ||
57 | |||
58 | static void __iomem *base; | ||
59 | static unsigned int clock_count_per_tick; | ||
60 | |||
61 | static void moxart_clkevt_mode(enum clock_event_mode mode, | ||
62 | struct clock_event_device *clk) | ||
63 | { | ||
64 | switch (mode) { | ||
65 | case CLOCK_EVT_MODE_RESUME: | ||
66 | case CLOCK_EVT_MODE_ONESHOT: | ||
67 | writel(TIMER1_DISABLE, base + TIMER_CR); | ||
68 | writel(~0, base + TIMER1_BASE + REG_LOAD); | ||
69 | break; | ||
70 | case CLOCK_EVT_MODE_PERIODIC: | ||
71 | writel(clock_count_per_tick, base + TIMER1_BASE + REG_LOAD); | ||
72 | writel(TIMER1_ENABLE, base + TIMER_CR); | ||
73 | break; | ||
74 | case CLOCK_EVT_MODE_UNUSED: | ||
75 | case CLOCK_EVT_MODE_SHUTDOWN: | ||
76 | default: | ||
77 | writel(TIMER1_DISABLE, base + TIMER_CR); | ||
78 | break; | ||
79 | } | ||
80 | } | ||
81 | |||
82 | static int moxart_clkevt_next_event(unsigned long cycles, | ||
83 | struct clock_event_device *unused) | ||
84 | { | ||
85 | u32 u; | ||
86 | |||
87 | writel(TIMER1_DISABLE, base + TIMER_CR); | ||
88 | |||
89 | u = readl(base + TIMER1_BASE + REG_COUNT) - cycles; | ||
90 | writel(u, base + TIMER1_BASE + REG_MATCH1); | ||
91 | |||
92 | writel(TIMER1_ENABLE, base + TIMER_CR); | ||
93 | |||
94 | return 0; | ||
95 | } | ||
96 | |||
97 | static struct clock_event_device moxart_clockevent = { | ||
98 | .name = "moxart_timer", | ||
99 | .rating = 200, | ||
100 | .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, | ||
101 | .set_mode = moxart_clkevt_mode, | ||
102 | .set_next_event = moxart_clkevt_next_event, | ||
103 | }; | ||
104 | |||
105 | static irqreturn_t moxart_timer_interrupt(int irq, void *dev_id) | ||
106 | { | ||
107 | struct clock_event_device *evt = dev_id; | ||
108 | evt->event_handler(evt); | ||
109 | return IRQ_HANDLED; | ||
110 | } | ||
111 | |||
112 | static struct irqaction moxart_timer_irq = { | ||
113 | .name = "moxart-timer", | ||
114 | .flags = IRQF_TIMER, | ||
115 | .handler = moxart_timer_interrupt, | ||
116 | .dev_id = &moxart_clockevent, | ||
117 | }; | ||
118 | |||
119 | static void __init moxart_timer_init(struct device_node *node) | ||
120 | { | ||
121 | int ret, irq; | ||
122 | unsigned long pclk; | ||
123 | struct clk *clk; | ||
124 | |||
125 | base = of_iomap(node, 0); | ||
126 | if (!base) | ||
127 | panic("%s: of_iomap failed\n", node->full_name); | ||
128 | |||
129 | irq = irq_of_parse_and_map(node, 0); | ||
130 | if (irq <= 0) | ||
131 | panic("%s: irq_of_parse_and_map failed\n", node->full_name); | ||
132 | |||
133 | ret = setup_irq(irq, &moxart_timer_irq); | ||
134 | if (ret) | ||
135 | panic("%s: setup_irq failed\n", node->full_name); | ||
136 | |||
137 | clk = of_clk_get(node, 0); | ||
138 | if (IS_ERR(clk)) | ||
139 | panic("%s: of_clk_get failed\n", node->full_name); | ||
140 | |||
141 | pclk = clk_get_rate(clk); | ||
142 | |||
143 | if (clocksource_mmio_init(base + TIMER2_BASE + REG_COUNT, | ||
144 | "moxart_timer", pclk, 200, 32, | ||
145 | clocksource_mmio_readl_down)) | ||
146 | panic("%s: clocksource_mmio_init failed\n", node->full_name); | ||
147 | |||
148 | clock_count_per_tick = DIV_ROUND_CLOSEST(pclk, HZ); | ||
149 | |||
150 | writel(~0, base + TIMER2_BASE + REG_LOAD); | ||
151 | writel(TIMEREG_CR_2_ENABLE, base + TIMER_CR); | ||
152 | |||
153 | moxart_clockevent.cpumask = cpumask_of(0); | ||
154 | moxart_clockevent.irq = irq; | ||
155 | |||
156 | /* | ||
157 | * documentation is not publicly available: | ||
158 | * min_delta / max_delta obtained by trial-and-error, | ||
159 | * max_delta 0xfffffffe should be ok because count | ||
160 | * register size is u32 | ||
161 | */ | ||
162 | clockevents_config_and_register(&moxart_clockevent, pclk, | ||
163 | 0x4, 0xfffffffe); | ||
164 | } | ||
165 | CLOCKSOURCE_OF_DECLARE(moxart, "moxa,moxart-timer", moxart_timer_init); | ||
diff --git a/drivers/clocksource/nomadik-mtu.c b/drivers/clocksource/nomadik-mtu.c index 2242cd3d618d..ed7b73b508e0 100644 --- a/drivers/clocksource/nomadik-mtu.c +++ b/drivers/clocksource/nomadik-mtu.c | |||
@@ -165,7 +165,8 @@ static void nmdk_clkevt_resume(struct clock_event_device *cedev) | |||
165 | 165 | ||
166 | static struct clock_event_device nmdk_clkevt = { | 166 | static struct clock_event_device nmdk_clkevt = { |
167 | .name = "mtu_1", | 167 | .name = "mtu_1", |
168 | .features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC, | 168 | .features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC | |
169 | CLOCK_EVT_FEAT_DYNIRQ, | ||
169 | .rating = 200, | 170 | .rating = 200, |
170 | .set_mode = nmdk_clkevt_mode, | 171 | .set_mode = nmdk_clkevt_mode, |
171 | .set_next_event = nmdk_clkevt_next, | 172 | .set_next_event = nmdk_clkevt_next, |
diff --git a/drivers/clocksource/samsung_pwm_timer.c b/drivers/clocksource/samsung_pwm_timer.c index 09e8bc7bc92f..85082e8d3052 100644 --- a/drivers/clocksource/samsung_pwm_timer.c +++ b/drivers/clocksource/samsung_pwm_timer.c | |||
@@ -44,16 +44,28 @@ | |||
44 | #define TCFG1_SHIFT(x) ((x) * 4) | 44 | #define TCFG1_SHIFT(x) ((x) * 4) |
45 | #define TCFG1_MUX_MASK 0xf | 45 | #define TCFG1_MUX_MASK 0xf |
46 | 46 | ||
47 | /* | ||
48 | * Each channel occupies 4 bits in TCON register, but there is a gap of 4 | ||
49 | * bits (one channel) after channel 0, so channels have different numbering | ||
50 | * when accessing TCON register. | ||
51 | * | ||
52 | * In addition, the location of autoreload bit for channel 4 (TCON channel 5) | ||
53 | * in its set of bits is 2 as opposed to 3 for other channels. | ||
54 | */ | ||
47 | #define TCON_START(chan) (1 << (4 * (chan) + 0)) | 55 | #define TCON_START(chan) (1 << (4 * (chan) + 0)) |
48 | #define TCON_MANUALUPDATE(chan) (1 << (4 * (chan) + 1)) | 56 | #define TCON_MANUALUPDATE(chan) (1 << (4 * (chan) + 1)) |
49 | #define TCON_INVERT(chan) (1 << (4 * (chan) + 2)) | 57 | #define TCON_INVERT(chan) (1 << (4 * (chan) + 2)) |
50 | #define TCON_AUTORELOAD(chan) (1 << (4 * (chan) + 3)) | 58 | #define _TCON_AUTORELOAD(chan) (1 << (4 * (chan) + 3)) |
59 | #define _TCON_AUTORELOAD4(chan) (1 << (4 * (chan) + 2)) | ||
60 | #define TCON_AUTORELOAD(chan) \ | ||
61 | ((chan < 5) ? _TCON_AUTORELOAD(chan) : _TCON_AUTORELOAD4(chan)) | ||
51 | 62 | ||
52 | DEFINE_SPINLOCK(samsung_pwm_lock); | 63 | DEFINE_SPINLOCK(samsung_pwm_lock); |
53 | EXPORT_SYMBOL(samsung_pwm_lock); | 64 | EXPORT_SYMBOL(samsung_pwm_lock); |
54 | 65 | ||
55 | struct samsung_pwm_clocksource { | 66 | struct samsung_pwm_clocksource { |
56 | void __iomem *base; | 67 | void __iomem *base; |
68 | void __iomem *source_reg; | ||
57 | unsigned int irq[SAMSUNG_PWM_NUM]; | 69 | unsigned int irq[SAMSUNG_PWM_NUM]; |
58 | struct samsung_pwm_variant variant; | 70 | struct samsung_pwm_variant variant; |
59 | 71 | ||
@@ -195,17 +207,6 @@ static int samsung_set_next_event(unsigned long cycles, | |||
195 | return 0; | 207 | return 0; |
196 | } | 208 | } |
197 | 209 | ||
198 | static void samsung_timer_resume(void) | ||
199 | { | ||
200 | /* event timer restart */ | ||
201 | samsung_time_setup(pwm.event_id, pwm.clock_count_per_tick - 1); | ||
202 | samsung_time_start(pwm.event_id, true); | ||
203 | |||
204 | /* source timer restart */ | ||
205 | samsung_time_setup(pwm.source_id, pwm.tcnt_max); | ||
206 | samsung_time_start(pwm.source_id, true); | ||
207 | } | ||
208 | |||
209 | static void samsung_set_mode(enum clock_event_mode mode, | 210 | static void samsung_set_mode(enum clock_event_mode mode, |
210 | struct clock_event_device *evt) | 211 | struct clock_event_device *evt) |
211 | { | 212 | { |
@@ -222,20 +223,29 @@ static void samsung_set_mode(enum clock_event_mode mode, | |||
222 | 223 | ||
223 | case CLOCK_EVT_MODE_UNUSED: | 224 | case CLOCK_EVT_MODE_UNUSED: |
224 | case CLOCK_EVT_MODE_SHUTDOWN: | 225 | case CLOCK_EVT_MODE_SHUTDOWN: |
225 | break; | ||
226 | |||
227 | case CLOCK_EVT_MODE_RESUME: | 226 | case CLOCK_EVT_MODE_RESUME: |
228 | samsung_timer_resume(); | ||
229 | break; | 227 | break; |
230 | } | 228 | } |
231 | } | 229 | } |
232 | 230 | ||
231 | static void samsung_clockevent_resume(struct clock_event_device *cev) | ||
232 | { | ||
233 | samsung_timer_set_prescale(pwm.event_id, pwm.tscaler_div); | ||
234 | samsung_timer_set_divisor(pwm.event_id, pwm.tdiv); | ||
235 | |||
236 | if (pwm.variant.has_tint_cstat) { | ||
237 | u32 mask = (1 << pwm.event_id); | ||
238 | writel(mask | (mask << 5), pwm.base + REG_TINT_CSTAT); | ||
239 | } | ||
240 | } | ||
241 | |||
233 | static struct clock_event_device time_event_device = { | 242 | static struct clock_event_device time_event_device = { |
234 | .name = "samsung_event_timer", | 243 | .name = "samsung_event_timer", |
235 | .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, | 244 | .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, |
236 | .rating = 200, | 245 | .rating = 200, |
237 | .set_next_event = samsung_set_next_event, | 246 | .set_next_event = samsung_set_next_event, |
238 | .set_mode = samsung_set_mode, | 247 | .set_mode = samsung_set_mode, |
248 | .resume = samsung_clockevent_resume, | ||
239 | }; | 249 | }; |
240 | 250 | ||
241 | static irqreturn_t samsung_clock_event_isr(int irq, void *dev_id) | 251 | static irqreturn_t samsung_clock_event_isr(int irq, void *dev_id) |
@@ -286,23 +296,34 @@ static void __init samsung_clockevent_init(void) | |||
286 | } | 296 | } |
287 | } | 297 | } |
288 | 298 | ||
289 | static void __iomem *samsung_timer_reg(void) | 299 | static void samsung_clocksource_suspend(struct clocksource *cs) |
290 | { | 300 | { |
291 | switch (pwm.source_id) { | 301 | samsung_time_stop(pwm.source_id); |
292 | case 0: | ||
293 | case 1: | ||
294 | case 2: | ||
295 | case 3: | ||
296 | return pwm.base + pwm.source_id * 0x0c + 0x14; | ||
297 | |||
298 | case 4: | ||
299 | return pwm.base + 0x40; | ||
300 | |||
301 | default: | ||
302 | BUG(); | ||
303 | } | ||
304 | } | 302 | } |
305 | 303 | ||
304 | static void samsung_clocksource_resume(struct clocksource *cs) | ||
305 | { | ||
306 | samsung_timer_set_prescale(pwm.source_id, pwm.tscaler_div); | ||
307 | samsung_timer_set_divisor(pwm.source_id, pwm.tdiv); | ||
308 | |||
309 | samsung_time_setup(pwm.source_id, pwm.tcnt_max); | ||
310 | samsung_time_start(pwm.source_id, true); | ||
311 | } | ||
312 | |||
313 | static cycle_t samsung_clocksource_read(struct clocksource *c) | ||
314 | { | ||
315 | return ~readl_relaxed(pwm.source_reg); | ||
316 | } | ||
317 | |||
318 | static struct clocksource samsung_clocksource = { | ||
319 | .name = "samsung_clocksource_timer", | ||
320 | .rating = 250, | ||
321 | .read = samsung_clocksource_read, | ||
322 | .suspend = samsung_clocksource_suspend, | ||
323 | .resume = samsung_clocksource_resume, | ||
324 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, | ||
325 | }; | ||
326 | |||
306 | /* | 327 | /* |
307 | * Override the global weak sched_clock symbol with this | 328 | * Override the global weak sched_clock symbol with this |
308 | * local implementation which uses the clocksource to get some | 329 | * local implementation which uses the clocksource to get some |
@@ -312,17 +333,11 @@ static void __iomem *samsung_timer_reg(void) | |||
312 | */ | 333 | */ |
313 | static u64 notrace samsung_read_sched_clock(void) | 334 | static u64 notrace samsung_read_sched_clock(void) |
314 | { | 335 | { |
315 | void __iomem *reg = samsung_timer_reg(); | 336 | return samsung_clocksource_read(NULL); |
316 | |||
317 | if (!reg) | ||
318 | return 0; | ||
319 | |||
320 | return ~__raw_readl(reg); | ||
321 | } | 337 | } |
322 | 338 | ||
323 | static void __init samsung_clocksource_init(void) | 339 | static void __init samsung_clocksource_init(void) |
324 | { | 340 | { |
325 | void __iomem *reg = samsung_timer_reg(); | ||
326 | unsigned long pclk; | 341 | unsigned long pclk; |
327 | unsigned long clock_rate; | 342 | unsigned long clock_rate; |
328 | int ret; | 343 | int ret; |
@@ -337,22 +352,22 @@ static void __init samsung_clocksource_init(void) | |||
337 | samsung_time_setup(pwm.source_id, pwm.tcnt_max); | 352 | samsung_time_setup(pwm.source_id, pwm.tcnt_max); |
338 | samsung_time_start(pwm.source_id, true); | 353 | samsung_time_start(pwm.source_id, true); |
339 | 354 | ||
355 | if (pwm.source_id == 4) | ||
356 | pwm.source_reg = pwm.base + 0x40; | ||
357 | else | ||
358 | pwm.source_reg = pwm.base + pwm.source_id * 0x0c + 0x14; | ||
359 | |||
340 | sched_clock_register(samsung_read_sched_clock, | 360 | sched_clock_register(samsung_read_sched_clock, |
341 | pwm.variant.bits, clock_rate); | 361 | pwm.variant.bits, clock_rate); |
342 | 362 | ||
343 | ret = clocksource_mmio_init(reg, "samsung_clocksource_timer", | 363 | samsung_clocksource.mask = CLOCKSOURCE_MASK(pwm.variant.bits); |
344 | clock_rate, 250, pwm.variant.bits, | 364 | ret = clocksource_register_hz(&samsung_clocksource, clock_rate); |
345 | clocksource_mmio_readl_down); | ||
346 | if (ret) | 365 | if (ret) |
347 | panic("samsung_clocksource_timer: can't register clocksource\n"); | 366 | panic("samsung_clocksource_timer: can't register clocksource\n"); |
348 | } | 367 | } |
349 | 368 | ||
350 | static void __init samsung_timer_resources(void) | 369 | static void __init samsung_timer_resources(void) |
351 | { | 370 | { |
352 | pwm.timerclk = clk_get(NULL, "timers"); | ||
353 | if (IS_ERR(pwm.timerclk)) | ||
354 | panic("failed to get timers clock for timer"); | ||
355 | |||
356 | clk_prepare_enable(pwm.timerclk); | 371 | clk_prepare_enable(pwm.timerclk); |
357 | 372 | ||
358 | pwm.tcnt_max = (1UL << pwm.variant.bits) - 1; | 373 | pwm.tcnt_max = (1UL << pwm.variant.bits) - 1; |
@@ -397,6 +412,10 @@ void __init samsung_pwm_clocksource_init(void __iomem *base, | |||
397 | memcpy(&pwm.variant, variant, sizeof(pwm.variant)); | 412 | memcpy(&pwm.variant, variant, sizeof(pwm.variant)); |
398 | memcpy(pwm.irq, irqs, SAMSUNG_PWM_NUM * sizeof(*irqs)); | 413 | memcpy(pwm.irq, irqs, SAMSUNG_PWM_NUM * sizeof(*irqs)); |
399 | 414 | ||
415 | pwm.timerclk = clk_get(NULL, "timers"); | ||
416 | if (IS_ERR(pwm.timerclk)) | ||
417 | panic("failed to get timers clock for timer"); | ||
418 | |||
400 | _samsung_pwm_clocksource_init(); | 419 | _samsung_pwm_clocksource_init(); |
401 | } | 420 | } |
402 | 421 | ||
@@ -404,7 +423,6 @@ void __init samsung_pwm_clocksource_init(void __iomem *base, | |||
404 | static void __init samsung_pwm_alloc(struct device_node *np, | 423 | static void __init samsung_pwm_alloc(struct device_node *np, |
405 | const struct samsung_pwm_variant *variant) | 424 | const struct samsung_pwm_variant *variant) |
406 | { | 425 | { |
407 | struct resource res; | ||
408 | struct property *prop; | 426 | struct property *prop; |
409 | const __be32 *cur; | 427 | const __be32 *cur; |
410 | u32 val; | 428 | u32 val; |
@@ -423,20 +441,16 @@ static void __init samsung_pwm_alloc(struct device_node *np, | |||
423 | pwm.variant.output_mask |= 1 << val; | 441 | pwm.variant.output_mask |= 1 << val; |
424 | } | 442 | } |
425 | 443 | ||
426 | of_address_to_resource(np, 0, &res); | 444 | pwm.base = of_iomap(np, 0); |
427 | if (!request_mem_region(res.start, | ||
428 | resource_size(&res), "samsung-pwm")) { | ||
429 | pr_err("%s: failed to request IO mem region\n", __func__); | ||
430 | return; | ||
431 | } | ||
432 | |||
433 | pwm.base = ioremap(res.start, resource_size(&res)); | ||
434 | if (!pwm.base) { | 445 | if (!pwm.base) { |
435 | pr_err("%s: failed to map PWM registers\n", __func__); | 446 | pr_err("%s: failed to map PWM registers\n", __func__); |
436 | release_mem_region(res.start, resource_size(&res)); | ||
437 | return; | 447 | return; |
438 | } | 448 | } |
439 | 449 | ||
450 | pwm.timerclk = of_clk_get_by_name(np, "timers"); | ||
451 | if (IS_ERR(pwm.timerclk)) | ||
452 | panic("failed to get timers clock for timer"); | ||
453 | |||
440 | _samsung_pwm_clocksource_init(); | 454 | _samsung_pwm_clocksource_init(); |
441 | } | 455 | } |
442 | 456 | ||
diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c index 08d0c418c94a..0965e9848b3d 100644 --- a/drivers/clocksource/sh_cmt.c +++ b/drivers/clocksource/sh_cmt.c | |||
@@ -37,6 +37,7 @@ | |||
37 | 37 | ||
38 | struct sh_cmt_priv { | 38 | struct sh_cmt_priv { |
39 | void __iomem *mapbase; | 39 | void __iomem *mapbase; |
40 | void __iomem *mapbase_str; | ||
40 | struct clk *clk; | 41 | struct clk *clk; |
41 | unsigned long width; /* 16 or 32 bit version of hardware block */ | 42 | unsigned long width; /* 16 or 32 bit version of hardware block */ |
42 | unsigned long overflow_bit; | 43 | unsigned long overflow_bit; |
@@ -79,6 +80,12 @@ struct sh_cmt_priv { | |||
79 | * CMCSR 0xffca0060 16-bit | 80 | * CMCSR 0xffca0060 16-bit |
80 | * CMCNT 0xffca0064 32-bit | 81 | * CMCNT 0xffca0064 32-bit |
81 | * CMCOR 0xffca0068 32-bit | 82 | * CMCOR 0xffca0068 32-bit |
83 | * | ||
84 | * "32-bit counter and 32-bit control" as found on r8a73a4 and r8a7790: | ||
85 | * CMSTR 0xffca0500 32-bit | ||
86 | * CMCSR 0xffca0510 32-bit | ||
87 | * CMCNT 0xffca0514 32-bit | ||
88 | * CMCOR 0xffca0518 32-bit | ||
82 | */ | 89 | */ |
83 | 90 | ||
84 | static unsigned long sh_cmt_read16(void __iomem *base, unsigned long offs) | 91 | static unsigned long sh_cmt_read16(void __iomem *base, unsigned long offs) |
@@ -109,9 +116,7 @@ static void sh_cmt_write32(void __iomem *base, unsigned long offs, | |||
109 | 116 | ||
110 | static inline unsigned long sh_cmt_read_cmstr(struct sh_cmt_priv *p) | 117 | static inline unsigned long sh_cmt_read_cmstr(struct sh_cmt_priv *p) |
111 | { | 118 | { |
112 | struct sh_timer_config *cfg = p->pdev->dev.platform_data; | 119 | return p->read_control(p->mapbase_str, 0); |
113 | |||
114 | return p->read_control(p->mapbase - cfg->channel_offset, 0); | ||
115 | } | 120 | } |
116 | 121 | ||
117 | static inline unsigned long sh_cmt_read_cmcsr(struct sh_cmt_priv *p) | 122 | static inline unsigned long sh_cmt_read_cmcsr(struct sh_cmt_priv *p) |
@@ -127,9 +132,7 @@ static inline unsigned long sh_cmt_read_cmcnt(struct sh_cmt_priv *p) | |||
127 | static inline void sh_cmt_write_cmstr(struct sh_cmt_priv *p, | 132 | static inline void sh_cmt_write_cmstr(struct sh_cmt_priv *p, |
128 | unsigned long value) | 133 | unsigned long value) |
129 | { | 134 | { |
130 | struct sh_timer_config *cfg = p->pdev->dev.platform_data; | 135 | p->write_control(p->mapbase_str, 0, value); |
131 | |||
132 | p->write_control(p->mapbase - cfg->channel_offset, 0, value); | ||
133 | } | 136 | } |
134 | 137 | ||
135 | static inline void sh_cmt_write_cmcsr(struct sh_cmt_priv *p, | 138 | static inline void sh_cmt_write_cmcsr(struct sh_cmt_priv *p, |
@@ -676,7 +679,7 @@ static int sh_cmt_register(struct sh_cmt_priv *p, char *name, | |||
676 | static int sh_cmt_setup(struct sh_cmt_priv *p, struct platform_device *pdev) | 679 | static int sh_cmt_setup(struct sh_cmt_priv *p, struct platform_device *pdev) |
677 | { | 680 | { |
678 | struct sh_timer_config *cfg = pdev->dev.platform_data; | 681 | struct sh_timer_config *cfg = pdev->dev.platform_data; |
679 | struct resource *res; | 682 | struct resource *res, *res2; |
680 | int irq, ret; | 683 | int irq, ret; |
681 | ret = -ENXIO; | 684 | ret = -ENXIO; |
682 | 685 | ||
@@ -694,6 +697,9 @@ static int sh_cmt_setup(struct sh_cmt_priv *p, struct platform_device *pdev) | |||
694 | goto err0; | 697 | goto err0; |
695 | } | 698 | } |
696 | 699 | ||
700 | /* optional resource for the shared timer start/stop register */ | ||
701 | res2 = platform_get_resource(p->pdev, IORESOURCE_MEM, 1); | ||
702 | |||
697 | irq = platform_get_irq(p->pdev, 0); | 703 | irq = platform_get_irq(p->pdev, 0); |
698 | if (irq < 0) { | 704 | if (irq < 0) { |
699 | dev_err(&p->pdev->dev, "failed to get irq\n"); | 705 | dev_err(&p->pdev->dev, "failed to get irq\n"); |
@@ -707,6 +713,15 @@ static int sh_cmt_setup(struct sh_cmt_priv *p, struct platform_device *pdev) | |||
707 | goto err0; | 713 | goto err0; |
708 | } | 714 | } |
709 | 715 | ||
716 | /* map second resource for CMSTR */ | ||
717 | p->mapbase_str = ioremap_nocache(res2 ? res2->start : | ||
718 | res->start - cfg->channel_offset, | ||
719 | res2 ? resource_size(res2) : 2); | ||
720 | if (p->mapbase_str == NULL) { | ||
721 | dev_err(&p->pdev->dev, "failed to remap I/O second memory\n"); | ||
722 | goto err1; | ||
723 | } | ||
724 | |||
710 | /* request irq using setup_irq() (too early for request_irq()) */ | 725 | /* request irq using setup_irq() (too early for request_irq()) */ |
711 | p->irqaction.name = dev_name(&p->pdev->dev); | 726 | p->irqaction.name = dev_name(&p->pdev->dev); |
712 | p->irqaction.handler = sh_cmt_interrupt; | 727 | p->irqaction.handler = sh_cmt_interrupt; |
@@ -719,11 +734,17 @@ static int sh_cmt_setup(struct sh_cmt_priv *p, struct platform_device *pdev) | |||
719 | if (IS_ERR(p->clk)) { | 734 | if (IS_ERR(p->clk)) { |
720 | dev_err(&p->pdev->dev, "cannot get clock\n"); | 735 | dev_err(&p->pdev->dev, "cannot get clock\n"); |
721 | ret = PTR_ERR(p->clk); | 736 | ret = PTR_ERR(p->clk); |
722 | goto err1; | 737 | goto err2; |
723 | } | 738 | } |
724 | 739 | ||
725 | p->read_control = sh_cmt_read16; | 740 | if (res2 && (resource_size(res2) == 4)) { |
726 | p->write_control = sh_cmt_write16; | 741 | /* assume both CMSTR and CMCSR to be 32-bit */ |
742 | p->read_control = sh_cmt_read32; | ||
743 | p->write_control = sh_cmt_write32; | ||
744 | } else { | ||
745 | p->read_control = sh_cmt_read16; | ||
746 | p->write_control = sh_cmt_write16; | ||
747 | } | ||
727 | 748 | ||
728 | if (resource_size(res) == 6) { | 749 | if (resource_size(res) == 6) { |
729 | p->width = 16; | 750 | p->width = 16; |
@@ -752,22 +773,23 @@ static int sh_cmt_setup(struct sh_cmt_priv *p, struct platform_device *pdev) | |||
752 | cfg->clocksource_rating); | 773 | cfg->clocksource_rating); |
753 | if (ret) { | 774 | if (ret) { |
754 | dev_err(&p->pdev->dev, "registration failed\n"); | 775 | dev_err(&p->pdev->dev, "registration failed\n"); |
755 | goto err2; | 776 | goto err3; |
756 | } | 777 | } |
757 | p->cs_enabled = false; | 778 | p->cs_enabled = false; |
758 | 779 | ||
759 | ret = setup_irq(irq, &p->irqaction); | 780 | ret = setup_irq(irq, &p->irqaction); |
760 | if (ret) { | 781 | if (ret) { |
761 | dev_err(&p->pdev->dev, "failed to request irq %d\n", irq); | 782 | dev_err(&p->pdev->dev, "failed to request irq %d\n", irq); |
762 | goto err2; | 783 | goto err3; |
763 | } | 784 | } |
764 | 785 | ||
765 | platform_set_drvdata(pdev, p); | 786 | platform_set_drvdata(pdev, p); |
766 | 787 | ||
767 | return 0; | 788 | return 0; |
768 | err2: | 789 | err3: |
769 | clk_put(p->clk); | 790 | clk_put(p->clk); |
770 | 791 | err2: | |
792 | iounmap(p->mapbase_str); | ||
771 | err1: | 793 | err1: |
772 | iounmap(p->mapbase); | 794 | iounmap(p->mapbase); |
773 | err0: | 795 | err0: |
diff --git a/drivers/clocksource/sun4i_timer.c b/drivers/clocksource/sun4i_timer.c index d4674e78ef35..8ead0258740a 100644 --- a/drivers/clocksource/sun4i_timer.c +++ b/drivers/clocksource/sun4i_timer.c | |||
@@ -19,42 +19,83 @@ | |||
19 | #include <linux/interrupt.h> | 19 | #include <linux/interrupt.h> |
20 | #include <linux/irq.h> | 20 | #include <linux/irq.h> |
21 | #include <linux/irqreturn.h> | 21 | #include <linux/irqreturn.h> |
22 | #include <linux/sched_clock.h> | ||
22 | #include <linux/of.h> | 23 | #include <linux/of.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 | 26 | ||
26 | #define TIMER_IRQ_EN_REG 0x00 | 27 | #define TIMER_IRQ_EN_REG 0x00 |
27 | #define TIMER_IRQ_EN(val) (1 << val) | 28 | #define TIMER_IRQ_EN(val) BIT(val) |
28 | #define TIMER_IRQ_ST_REG 0x04 | 29 | #define TIMER_IRQ_ST_REG 0x04 |
29 | #define TIMER_CTL_REG(val) (0x10 * val + 0x10) | 30 | #define TIMER_CTL_REG(val) (0x10 * val + 0x10) |
30 | #define TIMER_CTL_ENABLE (1 << 0) | 31 | #define TIMER_CTL_ENABLE BIT(0) |
31 | #define TIMER_CTL_AUTORELOAD (1 << 1) | 32 | #define TIMER_CTL_RELOAD BIT(1) |
32 | #define TIMER_CTL_ONESHOT (1 << 7) | 33 | #define TIMER_CTL_CLK_SRC(val) (((val) & 0x3) << 2) |
33 | #define TIMER_INTVAL_REG(val) (0x10 * val + 0x14) | 34 | #define TIMER_CTL_CLK_SRC_OSC24M (1) |
34 | #define TIMER_CNTVAL_REG(val) (0x10 * val + 0x18) | 35 | #define TIMER_CTL_CLK_PRES(val) (((val) & 0x7) << 4) |
35 | 36 | #define TIMER_CTL_ONESHOT BIT(7) | |
36 | #define TIMER_SCAL 16 | 37 | #define TIMER_INTVAL_REG(val) (0x10 * (val) + 0x14) |
38 | #define TIMER_CNTVAL_REG(val) (0x10 * (val) + 0x18) | ||
37 | 39 | ||
38 | static void __iomem *timer_base; | 40 | static void __iomem *timer_base; |
41 | static u32 ticks_per_jiffy; | ||
42 | |||
43 | /* | ||
44 | * When we disable a timer, we need to wait at least for 2 cycles of | ||
45 | * the timer source clock. We will use for that the clocksource timer | ||
46 | * that is already setup and runs at the same frequency than the other | ||
47 | * timers, and we never will be disabled. | ||
48 | */ | ||
49 | static void sun4i_clkevt_sync(void) | ||
50 | { | ||
51 | u32 old = readl(timer_base + TIMER_CNTVAL_REG(1)); | ||
52 | |||
53 | while ((old - readl(timer_base + TIMER_CNTVAL_REG(1))) < 3) | ||
54 | cpu_relax(); | ||
55 | } | ||
56 | |||
57 | static void sun4i_clkevt_time_stop(u8 timer) | ||
58 | { | ||
59 | u32 val = readl(timer_base + TIMER_CTL_REG(timer)); | ||
60 | writel(val & ~TIMER_CTL_ENABLE, timer_base + TIMER_CTL_REG(timer)); | ||
61 | sun4i_clkevt_sync(); | ||
62 | } | ||
63 | |||
64 | static void sun4i_clkevt_time_setup(u8 timer, unsigned long delay) | ||
65 | { | ||
66 | writel(delay, timer_base + TIMER_INTVAL_REG(timer)); | ||
67 | } | ||
68 | |||
69 | static void sun4i_clkevt_time_start(u8 timer, bool periodic) | ||
70 | { | ||
71 | u32 val = readl(timer_base + TIMER_CTL_REG(timer)); | ||
72 | |||
73 | if (periodic) | ||
74 | val &= ~TIMER_CTL_ONESHOT; | ||
75 | else | ||
76 | val |= TIMER_CTL_ONESHOT; | ||
77 | |||
78 | writel(val | TIMER_CTL_ENABLE | TIMER_CTL_RELOAD, | ||
79 | timer_base + TIMER_CTL_REG(timer)); | ||
80 | } | ||
39 | 81 | ||
40 | static void sun4i_clkevt_mode(enum clock_event_mode mode, | 82 | static void sun4i_clkevt_mode(enum clock_event_mode mode, |
41 | struct clock_event_device *clk) | 83 | struct clock_event_device *clk) |
42 | { | 84 | { |
43 | u32 u = readl(timer_base + TIMER_CTL_REG(0)); | ||
44 | |||
45 | switch (mode) { | 85 | switch (mode) { |
46 | case CLOCK_EVT_MODE_PERIODIC: | 86 | case CLOCK_EVT_MODE_PERIODIC: |
47 | u &= ~(TIMER_CTL_ONESHOT); | 87 | sun4i_clkevt_time_stop(0); |
48 | writel(u | TIMER_CTL_ENABLE, timer_base + TIMER_CTL_REG(0)); | 88 | sun4i_clkevt_time_setup(0, ticks_per_jiffy); |
89 | sun4i_clkevt_time_start(0, true); | ||
49 | break; | 90 | break; |
50 | |||
51 | case CLOCK_EVT_MODE_ONESHOT: | 91 | case CLOCK_EVT_MODE_ONESHOT: |
52 | writel(u | TIMER_CTL_ONESHOT, timer_base + TIMER_CTL_REG(0)); | 92 | sun4i_clkevt_time_stop(0); |
93 | sun4i_clkevt_time_start(0, false); | ||
53 | break; | 94 | break; |
54 | case CLOCK_EVT_MODE_UNUSED: | 95 | case CLOCK_EVT_MODE_UNUSED: |
55 | case CLOCK_EVT_MODE_SHUTDOWN: | 96 | case CLOCK_EVT_MODE_SHUTDOWN: |
56 | default: | 97 | default: |
57 | writel(u & ~(TIMER_CTL_ENABLE), timer_base + TIMER_CTL_REG(0)); | 98 | sun4i_clkevt_time_stop(0); |
58 | break; | 99 | break; |
59 | } | 100 | } |
60 | } | 101 | } |
@@ -62,10 +103,9 @@ static void sun4i_clkevt_mode(enum clock_event_mode mode, | |||
62 | static int sun4i_clkevt_next_event(unsigned long evt, | 103 | static int sun4i_clkevt_next_event(unsigned long evt, |
63 | struct clock_event_device *unused) | 104 | struct clock_event_device *unused) |
64 | { | 105 | { |
65 | u32 u = readl(timer_base + TIMER_CTL_REG(0)); | 106 | sun4i_clkevt_time_stop(0); |
66 | writel(evt, timer_base + TIMER_CNTVAL_REG(0)); | 107 | sun4i_clkevt_time_setup(0, evt); |
67 | writel(u | TIMER_CTL_ENABLE | TIMER_CTL_AUTORELOAD, | 108 | sun4i_clkevt_time_start(0, false); |
68 | timer_base + TIMER_CTL_REG(0)); | ||
69 | 109 | ||
70 | return 0; | 110 | return 0; |
71 | } | 111 | } |
@@ -96,6 +136,11 @@ static struct irqaction sun4i_timer_irq = { | |||
96 | .dev_id = &sun4i_clockevent, | 136 | .dev_id = &sun4i_clockevent, |
97 | }; | 137 | }; |
98 | 138 | ||
139 | static u32 sun4i_timer_sched_read(void) | ||
140 | { | ||
141 | return ~readl(timer_base + TIMER_CNTVAL_REG(1)); | ||
142 | } | ||
143 | |||
99 | static void __init sun4i_timer_init(struct device_node *node) | 144 | static void __init sun4i_timer_init(struct device_node *node) |
100 | { | 145 | { |
101 | unsigned long rate = 0; | 146 | unsigned long rate = 0; |
@@ -114,22 +159,23 @@ static void __init sun4i_timer_init(struct device_node *node) | |||
114 | clk = of_clk_get(node, 0); | 159 | clk = of_clk_get(node, 0); |
115 | if (IS_ERR(clk)) | 160 | if (IS_ERR(clk)) |
116 | panic("Can't get timer clock"); | 161 | panic("Can't get timer clock"); |
162 | clk_prepare_enable(clk); | ||
117 | 163 | ||
118 | rate = clk_get_rate(clk); | 164 | rate = clk_get_rate(clk); |
119 | 165 | ||
120 | writel(rate / (TIMER_SCAL * HZ), | 166 | writel(~0, timer_base + TIMER_INTVAL_REG(1)); |
121 | timer_base + TIMER_INTVAL_REG(0)); | 167 | writel(TIMER_CTL_ENABLE | TIMER_CTL_RELOAD | |
168 | TIMER_CTL_CLK_SRC(TIMER_CTL_CLK_SRC_OSC24M), | ||
169 | timer_base + TIMER_CTL_REG(1)); | ||
170 | |||
171 | setup_sched_clock(sun4i_timer_sched_read, 32, rate); | ||
172 | clocksource_mmio_init(timer_base + TIMER_CNTVAL_REG(1), node->name, | ||
173 | rate, 300, 32, clocksource_mmio_readl_down); | ||
122 | 174 | ||
123 | /* set clock source to HOSC, 16 pre-division */ | 175 | ticks_per_jiffy = DIV_ROUND_UP(rate, HZ); |
124 | val = readl(timer_base + TIMER_CTL_REG(0)); | ||
125 | val &= ~(0x07 << 4); | ||
126 | val &= ~(0x03 << 2); | ||
127 | val |= (4 << 4) | (1 << 2); | ||
128 | writel(val, timer_base + TIMER_CTL_REG(0)); | ||
129 | 176 | ||
130 | /* set mode to auto reload */ | 177 | writel(TIMER_CTL_CLK_SRC(TIMER_CTL_CLK_SRC_OSC24M), |
131 | val = readl(timer_base + TIMER_CTL_REG(0)); | 178 | timer_base + TIMER_CTL_REG(0)); |
132 | writel(val | TIMER_CTL_AUTORELOAD, timer_base + TIMER_CTL_REG(0)); | ||
133 | 179 | ||
134 | ret = setup_irq(irq, &sun4i_timer_irq); | 180 | ret = setup_irq(irq, &sun4i_timer_irq); |
135 | if (ret) | 181 | if (ret) |
@@ -141,8 +187,8 @@ static void __init sun4i_timer_init(struct device_node *node) | |||
141 | 187 | ||
142 | sun4i_clockevent.cpumask = cpumask_of(0); | 188 | sun4i_clockevent.cpumask = cpumask_of(0); |
143 | 189 | ||
144 | clockevents_config_and_register(&sun4i_clockevent, rate / TIMER_SCAL, | 190 | clockevents_config_and_register(&sun4i_clockevent, rate, 0x1, |
145 | 0x1, 0xff); | 191 | 0xffffffff); |
146 | } | 192 | } |
147 | CLOCKSOURCE_OF_DECLARE(sun4i, "allwinner,sun4i-timer", | 193 | CLOCKSOURCE_OF_DECLARE(sun4i, "allwinner,sun4i-timer", |
148 | sun4i_timer_init); | 194 | sun4i_timer_init); |
diff --git a/drivers/clocksource/time-armada-370-xp.c b/drivers/clocksource/time-armada-370-xp.c index 2bec8dca74b6..d8e47e502785 100644 --- a/drivers/clocksource/time-armada-370-xp.c +++ b/drivers/clocksource/time-armada-370-xp.c | |||
@@ -13,12 +13,26 @@ | |||
13 | * | 13 | * |
14 | * Timer 0 is used as free-running clocksource, while timer 1 is | 14 | * Timer 0 is used as free-running clocksource, while timer 1 is |
15 | * used as clock_event_device. | 15 | * used as clock_event_device. |
16 | * | ||
17 | * --- | ||
18 | * Clocksource driver for Armada 370 and Armada XP SoC. | ||
19 | * This driver implements one compatible string for each SoC, given | ||
20 | * each has its own characteristics: | ||
21 | * | ||
22 | * * Armada 370 has no 25 MHz fixed timer. | ||
23 | * | ||
24 | * * Armada XP cannot work properly without such 25 MHz fixed timer as | ||
25 | * doing otherwise leads to using a clocksource whose frequency varies | ||
26 | * when doing cpufreq frequency changes. | ||
27 | * | ||
28 | * See Documentation/devicetree/bindings/timer/marvell,armada-370-xp-timer.txt | ||
16 | */ | 29 | */ |
17 | 30 | ||
18 | #include <linux/init.h> | 31 | #include <linux/init.h> |
19 | #include <linux/platform_device.h> | 32 | #include <linux/platform_device.h> |
20 | #include <linux/kernel.h> | 33 | #include <linux/kernel.h> |
21 | #include <linux/clk.h> | 34 | #include <linux/clk.h> |
35 | #include <linux/cpu.h> | ||
22 | #include <linux/timer.h> | 36 | #include <linux/timer.h> |
23 | #include <linux/clockchips.h> | 37 | #include <linux/clockchips.h> |
24 | #include <linux/interrupt.h> | 38 | #include <linux/interrupt.h> |
@@ -28,20 +42,19 @@ | |||
28 | #include <linux/irq.h> | 42 | #include <linux/irq.h> |
29 | #include <linux/module.h> | 43 | #include <linux/module.h> |
30 | #include <linux/sched_clock.h> | 44 | #include <linux/sched_clock.h> |
31 | |||
32 | #include <asm/localtimer.h> | ||
33 | #include <linux/percpu.h> | 45 | #include <linux/percpu.h> |
46 | |||
34 | /* | 47 | /* |
35 | * Timer block registers. | 48 | * Timer block registers. |
36 | */ | 49 | */ |
37 | #define TIMER_CTRL_OFF 0x0000 | 50 | #define TIMER_CTRL_OFF 0x0000 |
38 | #define TIMER0_EN 0x0001 | 51 | #define TIMER0_EN BIT(0) |
39 | #define TIMER0_RELOAD_EN 0x0002 | 52 | #define TIMER0_RELOAD_EN BIT(1) |
40 | #define TIMER0_25MHZ 0x0800 | 53 | #define TIMER0_25MHZ BIT(11) |
41 | #define TIMER0_DIV(div) ((div) << 19) | 54 | #define TIMER0_DIV(div) ((div) << 19) |
42 | #define TIMER1_EN 0x0004 | 55 | #define TIMER1_EN BIT(2) |
43 | #define TIMER1_RELOAD_EN 0x0008 | 56 | #define TIMER1_RELOAD_EN BIT(3) |
44 | #define TIMER1_25MHZ 0x1000 | 57 | #define TIMER1_25MHZ BIT(12) |
45 | #define TIMER1_DIV(div) ((div) << 22) | 58 | #define TIMER1_DIV(div) ((div) << 22) |
46 | #define TIMER_EVENTS_STATUS 0x0004 | 59 | #define TIMER_EVENTS_STATUS 0x0004 |
47 | #define TIMER0_CLR_MASK (~0x1) | 60 | #define TIMER0_CLR_MASK (~0x1) |
@@ -69,7 +82,19 @@ static bool timer25Mhz = true; | |||
69 | */ | 82 | */ |
70 | static u32 ticks_per_jiffy; | 83 | static u32 ticks_per_jiffy; |
71 | 84 | ||
72 | static struct clock_event_device __percpu **percpu_armada_370_xp_evt; | 85 | static struct clock_event_device __percpu *armada_370_xp_evt; |
86 | |||
87 | static void timer_ctrl_clrset(u32 clr, u32 set) | ||
88 | { | ||
89 | writel((readl(timer_base + TIMER_CTRL_OFF) & ~clr) | set, | ||
90 | timer_base + TIMER_CTRL_OFF); | ||
91 | } | ||
92 | |||
93 | static void local_timer_ctrl_clrset(u32 clr, u32 set) | ||
94 | { | ||
95 | writel((readl(local_base + TIMER_CTRL_OFF) & ~clr) | set, | ||
96 | local_base + TIMER_CTRL_OFF); | ||
97 | } | ||
73 | 98 | ||
74 | static u64 notrace armada_370_xp_read_sched_clock(void) | 99 | static u64 notrace armada_370_xp_read_sched_clock(void) |
75 | { | 100 | { |
@@ -83,7 +108,6 @@ static int | |||
83 | armada_370_xp_clkevt_next_event(unsigned long delta, | 108 | armada_370_xp_clkevt_next_event(unsigned long delta, |
84 | struct clock_event_device *dev) | 109 | struct clock_event_device *dev) |
85 | { | 110 | { |
86 | u32 u; | ||
87 | /* | 111 | /* |
88 | * Clear clockevent timer interrupt. | 112 | * Clear clockevent timer interrupt. |
89 | */ | 113 | */ |
@@ -97,11 +121,8 @@ armada_370_xp_clkevt_next_event(unsigned long delta, | |||
97 | /* | 121 | /* |
98 | * Enable the timer. | 122 | * Enable the timer. |
99 | */ | 123 | */ |
100 | u = readl(local_base + TIMER_CTRL_OFF); | 124 | local_timer_ctrl_clrset(TIMER0_RELOAD_EN, |
101 | u = ((u & ~TIMER0_RELOAD_EN) | TIMER0_EN | | 125 | TIMER0_EN | TIMER0_DIV(TIMER_DIVIDER_SHIFT)); |
102 | TIMER0_DIV(TIMER_DIVIDER_SHIFT)); | ||
103 | writel(u, local_base + TIMER_CTRL_OFF); | ||
104 | |||
105 | return 0; | 126 | return 0; |
106 | } | 127 | } |
107 | 128 | ||
@@ -109,8 +130,6 @@ static void | |||
109 | armada_370_xp_clkevt_mode(enum clock_event_mode mode, | 130 | armada_370_xp_clkevt_mode(enum clock_event_mode mode, |
110 | struct clock_event_device *dev) | 131 | struct clock_event_device *dev) |
111 | { | 132 | { |
112 | u32 u; | ||
113 | |||
114 | if (mode == CLOCK_EVT_MODE_PERIODIC) { | 133 | if (mode == CLOCK_EVT_MODE_PERIODIC) { |
115 | 134 | ||
116 | /* | 135 | /* |
@@ -122,18 +141,14 @@ armada_370_xp_clkevt_mode(enum clock_event_mode mode, | |||
122 | /* | 141 | /* |
123 | * Enable timer. | 142 | * Enable timer. |
124 | */ | 143 | */ |
125 | 144 | local_timer_ctrl_clrset(0, TIMER0_RELOAD_EN | | |
126 | u = readl(local_base + TIMER_CTRL_OFF); | 145 | TIMER0_EN | |
127 | 146 | TIMER0_DIV(TIMER_DIVIDER_SHIFT)); | |
128 | writel((u | TIMER0_EN | TIMER0_RELOAD_EN | | ||
129 | TIMER0_DIV(TIMER_DIVIDER_SHIFT)), | ||
130 | local_base + TIMER_CTRL_OFF); | ||
131 | } else { | 147 | } else { |
132 | /* | 148 | /* |
133 | * Disable timer. | 149 | * Disable timer. |
134 | */ | 150 | */ |
135 | u = readl(local_base + TIMER_CTRL_OFF); | 151 | local_timer_ctrl_clrset(TIMER0_EN, 0); |
136 | writel(u & ~TIMER0_EN, local_base + TIMER_CTRL_OFF); | ||
137 | 152 | ||
138 | /* | 153 | /* |
139 | * ACK pending timer interrupt. | 154 | * ACK pending timer interrupt. |
@@ -142,21 +157,14 @@ armada_370_xp_clkevt_mode(enum clock_event_mode mode, | |||
142 | } | 157 | } |
143 | } | 158 | } |
144 | 159 | ||
145 | static struct clock_event_device armada_370_xp_clkevt = { | 160 | static int armada_370_xp_clkevt_irq; |
146 | .name = "armada_370_xp_per_cpu_tick", | ||
147 | .features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC, | ||
148 | .shift = 32, | ||
149 | .rating = 300, | ||
150 | .set_next_event = armada_370_xp_clkevt_next_event, | ||
151 | .set_mode = armada_370_xp_clkevt_mode, | ||
152 | }; | ||
153 | 161 | ||
154 | static irqreturn_t armada_370_xp_timer_interrupt(int irq, void *dev_id) | 162 | static irqreturn_t armada_370_xp_timer_interrupt(int irq, void *dev_id) |
155 | { | 163 | { |
156 | /* | 164 | /* |
157 | * ACK timer interrupt and call event handler. | 165 | * ACK timer interrupt and call event handler. |
158 | */ | 166 | */ |
159 | struct clock_event_device *evt = *(struct clock_event_device **)dev_id; | 167 | struct clock_event_device *evt = dev_id; |
160 | 168 | ||
161 | writel(TIMER0_CLR_MASK, local_base + LCL_TIMER_EVENTS_STATUS); | 169 | writel(TIMER0_CLR_MASK, local_base + LCL_TIMER_EVENTS_STATUS); |
162 | evt->event_handler(evt); | 170 | evt->event_handler(evt); |
@@ -167,91 +175,83 @@ static irqreturn_t armada_370_xp_timer_interrupt(int irq, void *dev_id) | |||
167 | /* | 175 | /* |
168 | * Setup the local clock events for a CPU. | 176 | * Setup the local clock events for a CPU. |
169 | */ | 177 | */ |
170 | static int __cpuinit armada_370_xp_timer_setup(struct clock_event_device *evt) | 178 | static int armada_370_xp_timer_setup(struct clock_event_device *evt) |
171 | { | 179 | { |
172 | u32 u; | 180 | u32 clr = 0, set = 0; |
173 | int cpu = smp_processor_id(); | 181 | int cpu = smp_processor_id(); |
174 | 182 | ||
175 | /* Use existing clock_event for cpu 0 */ | ||
176 | if (!smp_processor_id()) | ||
177 | return 0; | ||
178 | |||
179 | u = readl(local_base + TIMER_CTRL_OFF); | ||
180 | if (timer25Mhz) | 183 | if (timer25Mhz) |
181 | writel(u | TIMER0_25MHZ, local_base + TIMER_CTRL_OFF); | 184 | set = TIMER0_25MHZ; |
182 | else | 185 | else |
183 | writel(u & ~TIMER0_25MHZ, local_base + TIMER_CTRL_OFF); | 186 | clr = TIMER0_25MHZ; |
184 | 187 | local_timer_ctrl_clrset(clr, set); | |
185 | evt->name = armada_370_xp_clkevt.name; | 188 | |
186 | evt->irq = armada_370_xp_clkevt.irq; | 189 | evt->name = "armada_370_xp_per_cpu_tick", |
187 | evt->features = armada_370_xp_clkevt.features; | 190 | evt->features = CLOCK_EVT_FEAT_ONESHOT | |
188 | evt->shift = armada_370_xp_clkevt.shift; | 191 | CLOCK_EVT_FEAT_PERIODIC; |
189 | evt->rating = armada_370_xp_clkevt.rating, | 192 | evt->shift = 32, |
193 | evt->rating = 300, | ||
190 | evt->set_next_event = armada_370_xp_clkevt_next_event, | 194 | evt->set_next_event = armada_370_xp_clkevt_next_event, |
191 | evt->set_mode = armada_370_xp_clkevt_mode, | 195 | evt->set_mode = armada_370_xp_clkevt_mode, |
196 | evt->irq = armada_370_xp_clkevt_irq; | ||
192 | evt->cpumask = cpumask_of(cpu); | 197 | evt->cpumask = cpumask_of(cpu); |
193 | 198 | ||
194 | *__this_cpu_ptr(percpu_armada_370_xp_evt) = evt; | ||
195 | |||
196 | clockevents_config_and_register(evt, timer_clk, 1, 0xfffffffe); | 199 | clockevents_config_and_register(evt, timer_clk, 1, 0xfffffffe); |
197 | enable_percpu_irq(evt->irq, 0); | 200 | enable_percpu_irq(evt->irq, 0); |
198 | 201 | ||
199 | return 0; | 202 | return 0; |
200 | } | 203 | } |
201 | 204 | ||
202 | static void armada_370_xp_timer_stop(struct clock_event_device *evt) | 205 | static void armada_370_xp_timer_stop(struct clock_event_device *evt) |
203 | { | 206 | { |
204 | evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt); | 207 | evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt); |
205 | disable_percpu_irq(evt->irq); | 208 | disable_percpu_irq(evt->irq); |
206 | } | 209 | } |
207 | 210 | ||
208 | static struct local_timer_ops armada_370_xp_local_timer_ops __cpuinitdata = { | 211 | static int armada_370_xp_timer_cpu_notify(struct notifier_block *self, |
209 | .setup = armada_370_xp_timer_setup, | 212 | unsigned long action, void *hcpu) |
210 | .stop = armada_370_xp_timer_stop, | 213 | { |
214 | /* | ||
215 | * Grab cpu pointer in each case to avoid spurious | ||
216 | * preemptible warnings | ||
217 | */ | ||
218 | switch (action & ~CPU_TASKS_FROZEN) { | ||
219 | case CPU_STARTING: | ||
220 | armada_370_xp_timer_setup(this_cpu_ptr(armada_370_xp_evt)); | ||
221 | break; | ||
222 | case CPU_DYING: | ||
223 | armada_370_xp_timer_stop(this_cpu_ptr(armada_370_xp_evt)); | ||
224 | break; | ||
225 | } | ||
226 | |||
227 | return NOTIFY_OK; | ||
228 | } | ||
229 | |||
230 | static struct notifier_block armada_370_xp_timer_cpu_nb = { | ||
231 | .notifier_call = armada_370_xp_timer_cpu_notify, | ||
211 | }; | 232 | }; |
212 | 233 | ||
213 | void __init armada_370_xp_timer_init(void) | 234 | static void __init armada_370_xp_timer_common_init(struct device_node *np) |
214 | { | 235 | { |
215 | u32 u; | 236 | u32 clr = 0, set = 0; |
216 | struct device_node *np; | ||
217 | int res; | 237 | int res; |
218 | 238 | ||
219 | np = of_find_compatible_node(NULL, NULL, "marvell,armada-370-xp-timer"); | ||
220 | timer_base = of_iomap(np, 0); | 239 | timer_base = of_iomap(np, 0); |
221 | WARN_ON(!timer_base); | 240 | WARN_ON(!timer_base); |
222 | local_base = of_iomap(np, 1); | 241 | local_base = of_iomap(np, 1); |
223 | 242 | ||
224 | if (of_find_property(np, "marvell,timer-25Mhz", NULL)) { | 243 | if (timer25Mhz) |
225 | /* The fixed 25MHz timer is available so let's use it */ | 244 | set = TIMER0_25MHZ; |
226 | u = readl(local_base + TIMER_CTRL_OFF); | 245 | else |
227 | writel(u | TIMER0_25MHZ, | 246 | clr = TIMER0_25MHZ; |
228 | local_base + TIMER_CTRL_OFF); | 247 | timer_ctrl_clrset(clr, set); |
229 | u = readl(timer_base + TIMER_CTRL_OFF); | 248 | local_timer_ctrl_clrset(clr, set); |
230 | writel(u | TIMER0_25MHZ, | ||
231 | timer_base + TIMER_CTRL_OFF); | ||
232 | timer_clk = 25000000; | ||
233 | } else { | ||
234 | unsigned long rate = 0; | ||
235 | struct clk *clk = of_clk_get(np, 0); | ||
236 | WARN_ON(IS_ERR(clk)); | ||
237 | rate = clk_get_rate(clk); | ||
238 | u = readl(local_base + TIMER_CTRL_OFF); | ||
239 | writel(u & ~(TIMER0_25MHZ), | ||
240 | local_base + TIMER_CTRL_OFF); | ||
241 | |||
242 | u = readl(timer_base + TIMER_CTRL_OFF); | ||
243 | writel(u & ~(TIMER0_25MHZ), | ||
244 | timer_base + TIMER_CTRL_OFF); | ||
245 | |||
246 | timer_clk = rate / TIMER_DIVIDER; | ||
247 | timer25Mhz = false; | ||
248 | } | ||
249 | 249 | ||
250 | /* | 250 | /* |
251 | * We use timer 0 as clocksource, and private(local) timer 0 | 251 | * We use timer 0 as clocksource, and private(local) timer 0 |
252 | * for clockevents | 252 | * for clockevents |
253 | */ | 253 | */ |
254 | armada_370_xp_clkevt.irq = irq_of_parse_and_map(np, 4); | 254 | armada_370_xp_clkevt_irq = irq_of_parse_and_map(np, 4); |
255 | 255 | ||
256 | ticks_per_jiffy = (timer_clk + HZ / 2) / HZ; | 256 | ticks_per_jiffy = (timer_clk + HZ / 2) / HZ; |
257 | 257 | ||
@@ -267,35 +267,52 @@ void __init armada_370_xp_timer_init(void) | |||
267 | writel(0xffffffff, timer_base + TIMER0_VAL_OFF); | 267 | writel(0xffffffff, timer_base + TIMER0_VAL_OFF); |
268 | writel(0xffffffff, timer_base + TIMER0_RELOAD_OFF); | 268 | writel(0xffffffff, timer_base + TIMER0_RELOAD_OFF); |
269 | 269 | ||
270 | u = readl(timer_base + TIMER_CTRL_OFF); | 270 | timer_ctrl_clrset(0, TIMER0_EN | TIMER0_RELOAD_EN | |
271 | 271 | TIMER0_DIV(TIMER_DIVIDER_SHIFT)); | |
272 | writel((u | TIMER0_EN | TIMER0_RELOAD_EN | | ||
273 | TIMER0_DIV(TIMER_DIVIDER_SHIFT)), timer_base + TIMER_CTRL_OFF); | ||
274 | 272 | ||
275 | clocksource_mmio_init(timer_base + TIMER0_VAL_OFF, | 273 | clocksource_mmio_init(timer_base + TIMER0_VAL_OFF, |
276 | "armada_370_xp_clocksource", | 274 | "armada_370_xp_clocksource", |
277 | timer_clk, 300, 32, clocksource_mmio_readl_down); | 275 | timer_clk, 300, 32, clocksource_mmio_readl_down); |
278 | 276 | ||
279 | /* Register the clockevent on the private timer of CPU 0 */ | 277 | register_cpu_notifier(&armada_370_xp_timer_cpu_nb); |
280 | armada_370_xp_clkevt.cpumask = cpumask_of(0); | ||
281 | clockevents_config_and_register(&armada_370_xp_clkevt, | ||
282 | timer_clk, 1, 0xfffffffe); | ||
283 | 278 | ||
284 | percpu_armada_370_xp_evt = alloc_percpu(struct clock_event_device *); | 279 | armada_370_xp_evt = alloc_percpu(struct clock_event_device); |
285 | 280 | ||
286 | 281 | ||
287 | /* | 282 | /* |
288 | * Setup clockevent timer (interrupt-driven). | 283 | * Setup clockevent timer (interrupt-driven). |
289 | */ | 284 | */ |
290 | *__this_cpu_ptr(percpu_armada_370_xp_evt) = &armada_370_xp_clkevt; | 285 | res = request_percpu_irq(armada_370_xp_clkevt_irq, |
291 | res = request_percpu_irq(armada_370_xp_clkevt.irq, | ||
292 | armada_370_xp_timer_interrupt, | 286 | armada_370_xp_timer_interrupt, |
293 | armada_370_xp_clkevt.name, | 287 | "armada_370_xp_per_cpu_tick", |
294 | percpu_armada_370_xp_evt); | 288 | armada_370_xp_evt); |
295 | if (!res) { | 289 | /* Immediately configure the timer on the boot CPU */ |
296 | enable_percpu_irq(armada_370_xp_clkevt.irq, 0); | 290 | if (!res) |
297 | #ifdef CONFIG_LOCAL_TIMERS | 291 | armada_370_xp_timer_setup(this_cpu_ptr(armada_370_xp_evt)); |
298 | local_timer_register(&armada_370_xp_local_timer_ops); | 292 | } |
299 | #endif | 293 | |
300 | } | 294 | static void __init armada_xp_timer_init(struct device_node *np) |
295 | { | ||
296 | struct clk *clk = of_clk_get_by_name(np, "fixed"); | ||
297 | |||
298 | /* The 25Mhz fixed clock is mandatory, and must always be available */ | ||
299 | BUG_ON(IS_ERR(clk)); | ||
300 | timer_clk = clk_get_rate(clk); | ||
301 | |||
302 | armada_370_xp_timer_common_init(np); | ||
303 | } | ||
304 | CLOCKSOURCE_OF_DECLARE(armada_xp, "marvell,armada-xp-timer", | ||
305 | armada_xp_timer_init); | ||
306 | |||
307 | static void __init armada_370_timer_init(struct device_node *np) | ||
308 | { | ||
309 | struct clk *clk = of_clk_get(np, 0); | ||
310 | |||
311 | BUG_ON(IS_ERR(clk)); | ||
312 | timer_clk = clk_get_rate(clk) / TIMER_DIVIDER; | ||
313 | timer25Mhz = false; | ||
314 | |||
315 | armada_370_xp_timer_common_init(np); | ||
301 | } | 316 | } |
317 | CLOCKSOURCE_OF_DECLARE(armada_370, "marvell,armada-370-timer", | ||
318 | armada_370_timer_init); | ||
diff --git a/drivers/clocksource/time-orion.c b/drivers/clocksource/time-orion.c index ecbeb6810215..9c7f018a67ca 100644 --- a/drivers/clocksource/time-orion.c +++ b/drivers/clocksource/time-orion.c | |||
@@ -19,7 +19,7 @@ | |||
19 | #include <linux/of_address.h> | 19 | #include <linux/of_address.h> |
20 | #include <linux/of_irq.h> | 20 | #include <linux/of_irq.h> |
21 | #include <linux/spinlock.h> | 21 | #include <linux/spinlock.h> |
22 | #include <asm/sched_clock.h> | 22 | #include <linux/sched_clock.h> |
23 | 23 | ||
24 | #define TIMER_CTRL 0x00 | 24 | #define TIMER_CTRL 0x00 |
25 | #define TIMER0_EN BIT(0) | 25 | #define TIMER0_EN BIT(0) |
diff --git a/drivers/clocksource/timer-marco.c b/drivers/clocksource/timer-marco.c index e5dc9129ca26..09a17d9a6594 100644 --- a/drivers/clocksource/timer-marco.c +++ b/drivers/clocksource/timer-marco.c | |||
@@ -10,6 +10,7 @@ | |||
10 | #include <linux/interrupt.h> | 10 | #include <linux/interrupt.h> |
11 | #include <linux/clockchips.h> | 11 | #include <linux/clockchips.h> |
12 | #include <linux/clocksource.h> | 12 | #include <linux/clocksource.h> |
13 | #include <linux/cpu.h> | ||
13 | #include <linux/bitops.h> | 14 | #include <linux/bitops.h> |
14 | #include <linux/irq.h> | 15 | #include <linux/irq.h> |
15 | #include <linux/clk.h> | 16 | #include <linux/clk.h> |
@@ -18,7 +19,6 @@ | |||
18 | #include <linux/of_irq.h> | 19 | #include <linux/of_irq.h> |
19 | #include <linux/of_address.h> | 20 | #include <linux/of_address.h> |
20 | #include <linux/sched_clock.h> | 21 | #include <linux/sched_clock.h> |
21 | #include <asm/localtimer.h> | ||
22 | #include <asm/mach/time.h> | 22 | #include <asm/mach/time.h> |
23 | 23 | ||
24 | #define SIRFSOC_TIMER_32COUNTER_0_CTRL 0x0000 | 24 | #define SIRFSOC_TIMER_32COUNTER_0_CTRL 0x0000 |
@@ -151,13 +151,7 @@ static void sirfsoc_clocksource_resume(struct clocksource *cs) | |||
151 | BIT(1) | BIT(0), sirfsoc_timer_base + SIRFSOC_TIMER_64COUNTER_CTRL); | 151 | BIT(1) | BIT(0), sirfsoc_timer_base + SIRFSOC_TIMER_64COUNTER_CTRL); |
152 | } | 152 | } |
153 | 153 | ||
154 | static struct clock_event_device sirfsoc_clockevent = { | 154 | static struct clock_event_device __percpu *sirfsoc_clockevent; |
155 | .name = "sirfsoc_clockevent", | ||
156 | .rating = 200, | ||
157 | .features = CLOCK_EVT_FEAT_ONESHOT, | ||
158 | .set_mode = sirfsoc_timer_set_mode, | ||
159 | .set_next_event = sirfsoc_timer_set_next_event, | ||
160 | }; | ||
161 | 155 | ||
162 | static struct clocksource sirfsoc_clocksource = { | 156 | static struct clocksource sirfsoc_clocksource = { |
163 | .name = "sirfsoc_clocksource", | 157 | .name = "sirfsoc_clocksource", |
@@ -173,37 +167,38 @@ static struct irqaction sirfsoc_timer_irq = { | |||
173 | .name = "sirfsoc_timer0", | 167 | .name = "sirfsoc_timer0", |
174 | .flags = IRQF_TIMER | IRQF_NOBALANCING, | 168 | .flags = IRQF_TIMER | IRQF_NOBALANCING, |
175 | .handler = sirfsoc_timer_interrupt, | 169 | .handler = sirfsoc_timer_interrupt, |
176 | .dev_id = &sirfsoc_clockevent, | ||
177 | }; | 170 | }; |
178 | 171 | ||
179 | #ifdef CONFIG_LOCAL_TIMERS | ||
180 | |||
181 | static struct irqaction sirfsoc_timer1_irq = { | 172 | static struct irqaction sirfsoc_timer1_irq = { |
182 | .name = "sirfsoc_timer1", | 173 | .name = "sirfsoc_timer1", |
183 | .flags = IRQF_TIMER | IRQF_NOBALANCING, | 174 | .flags = IRQF_TIMER | IRQF_NOBALANCING, |
184 | .handler = sirfsoc_timer_interrupt, | 175 | .handler = sirfsoc_timer_interrupt, |
185 | }; | 176 | }; |
186 | 177 | ||
187 | static int __cpuinit sirfsoc_local_timer_setup(struct clock_event_device *ce) | 178 | static int sirfsoc_local_timer_setup(struct clock_event_device *ce) |
188 | { | 179 | { |
189 | /* Use existing clock_event for cpu 0 */ | 180 | int cpu = smp_processor_id(); |
190 | if (!smp_processor_id()) | 181 | struct irqaction *action; |
191 | return 0; | 182 | |
183 | if (cpu == 0) | ||
184 | action = &sirfsoc_timer_irq; | ||
185 | else | ||
186 | action = &sirfsoc_timer1_irq; | ||
192 | 187 | ||
193 | ce->irq = sirfsoc_timer1_irq.irq; | 188 | ce->irq = action->irq; |
194 | ce->name = "local_timer"; | 189 | ce->name = "local_timer"; |
195 | ce->features = sirfsoc_clockevent.features; | 190 | ce->features = CLOCK_EVT_FEAT_ONESHOT; |
196 | ce->rating = sirfsoc_clockevent.rating; | 191 | ce->rating = 200; |
197 | ce->set_mode = sirfsoc_timer_set_mode; | 192 | ce->set_mode = sirfsoc_timer_set_mode; |
198 | ce->set_next_event = sirfsoc_timer_set_next_event; | 193 | ce->set_next_event = sirfsoc_timer_set_next_event; |
199 | ce->shift = sirfsoc_clockevent.shift; | 194 | clockevents_calc_mult_shift(ce, CLOCK_TICK_RATE, 60); |
200 | ce->mult = sirfsoc_clockevent.mult; | 195 | ce->max_delta_ns = clockevent_delta2ns(-2, ce); |
201 | ce->max_delta_ns = sirfsoc_clockevent.max_delta_ns; | 196 | ce->min_delta_ns = clockevent_delta2ns(2, ce); |
202 | ce->min_delta_ns = sirfsoc_clockevent.min_delta_ns; | 197 | ce->cpumask = cpumask_of(cpu); |
203 | 198 | ||
204 | sirfsoc_timer1_irq.dev_id = ce; | 199 | action->dev_id = ce; |
205 | BUG_ON(setup_irq(ce->irq, &sirfsoc_timer1_irq)); | 200 | BUG_ON(setup_irq(ce->irq, action)); |
206 | irq_set_affinity(sirfsoc_timer1_irq.irq, cpumask_of(1)); | 201 | irq_set_affinity(action->irq, cpumask_of(cpu)); |
207 | 202 | ||
208 | clockevents_register_device(ce); | 203 | clockevents_register_device(ce); |
209 | return 0; | 204 | return 0; |
@@ -211,31 +206,48 @@ static int __cpuinit sirfsoc_local_timer_setup(struct clock_event_device *ce) | |||
211 | 206 | ||
212 | static void sirfsoc_local_timer_stop(struct clock_event_device *ce) | 207 | static void sirfsoc_local_timer_stop(struct clock_event_device *ce) |
213 | { | 208 | { |
209 | int cpu = smp_processor_id(); | ||
210 | |||
214 | sirfsoc_timer_count_disable(1); | 211 | sirfsoc_timer_count_disable(1); |
215 | 212 | ||
216 | remove_irq(sirfsoc_timer1_irq.irq, &sirfsoc_timer1_irq); | 213 | if (cpu == 0) |
214 | remove_irq(sirfsoc_timer_irq.irq, &sirfsoc_timer_irq); | ||
215 | else | ||
216 | remove_irq(sirfsoc_timer1_irq.irq, &sirfsoc_timer1_irq); | ||
217 | } | 217 | } |
218 | 218 | ||
219 | static struct local_timer_ops sirfsoc_local_timer_ops __cpuinitdata = { | 219 | static int sirfsoc_cpu_notify(struct notifier_block *self, |
220 | .setup = sirfsoc_local_timer_setup, | 220 | unsigned long action, void *hcpu) |
221 | .stop = sirfsoc_local_timer_stop, | 221 | { |
222 | /* | ||
223 | * Grab cpu pointer in each case to avoid spurious | ||
224 | * preemptible warnings | ||
225 | */ | ||
226 | switch (action & ~CPU_TASKS_FROZEN) { | ||
227 | case CPU_STARTING: | ||
228 | sirfsoc_local_timer_setup(this_cpu_ptr(sirfsoc_clockevent)); | ||
229 | break; | ||
230 | case CPU_DYING: | ||
231 | sirfsoc_local_timer_stop(this_cpu_ptr(sirfsoc_clockevent)); | ||
232 | break; | ||
233 | } | ||
234 | |||
235 | return NOTIFY_OK; | ||
236 | } | ||
237 | |||
238 | static struct notifier_block sirfsoc_cpu_nb = { | ||
239 | .notifier_call = sirfsoc_cpu_notify, | ||
222 | }; | 240 | }; |
223 | #endif /* CONFIG_LOCAL_TIMERS */ | ||
224 | 241 | ||
225 | static void __init sirfsoc_clockevent_init(void) | 242 | static void __init sirfsoc_clockevent_init(void) |
226 | { | 243 | { |
227 | clockevents_calc_mult_shift(&sirfsoc_clockevent, CLOCK_TICK_RATE, 60); | 244 | sirfsoc_clockevent = alloc_percpu(struct clock_event_device); |
228 | 245 | BUG_ON(!sirfsoc_clockevent); | |
229 | sirfsoc_clockevent.max_delta_ns = | 246 | |
230 | clockevent_delta2ns(-2, &sirfsoc_clockevent); | 247 | BUG_ON(register_cpu_notifier(&sirfsoc_cpu_nb)); |
231 | sirfsoc_clockevent.min_delta_ns = | 248 | |
232 | clockevent_delta2ns(2, &sirfsoc_clockevent); | 249 | /* Immediately configure the timer on the boot CPU */ |
233 | 250 | sirfsoc_local_timer_setup(this_cpu_ptr(sirfsoc_clockevent)); | |
234 | sirfsoc_clockevent.cpumask = cpumask_of(0); | ||
235 | clockevents_register_device(&sirfsoc_clockevent); | ||
236 | #ifdef CONFIG_LOCAL_TIMERS | ||
237 | local_timer_register(&sirfsoc_local_timer_ops); | ||
238 | #endif | ||
239 | } | 251 | } |
240 | 252 | ||
241 | /* initialize the kernel jiffy timer source */ | 253 | /* initialize the kernel jiffy timer source */ |
@@ -273,8 +285,6 @@ static void __init sirfsoc_marco_timer_init(void) | |||
273 | 285 | ||
274 | BUG_ON(clocksource_register_hz(&sirfsoc_clocksource, CLOCK_TICK_RATE)); | 286 | BUG_ON(clocksource_register_hz(&sirfsoc_clocksource, CLOCK_TICK_RATE)); |
275 | 287 | ||
276 | BUG_ON(setup_irq(sirfsoc_timer_irq.irq, &sirfsoc_timer_irq)); | ||
277 | |||
278 | sirfsoc_clockevent_init(); | 288 | sirfsoc_clockevent_init(); |
279 | } | 289 | } |
280 | 290 | ||
@@ -288,11 +298,9 @@ static void __init sirfsoc_of_timer_init(struct device_node *np) | |||
288 | if (!sirfsoc_timer_irq.irq) | 298 | if (!sirfsoc_timer_irq.irq) |
289 | panic("No irq passed for timer0 via DT\n"); | 299 | panic("No irq passed for timer0 via DT\n"); |
290 | 300 | ||
291 | #ifdef CONFIG_LOCAL_TIMERS | ||
292 | sirfsoc_timer1_irq.irq = irq_of_parse_and_map(np, 1); | 301 | sirfsoc_timer1_irq.irq = irq_of_parse_and_map(np, 1); |
293 | if (!sirfsoc_timer1_irq.irq) | 302 | if (!sirfsoc_timer1_irq.irq) |
294 | panic("No irq passed for timer1 via DT\n"); | 303 | panic("No irq passed for timer1 via DT\n"); |
295 | #endif | ||
296 | 304 | ||
297 | sirfsoc_marco_timer_init(); | 305 | sirfsoc_marco_timer_init(); |
298 | } | 306 | } |