Skip to content

Commit

Permalink
time: convert arch_gettimeoffset to a pointer
Browse files Browse the repository at this point in the history
Currently, whenever CONFIG_ARCH_USES_GETTIMEOFFSET is enabled, each
arch core provides a single implementation of arch_gettimeoffset(). In
many cases, different sub-architectures, different machines, or
different timer providers exist, and so the arch ends up implementing
arch_gettimeoffset() as a call-through-pointer anyway. Examples are
ARM, Cris, M68K, and it's arguable that the remaining architectures,
M32R and Blackfin, should be doing this anyway.

Modify arch_gettimeoffset so that it itself is a function pointer, which
the arch initializes. This will allow later changes to move the
initialization of this function into individual machine support or timer
drivers. This is particularly useful for code in drivers/clocksource
which should rely on an arch-independant mechanism to register their
implementation of arch_gettimeoffset().

This patch also converts the Cris architecture to set arch_gettimeoffset
directly to the final implementation in time_init(), because Cris already
had separate time_init() functions per sub-architecture. M68K and ARM
are converted to set arch_gettimeoffset to the final implementation in
later patches, because they already have function pointers in place for
this purpose.

Cc: Russell King <linux@arm.linux.org.uk>
Cc: Mike Frysinger <vapier@gentoo.org>
Cc: Mikael Starvik <starvik@axis.com>
Cc: Hirokazu Takata <takata@linux-m32r.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Geert Uytterhoeven <geert@linux-m68k.org>
Acked-by: Jesper Nilsson <jesper.nilsson@axis.com>
Acked-by: John Stultz <johnstul@us.ibm.com>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
  • Loading branch information
Stephen Warren committed Dec 24, 2012
1 parent 547046f commit 7b1f620
Show file tree
Hide file tree
Showing 8 changed files with 48 additions and 31 deletions.
6 changes: 5 additions & 1 deletion arch/arm/kernel/time.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ EXPORT_SYMBOL(profile_pc);
#endif

