aboutsummaryrefslogtreecommitdiffstats
path: root/arch/microblaze/kernel/timer.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/microblaze/kernel/timer.c')
-rw-r--r--arch/microblaze/kernel/timer.c51
1 files changed, 28 insertions, 23 deletions
diff --git a/arch/microblaze/kernel/timer.c b/arch/microblaze/kernel/timer.c
index 3e39b1082fdf..fb0c61443f19 100644
--- a/arch/microblaze/kernel/timer.c
+++ b/arch/microblaze/kernel/timer.c
@@ -12,12 +12,12 @@
12#include <linux/interrupt.h> 12#include <linux/interrupt.h>
13#include <linux/delay.h> 13#include <linux/delay.h>
14#include <linux/sched.h> 14#include <linux/sched.h>
15#include <linux/sched_clock.h>
15#include <linux/clk.h> 16#include <linux/clk.h>
16#include <linux/clockchips.h> 17#include <linux/clockchips.h>
17#include <linux/of_address.h> 18#include <linux/of_address.h>
18#include <linux/of_irq.h> 19#include <linux/of_irq.h>
19#include <asm/cpuinfo.h> 20#include <asm/cpuinfo.h>
20#include <linux/cnt32_to_63.h>
21 21
22static void __iomem *timer_baseaddr; 22static void __iomem *timer_baseaddr;
23 23
@@ -167,10 +167,15 @@ static __init void xilinx_clockevent_init(void)
167 clockevents_register_device(&clockevent_xilinx_timer); 167 clockevents_register_device(&clockevent_xilinx_timer);
168} 168}
169 169
170static u64 xilinx_clock_read(void)
171{
172 return in_be32(timer_baseaddr + TCR1);
173}
174
170static cycle_t xilinx_read(struct clocksource *cs) 175static cycle_t xilinx_read(struct clocksource *cs)
171{ 176{
172 /* reading actual value of timer 1 */ 177 /* reading actual value of timer 1 */
173 return (cycle_t) (in_be32(timer_baseaddr + TCR1)); 178 return (cycle_t)xilinx_clock_read();
174} 179}
175 180
176static struct timecounter xilinx_tc = { 181static struct timecounter xilinx_tc = {
@@ -222,17 +227,17 @@ static int __init xilinx_clocksource_init(void)
222 return 0; 227 return 0;
223} 228}
224 229
225/*
226 * We have to protect accesses before timer initialization
227 * and return 0 for sched_clock function below.
228 */
229static int timer_initialized;
230
231static void __init xilinx_timer_init(struct device_node *timer) 230static void __init xilinx_timer_init(struct device_node *timer)
232{ 231{
232 struct clk *clk;
233 static int initialized;
233 u32 irq; 234 u32 irq;
234 u32 timer_num = 1; 235 u32 timer_num = 1;
235 int ret; 236
237 if (initialized)
238 return;
239
240 initialized = 1;
236 241
237 timer_baseaddr = of_iomap(timer, 0); 242 timer_baseaddr = of_iomap(timer, 0);
238 if (!timer_baseaddr) { 243 if (!timer_baseaddr) {
@@ -250,10 +255,20 @@ static void __init xilinx_timer_init(struct device_node *timer)
250 255
251 pr_info("%s: irq=%d\n", timer->full_name, irq); 256 pr_info("%s: irq=%d\n", timer->full_name, irq);
252 257
253 /* If there is clock-frequency property than use it */ 258 clk = of_clk_get(timer, 0);
254 ret = of_property_read_u32(timer, "clock-frequency", &timer_clock_freq); 259 if (IS_ERR(clk)) {
255 if (ret < 0) 260 pr_err("ERROR: timer CCF input clock not found\n");
261 /* If there is clock-frequency property than use it */
262 of_property_read_u32(timer, "clock-frequency",
263 &timer_clock_freq);
264 } else {
265 timer_clock_freq = clk_get_rate(clk);
266 }
267
268 if (!timer_clock_freq) {
269 pr_err("ERROR: Using CPU clock frequency\n");
256 timer_clock_freq = cpuinfo.cpu_clock_freq; 270 timer_clock_freq = cpuinfo.cpu_clock_freq;
271 }
257 272
258 freq_div_hz = timer_clock_freq / HZ; 273 freq_div_hz = timer_clock_freq / HZ;
259 274
@@ -263,18 +278,8 @@ static void __init xilinx_timer_init(struct device_node *timer)
263#endif 278#endif
264 xilinx_clocksource_init(); 279 xilinx_clocksource_init();
265 xilinx_clockevent_init(); 280 xilinx_clockevent_init();
266 timer_initialized = 1;
267}
268 281
269unsigned long long notrace sched_clock(void) 282 sched_clock_register(xilinx_clock_read, 32, timer_clock_freq);
270{
271 if (timer_initialized) {
272 struct clocksource *cs = &clocksource_microblaze;
273
274 cycle_t cyc = cnt32_to_63(cs->read(NULL)) & LLONG_MAX;
275 return clocksource_cyc2ns(cyc, cs->mult, cs->shift);
276 }
277 return 0;
278} 283}
279 284
280CLOCKSOURCE_OF_DECLARE(xilinx_timer, "xlnx,xps-timer-1.00.a", 285CLOCKSOURCE_OF_DECLARE(xilinx_timer, "xlnx,xps-timer-1.00.a",