aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/plat-nomadik/timer.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/plat-nomadik/timer.c')
-rw-r--r--arch/arm/plat-nomadik/timer.c60
1 files changed, 24 insertions, 36 deletions
diff --git a/arch/arm/plat-nomadik/timer.c b/arch/arm/plat-nomadik/timer.c
index aedf9c1d645e..ef74e157a9d5 100644
--- a/arch/arm/plat-nomadik/timer.c
+++ b/arch/arm/plat-nomadik/timer.c
@@ -3,6 +3,7 @@
3 * 3 *
4 * Copyright (C) 2008 STMicroelectronics 4 * Copyright (C) 2008 STMicroelectronics
5 * Copyright (C) 2010 Alessandro Rubini 5 * Copyright (C) 2010 Alessandro Rubini
6 * Copyright (C) 2010 Linus Walleij for ST-Ericsson
6 * 7 *
7 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2, as 9 * it under the terms of the GNU General Public License version 2, as
@@ -16,48 +17,36 @@
16#include <linux/clk.h> 17#include <linux/clk.h>
17#include <linux/jiffies.h> 18#include <linux/jiffies.h>
18#include <linux/err.h> 19#include <linux/err.h>
20#include <linux/sched.h>
19#include <asm/mach/time.h> 21#include <asm/mach/time.h>
22#include <asm/sched_clock.h>
20 23
21#include <plat/mtu.h> 24#include <plat/mtu.h>
22 25
23void __iomem *mtu_base; /* ssigned by machine code */ 26void __iomem *mtu_base; /* Assigned by machine code */
24 27
25/* 28/*
26 * Kernel assumes that sched_clock can be called early 29 * Override the global weak sched_clock symbol with this
27 * but the MTU may not yet be initialized. 30 * local implementation which uses the clocksource to get some
31 * better resolution when scheduling the kernel.
28 */ 32 */
29static cycle_t nmdk_read_timer_dummy(struct clocksource *cs) 33static DEFINE_CLOCK_DATA(cd);
30{
31 return 0;
32}
33 34
34/* clocksource: MTU decrements, so we negate the value being read. */ 35unsigned long long notrace sched_clock(void)
35static cycle_t nmdk_read_timer(struct clocksource *cs)
36{ 36{
37 return -readl(mtu_base + MTU_VAL(0)); 37 u32 cyc;
38}
39 38
40static struct clocksource nmdk_clksrc = { 39 if (unlikely(!mtu_base))
41 .name = "mtu_0", 40 return 0;
42 .rating = 200,
43 .read = nmdk_read_timer_dummy,
44 .mask = CLOCKSOURCE_MASK(32),
45 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
46};
47 41
48/* 42 cyc = -readl(mtu_base + MTU_VAL(0));
49 * Override the global weak sched_clock symbol with this 43 return cyc_to_sched_clock(&cd, cyc, (u32)~0);
50 * local implementation which uses the clocksource to get some 44}
51 * better resolution when scheduling the kernel. We accept that 45
52 * this wraps around for now, since it is just a relative time 46static void notrace nomadik_update_sched_clock(void)
53 * stamp. (Inspired by OMAP implementation.)
54 */
55unsigned long long notrace sched_clock(void)
56{ 47{
57 return clocksource_cyc2ns(nmdk_clksrc.read( 48 u32 cyc = -readl(mtu_base + MTU_VAL(0));
58 &nmdk_clksrc), 49 update_sched_clock(&cd, cyc, (u32)~0);
59 nmdk_clksrc.mult,
60 nmdk_clksrc.shift);
61} 50}
62 51
63/* Clockevent device: use one-shot mode */ 52/* Clockevent device: use one-shot mode */
@@ -153,7 +142,6 @@ void __init nmdk_timer_init(void)
153 } else { 142 } else {
154 cr |= MTU_CRn_PRESCALE_1; 143 cr |= MTU_CRn_PRESCALE_1;
155 } 144 }
156 clocksource_calc_mult_shift(&nmdk_clksrc, rate, MTU_MIN_RANGE);
157 145
158 /* Timer 0 is the free running clocksource */ 146 /* Timer 0 is the free running clocksource */
159 writel(cr, mtu_base + MTU_CR(0)); 147 writel(cr, mtu_base + MTU_CR(0));
@@ -161,12 +149,12 @@ void __init nmdk_timer_init(void)
161 writel(0, mtu_base + MTU_BGLR(0)); 149 writel(0, mtu_base + MTU_BGLR(0));
162 writel(cr | MTU_CRn_ENA, mtu_base + MTU_CR(0)); 150 writel(cr | MTU_CRn_ENA, mtu_base + MTU_CR(0));
163 151
164 /* Now the scheduling clock is ready */ 152 if (clocksource_mmio_init(mtu_base + MTU_VAL(0), "mtu_0",
165 nmdk_clksrc.read = nmdk_read_timer; 153 rate, 200, 32, clocksource_mmio_readl_down))
166
167 if (clocksource_register(&nmdk_clksrc))
168 pr_err("timer: failed to initialize clock source %s\n", 154 pr_err("timer: failed to initialize clock source %s\n",
169 nmdk_clksrc.name); 155 "mtu_0");
156
157 init_sched_clock(&cd, nomadik_update_sched_clock, 32, rate);
170 158
171 /* Timer 1 is used for events */ 159 /* Timer 1 is used for events */
172 160