#ifdef CONFIG_ARCH_USES_GETTIMEOFFSET
u32 arch_gettimeoffset(void)
static u32 arm_gettimeoffset(void)
{
if (system_timer->offset != NULL)
return system_timer->offset() * 1000;
Expand Down Expand Up @@ -164,6 +164,10 @@ device_initcall(timer_init_syscore_ops);

void __init time_init(void)
{
#ifdef CONFIG_ARCH_USES_GETTIMEOFFSET
arch_gettimeoffset = arm_gettimeoffset;
#endif

system_timer = machine_desc->timer;
system_timer->init();
sched_clock_postinit();
Expand Down
6 changes: 5 additions & 1 deletion arch/blackfin/kernel/time.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ time_sched_init(irqreturn_t(*timer_routine) (int, void *))
/*
* Should return useconds since last timer tick
*/
u32 arch_gettimeoffset(void)
static u32 blackfin_gettimeoffset(void)
{
unsigned long offset;
unsigned long clocks_per_jiffy;
Expand Down Expand Up @@ -141,6 +141,10 @@ void read_persistent_clock(struct timespec *ts)

void __init time_init(void)
{
#ifdef CONFIG_ARCH_USES_GETTIMEOFFSET
arch_gettimeoffset = blackfin_gettimeoffset;
#endif

#ifdef CONFIG_RTC_DRV_BFIN
/* [#2663] hack to filter junk RTC values that would cause
* userspace to have to deal with time values greater than
Expand Down
6 changes: 4 additions & 2 deletions arch/cris/arch-v10/kernel/time.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,9 @@ unsigned long get_ns_in_jiffie(void)
return ns;
}

unsigned long do_slow_gettimeoffset(void)
static u32 cris_v10_gettimeoffset(void)
{
unsigned long count;
u32 count;

/* The timer interrupt comes from Etrax timer 0. In order to get
* better precision, we check the current value. It might have
Expand Down Expand Up @@ -191,6 +191,8 @@ static struct irqaction irq2 = {
void __init
time_init(void)
{
arch_gettimeoffset = cris_v10_gettimeoffset;

/* probe for the RTC and read it if it exists
* Before the RTC can be probed the loops_per_usec variable needs
* to be initialized to make usleep work. A better value for
Expand Down
11 changes: 0 additions & 11 deletions arch/cris/kernel/time.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,17 +39,6 @@
extern unsigned long loops_per_jiffy; /* init/main.c */
unsigned long loops_per_usec;


#ifdef CONFIG_ARCH_USES_GETTIMEOFFSET
extern unsigned long do_slow_gettimeoffset(void);
static unsigned long (*do_gettimeoffset)(void) = do_slow_gettimeoffset;

u32 arch_gettimeoffset(void)
{
return do_gettimeoffset();
}
#endif

int set_rtc_mmss(unsigned long nowtime)
{
D(printk(KERN_DEBUG "set_rtc_mmss(%lu)\n", nowtime));
Expand Down
4 changes: 3 additions & 1 deletion arch/m32r/kernel/time.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ extern void smp_local_timer_interrupt(void);

static unsigned long latch;

u32 arch_gettimeoffset(void)
static u32 m32r_gettimeoffset(void)
{
unsigned long elapsed_time = 0; /* [us] */

Expand Down Expand Up @@ -165,6 +165,8 @@ void read_persistent_clock(struct timespec *ts)

void __init time_init(void)
{
arch_gettimeoffset = m32r_gettimeoffset;

#if defined(CONFIG_CHIP_M32102) || defined(CONFIG_CHIP_XNUX2) \
|| defined(CONFIG_CHIP_VDEC2) || defined(CONFIG_CHIP_M32700) \
|| defined(CONFIG_CHIP_OPSP) || defined(CONFIG_CHIP_M32104)
Expand Down
16 changes: 10 additions & 6 deletions arch/m68k/kernel/time.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,14 +80,9 @@ void read_persistent_clock(struct timespec *ts)
}
}

void __init time_init(void)
{
mach_sched_init(timer_interrupt);
}

#ifdef CONFIG_ARCH_USES_GETTIMEOFFSET

u32 arch_gettimeoffset(void)
static u32 m68k_gettimeoffset(void)
{
return mach_gettimeoffset() * 1000;
}
Expand All @@ -106,3 +101,12 @@ static int __init rtc_init(void)
module_init(rtc_init);

#endif /* CONFIG_ARCH_USES_GETTIMEOFFSET */

void __init time_init(void)
{
#ifdef CONFIG_ARCH_USES_GETTIMEOFFSET
arch_gettimeoffset = m68k_gettimeoffset;
#endif

mach_sched_init(timer_interrupt);
}
4 changes: 1 addition & 3 deletions include/linux/time.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,9 +142,7 @@ void timekeeping_inject_sleeptime(struct timespec *delta);
* finer then tick granular time.
*/
#ifdef CONFIG_ARCH_USES_GETTIMEOFFSET
extern u32 arch_gettimeoffset(void);
#else
static inline u32 arch_gettimeoffset(void) { return 0; }
extern u32 (*arch_gettimeoffset)(void);
#endif

extern void do_gettimeofday(struct timeval *tv);
Expand Down
26 changes: 20 additions & 6 deletions kernel/time/timekeeping.c
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,20 @@ static void tk_setup_internals(struct timekeeper *tk, struct clocksource *clock)
}

/* Timekeeper helper functions. */

#ifdef CONFIG_ARCH_USES_GETTIMEOFFSET
u32 (*arch_gettimeoffset)(void);

u32 get_arch_timeoffset(void)
{
if (likely(arch_gettimeoffset))
return arch_gettimeoffset();
return 0;
}
#else
static inline u32 get_arch_timeoffset(void) { return 0; }
#endif

static inline s64 timekeeping_get_ns(struct timekeeper *tk)
{
cycle_t cycle_now, cycle_delta;
Expand All @@ -151,8 +165,8 @@ static inline s64 timekeeping_get_ns(struct timekeeper *tk)
nsec = cycle_delta * tk->mult + tk->xtime_nsec;
nsec >>= tk->shift;

/* If arch requires, add in gettimeoffset() */
return nsec + arch_gettimeoffset();
/* If arch requires, add in get_arch_timeoffset() */
return nsec + get_arch_timeoffset();
}

static inline s64 timekeeping_get_ns_raw(struct timekeeper *tk)
Expand All @@ -171,8 +185,8 @@ static inline s64 timekeeping_get_ns_raw(struct timekeeper *tk)
/* convert delta to nanoseconds. */
nsec = clocksource_cyc2ns(cycle_delta, clock->mult, clock->shift);

/* If arch requires, add in gettimeoffset() */
return nsec + arch_gettimeoffset();
/* If arch requires, add in get_arch_timeoffset() */
return nsec + get_arch_timeoffset();
}

static RAW_NOTIFIER_HEAD(pvclock_gtod_chain);
Expand Down Expand Up @@ -254,8 +268,8 @@ static void timekeeping_forward_now(struct timekeeper *tk)

tk->xtime_nsec += cycle_delta * tk->mult;

/* If arch requires, add in gettimeoffset() */
tk->xtime_nsec += (u64)arch_gettimeoffset() << tk->shift;
/* If arch requires, add in get_arch_timeoffset() */
tk->xtime_nsec += (u64)get_arch_timeoffset() << tk->shift;

tk_normalize_xtime(tk);

Expand Down

0 comments on commit 7b1f620

Please sign in to comment.