Re: [PATCH 02/11] time: convert arch_gettimeoffset to a pointer

From: Jesper Nilsson
Date: Mon Nov 12 2012 - 05:46:18 EST


On Thu, Nov 08, 2012 at 10:01:47PM +0100, Stephen Warren wrote:
> From: Stephen Warren <swarren@xxxxxxxxxx>
>
> 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 the final implementation in later
> patches, because they already have function pointers in place for this
> purpose.
>
> Cc: Russell King <linux@xxxxxxxxxxxxxxxx>
> Cc: Mike Frysinger <vapier@xxxxxxxxxx>
> Cc: Mikael Starvik <starvik@xxxxxxxx>

For the cris parts:

Acked-by: Jesper Nilsson <jesper.nilsson@xxxxxxxx>

> Cc: Hirokazu Takata <takata@xxxxxxxxxxxxxx>
> Cc: Geert Uytterhoeven <geert@xxxxxxxxxxxxxx>
> Cc: John Stultz <johnstul@xxxxxxxxxx>
> Cc: Thomas Gleixner <tglx@xxxxxxxxxxxxx>
> Signed-off-by: Stephen Warren <swarren@xxxxxxxxxx>
> ---
> arch/arm/kernel/time.c | 6 +++++-
> arch/blackfin/kernel/time.c | 6 +++++-
> arch/cris/arch-v10/kernel/time.c | 6 ++++--
> arch/cris/kernel/time.c | 11 -----------
> arch/m32r/kernel/time.c | 4 +++-
> arch/m68k/kernel/time.c | 16 ++++++++++------
> include/linux/time.h | 4 +---
> kernel/time/timekeeping.c | 20 +++++++++++++++++---
> 8 files changed, 45 insertions(+), 28 deletions(-)
>
> diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c
> index 09be0c3..b0190b4 100644
> --- a/arch/arm/kernel/time.c
> +++ b/arch/arm/kernel/time.c
> @@ -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;
> @@ -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();
> diff --git a/arch/blackfin/kernel/time.c b/arch/blackfin/kernel/time.c
> index 2310b24..3126b92 100644
> --- a/arch/blackfin/kernel/time.c
> +++ b/arch/blackfin/kernel/time.c
> @@ -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;
> @@ -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
> diff --git a/arch/cris/arch-v10/kernel/time.c b/arch/cris/arch-v10/kernel/time.c
> index 162892f..fce7c54 100644
> --- a/arch/cris/arch-v10/kernel/time.c
> +++ b/arch/cris/arch-v10/kernel/time.c
> @@ -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
> @@ -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
> diff --git a/arch/cris/kernel/time.c b/arch/cris/kernel/time.c
> index b063c92..fe6acda 100644
> --- a/arch/cris/kernel/time.c
> +++ b/arch/cris/kernel/time.c
> @@ -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));
> diff --git a/arch/m32r/kernel/time.c b/arch/m32r/kernel/time.c
> index 84dd040..1a15f81 100644
> --- a/arch/m32r/kernel/time.c
> +++ b/arch/m32r/kernel/time.c
> @@ -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] */
>
> @@ -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)
> diff --git a/arch/m68k/kernel/time.c b/arch/m68k/kernel/time.c
> index 5d0bcaa..c2994c8 100644
> --- a/arch/m68k/kernel/time.c
> +++ b/arch/m68k/kernel/time.c
> @@ -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;
> }
> @@ -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);
> +}
> diff --git a/include/linux/time.h b/include/linux/time.h
> index 4d358e9..05e32a7 100644
> --- a/include/linux/time.h
> +++ b/include/linux/time.h
> @@ -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);
> diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
> index e424970..9d00ace 100644
> --- a/kernel/time/timekeeping.c
> +++ b/kernel/time/timekeeping.c
> @@ -140,6 +140,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 gettimeoffset(void)
> +{
> + if (likely(arch_gettimeoffset))
> + return arch_gettimeoffset();
> + return 0;
> +}
> +#else
> +static inline u32 gettimeoffset(void) { return 0; }
> +#endif
> +
> static inline s64 timekeeping_get_ns(struct timekeeper *tk)
> {
> cycle_t cycle_now, cycle_delta;
> @@ -157,7 +171,7 @@ static inline s64 timekeeping_get_ns(struct timekeeper *tk)
> nsec >>= tk->shift;
>
> /* If arch requires, add in gettimeoffset() */
> - return nsec + arch_gettimeoffset();
> + return nsec + gettimeoffset();
> }
>
> static inline s64 timekeeping_get_ns_raw(struct timekeeper *tk)
> @@ -177,7 +191,7 @@ static inline s64 timekeeping_get_ns_raw(struct timekeeper *tk)
> nsec = clocksource_cyc2ns(cycle_delta, clock->mult, clock->shift);
>
> /* If arch requires, add in gettimeoffset() */
> - return nsec + arch_gettimeoffset();
> + return nsec + gettimeoffset();
> }
>
> /* must hold write on timekeeper.lock */
> @@ -211,7 +225,7 @@ 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;
> + tk->xtime_nsec += (u64)gettimeoffset() << tk->shift;
>
> tk_normalize_xtime(tk);
>
> --
> 1.7.0.4

/^JN - Jesper Nilsson
--
Jesper Nilsson -- jesper.nilsson@xxxxxxxx
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/