aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarc Zyngier <Marc.Zyngier@arm.com>2012-05-05 14:28:44 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2012-05-06 06:09:21 -0400
commitbd0493eaaf5c7a1ea00786d46cc2f4af44e76f28 (patch)
treebd7fbb1d21c5c00b0c37eeb3ac1b09a9d4f123ac
parentf67860a76f162ebcc6a2cacf3b0538d8a67d55ae (diff)
ARM: 7413/1: move read_{boot,persistent}_clock to the architecture level
At the moment, read_persistent_clock is implemented at the platform level, which makes it impossible to compile these platforms in a single kernel. Implement these two functions at the architecture level, and provide a thin registration interface for both read_boot_clock and read_persistent_clock. The two affected platforms (OMAP and Tegra) are converted at the same time. Reported-by: Jeff Ohlstein <johlstei@codeaurora.org> Tested-by: Stephen Warren <swarren@wwwdotorg.org> Tested-by: Tony Lindgren <tony@atomide.com> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-rw-r--r--arch/arm/include/asm/mach/time.h5
-rw-r--r--arch/arm/kernel/time.c36
-rw-r--r--arch/arm/mach-tegra/timer.c5
-rw-r--r--arch/arm/plat-omap/counter_32k.c6
4 files changed, 48 insertions, 4 deletions
diff --git a/arch/arm/include/asm/mach/time.h b/arch/arm/include/asm/mach/time.h
index f73c908b7fa0..6ca945f534ab 100644
--- a/arch/arm/include/asm/mach/time.h
+++ b/arch/arm/include/asm/mach/time.h
@@ -42,4 +42,9 @@ struct sys_timer {
42 42
43extern void timer_tick(void); 43extern void timer_tick(void);
44 44
45struct timespec;
46typedef void (*clock_access_fn)(struct timespec *);
47extern int register_persistent_clock(clock_access_fn read_boot,
48 clock_access_fn read_persistent);
49
45#endif 50#endif
diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c
index fe31b22f18fd..af2afb019672 100644
--- a/arch/arm/kernel/time.c
+++ b/arch/arm/kernel/time.c
@@ -110,6 +110,42 @@ void timer_tick(void)
110} 110}
111#endif 111#endif
112 112
113static void dummy_clock_access(struct timespec *ts)
114{
115 ts->tv_sec = 0;
116 ts->tv_nsec = 0;
117}
118
119static clock_access_fn __read_persistent_clock = dummy_clock_access;
120static clock_access_fn __read_boot_clock = dummy_clock_access;;
121
122void read_persistent_clock(struct timespec *ts)
123{
124 __read_persistent_clock(ts);
125}
126
127void read_boot_clock(struct timespec *ts)
128{
129 __read_boot_clock(ts);
130}
131
132int __init register_persistent_clock(clock_access_fn read_boot,
133 clock_access_fn read_persistent)
134{
135 /* Only allow the clockaccess functions to be registered once */
136 if (__read_persistent_clock == dummy_clock_access &&
137 __read_boot_clock == dummy_clock_access) {
138 if (read_boot)
139 __read_boot_clock = read_boot;
140 if (read_persistent)
141 __read_persistent_clock = read_persistent;
142
143 return 0;
144 }
145
146 return -EINVAL;
147}
148
113#if defined(CONFIG_PM) && !defined(CONFIG_GENERIC_CLOCKEVENTS) 149#if defined(CONFIG_PM) && !defined(CONFIG_GENERIC_CLOCKEVENTS)
114static int timer_suspend(void) 150static int timer_suspend(void)
115{ 151{
diff --git a/arch/arm/mach-tegra/timer.c b/arch/arm/mach-tegra/timer.c
index 1eed8d4a80ef..315672c7bd48 100644
--- a/arch/arm/mach-tegra/timer.c
+++ b/arch/arm/mach-tegra/timer.c
@@ -124,7 +124,7 @@ static u64 tegra_rtc_read_ms(void)
124} 124}
125 125
126/* 126/*
127 * read_persistent_clock - Return time from a persistent clock. 127 * tegra_read_persistent_clock - Return time from a persistent clock.
128 * 128 *
129 * Reads the time from a source which isn't disabled during PM, the 129 * Reads the time from a source which isn't disabled during PM, the
130 * 32k sync timer. Convert the cycles elapsed since last read into 130 * 32k sync timer. Convert the cycles elapsed since last read into
@@ -133,7 +133,7 @@ static u64 tegra_rtc_read_ms(void)
133 * tegra_rtc driver could be executing to avoid race conditions 133 * tegra_rtc driver could be executing to avoid race conditions
134 * on the RTC shadow register 134 * on the RTC shadow register
135 */ 135 */
136void read_persistent_clock(struct timespec *ts) 136static void tegra_read_persistent_clock(struct timespec *ts)
137{ 137{
138 u64 delta; 138 u64 delta;
139 struct timespec *tsp = &persistent_ts; 139 struct timespec *tsp = &persistent_ts;
@@ -243,6 +243,7 @@ static void __init tegra_init_timer(void)
243 tegra_clockevent.irq = tegra_timer_irq.irq; 243 tegra_clockevent.irq = tegra_timer_irq.irq;
244 clockevents_register_device(&tegra_clockevent); 244 clockevents_register_device(&tegra_clockevent);
245 tegra_twd_init(); 245 tegra_twd_init();
246 register_persistent_clock(NULL, tegra_read_persistent_clock);
246} 247}
247 248
248struct sys_timer tegra_timer = { 249struct sys_timer tegra_timer = {
diff --git a/arch/arm/plat-omap/counter_32k.c b/arch/arm/plat-omap/counter_32k.c
index 5068fe5a6910..44ae077dbc28 100644
--- a/arch/arm/plat-omap/counter_32k.c
+++ b/arch/arm/plat-omap/counter_32k.c
@@ -19,6 +19,7 @@
19#include <linux/io.h> 19#include <linux/io.h>
20#include <linux/clocksource.h> 20#include <linux/clocksource.h>
21 21
22#include <asm/mach/time.h>
22#include <asm/sched_clock.h> 23#include <asm/sched_clock.h>
23 24
24#include <plat/hardware.h> 25#include <plat/hardware.h>
@@ -43,7 +44,7 @@ static u32 notrace omap_32k_read_sched_clock(void)
43} 44}
44 45
45/** 46/**
46 * read_persistent_clock - Return time from a persistent clock. 47 * omap_read_persistent_clock - Return time from a persistent clock.
47 * 48 *
48 * Reads the time from a source which isn't disabled during PM, the 49 * Reads the time from a source which isn't disabled during PM, the
49 * 32k sync timer. Convert the cycles elapsed since last read into 50 * 32k sync timer. Convert the cycles elapsed since last read into
@@ -52,7 +53,7 @@ static u32 notrace omap_32k_read_sched_clock(void)
52static struct timespec persistent_ts; 53static struct timespec persistent_ts;
53static cycles_t cycles, last_cycles; 54static cycles_t cycles, last_cycles;
54static unsigned int persistent_mult, persistent_shift; 55static unsigned int persistent_mult, persistent_shift;
55void read_persistent_clock(struct timespec *ts) 56static void omap_read_persistent_clock(struct timespec *ts)
56{ 57{
57 unsigned long long nsecs; 58 unsigned long long nsecs;
58 cycles_t delta; 59 cycles_t delta;
@@ -116,6 +117,7 @@ int __init omap_init_clocksource_32k(void)
116 printk(err, "32k_counter"); 117 printk(err, "32k_counter");
117 118
118 setup_sched_clock(omap_32k_read_sched_clock, 32, 32768); 119 setup_sched_clock(omap_32k_read_sched_clock, 32, 32768);
120 register_persistent_clock(NULL, omap_read_persistent_clock);
119 } 121 }
120 return 0; 122 return 0;
121} 123}