Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Marc Zyngier and committed by
Russell King
bd0493ea f67860a7

+48 -4
+5
arch/arm/include/asm/mach/time.h
··· 42 42 43 43 extern void timer_tick(void); 44 44 45 + struct timespec; 46 + typedef void (*clock_access_fn)(struct timespec *); 47 + extern int register_persistent_clock(clock_access_fn read_boot, 48 + clock_access_fn read_persistent); 49 + 45 50 #endif
+36
arch/arm/kernel/time.c
··· 110 110 } 111 111 #endif 112 112 113 + static void dummy_clock_access(struct timespec *ts) 114 + { 115 + ts->tv_sec = 0; 116 + ts->tv_nsec = 0; 117 + } 118 + 119 + static clock_access_fn __read_persistent_clock = dummy_clock_access; 120 + static clock_access_fn __read_boot_clock = dummy_clock_access;; 121 + 122 + void read_persistent_clock(struct timespec *ts) 123 + { 124 + __read_persistent_clock(ts); 125 + } 126 + 127 + void read_boot_clock(struct timespec *ts) 128 + { 129 + __read_boot_clock(ts); 130 + } 131 + 132 + int __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 149 #if defined(CONFIG_PM) && !defined(CONFIG_GENERIC_CLOCKEVENTS) 114 150 static int timer_suspend(void) 115 151 {
+3 -2
arch/arm/mach-tegra/timer.c
··· 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 129 * Reads the time from a source which isn't disabled during PM, the 130 130 * 32k sync timer. Convert the cycles elapsed since last read into ··· 133 133 * tegra_rtc driver could be executing to avoid race conditions 134 134 * on the RTC shadow register 135 135 */ 136 - void read_persistent_clock(struct timespec *ts) 136 + static void tegra_read_persistent_clock(struct timespec *ts) 137 137 { 138 138 u64 delta; 139 139 struct timespec *tsp = &persistent_ts; ··· 243 243 tegra_clockevent.irq = tegra_timer_irq.irq; 244 244 clockevents_register_device(&tegra_clockevent); 245 245 tegra_twd_init(); 246 + register_persistent_clock(NULL, tegra_read_persistent_clock); 246 247 } 247 248 248 249 struct sys_timer tegra_timer = {
+4 -2
arch/arm/plat-omap/counter_32k.c
··· 19 19 #include <linux/io.h> 20 20 #include <linux/clocksource.h> 21 21 22 + #include <asm/mach/time.h> 22 23 #include <asm/sched_clock.h> 23 24 24 25 #include <plat/hardware.h> ··· 44 43 } 45 44 46 45 /** 47 - * read_persistent_clock - Return time from a persistent clock. 46 + * omap_read_persistent_clock - Return time from a persistent clock. 48 47 * 49 48 * Reads the time from a source which isn't disabled during PM, the 50 49 * 32k sync timer. Convert the cycles elapsed since last read into ··· 53 52 static struct timespec persistent_ts; 54 53 static cycles_t cycles, last_cycles; 55 54 static unsigned int persistent_mult, persistent_shift; 56 - void read_persistent_clock(struct timespec *ts) 55 + static void omap_read_persistent_clock(struct timespec *ts) 57 56 { 58 57 unsigned long long nsecs; 59 58 cycles_t delta; ··· 117 116 printk(err, "32k_counter"); 118 117 119 118 setup_sched_clock(omap_32k_read_sched_clock, 32, 32768); 119 + register_persistent_clock(NULL, omap_read_persistent_clock); 120 120 } 121 121 return 0; 122 122 }