On Thu, Nov 08, 2012 at 10:01:47PM +0100, Stephen Warren wrote:
> From: Stephen Warren <swar...@nvidia.com>
> 
> 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 <li...@arm.linux.org.uk>
> Cc: Mike Frysinger <vap...@gentoo.org>
> Cc: Mikael Starvik <star...@axis.com>

For the cris parts:

Acked-by: Jesper Nilsson <jesper.nils...@axis.com>

> Cc: Hirokazu Takata <tak...@linux-m32r.org>
> Cc: Geert Uytterhoeven <ge...@linux-m68k.org>
> Cc: John Stultz <johns...@us.ibm.com>
> Cc: Thomas Gleixner <t...@linutronix.de>
> Signed-off-by: Stephen Warren <swar...@nvidia.com>
> ---
>  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.nils...@axis.com
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to