Merge branch 'fortglx/3.13/time' of git://git.linaro.org/people/jstultz/linux into...
authorIngo Molnar <mingo@kernel.org>
Thu, 10 Oct 2013 04:25:23 +0000 (06:25 +0200)
committerIngo Molnar <mingo@kernel.org>
Thu, 10 Oct 2013 04:25:23 +0000 (06:25 +0200)
Pull more timekeeping items for v3.13 from John Stultz:

  * Small cleanup in the clocksource code.

  * Fix for rtc-pl031 to let it work with alarmtimers.

  * Move arm64 to using the generic sched_clock framework & resulting
    cleanup in the generic sched_clock code.

Signed-off-by: Ingo Molnar <mingo@kernel.org>
1  2 
drivers/clocksource/arm_arch_timer.c

index b94b0d44c158e7f172b886ef0460945c4b438f80,5d527895c74d3eb26e8c845c94c24c2ff2193c8a..f655036b524f430b00b643f693eb35a49b02086f
  #include <linux/device.h>
  #include <linux/smp.h>
  #include <linux/cpu.h>
 +#include <linux/cpu_pm.h>
  #include <linux/clockchips.h>
  #include <linux/interrupt.h>
  #include <linux/of_irq.h>
  #include <linux/of_address.h>
  #include <linux/io.h>
  #include <linux/slab.h>
+ #include <linux/sched_clock.h>
  
  #include <asm/arch_timer.h>
  #include <asm/virt.h>
@@@ -295,19 -295,6 +296,19 @@@ static void __arch_timer_setup(unsigne
        clockevents_config_and_register(clk, arch_timer_rate, 0xf, 0x7fffffff);
  }
  
 +static void arch_timer_configure_evtstream(void)
 +{
 +      int evt_stream_div, pos;
 +
 +      /* Find the closest power of two to the divisor */
 +      evt_stream_div = arch_timer_rate / ARCH_TIMER_EVT_STREAM_FREQ;
 +      pos = fls(evt_stream_div);
 +      if (pos > 1 && !(evt_stream_div & (1 << (pos - 2))))
 +              pos--;
 +      /* enable event stream */
 +      arch_timer_evtstrm_enable(min(pos, 15));
 +}
 +
  static int arch_timer_setup(struct clock_event_device *clk)
  {
        __arch_timer_setup(ARCH_CP15_TIMER, clk);
        }
  
        arch_counter_set_user_access();
 +      if (IS_ENABLED(CONFIG_ARM_ARCH_TIMER_EVTSTREAM))
 +              arch_timer_configure_evtstream();
  
        return 0;
  }
@@@ -405,7 -390,7 +406,7 @@@ static struct clocksource clocksource_c
        .rating = 400,
        .read   = arch_counter_read,
        .mask   = CLOCKSOURCE_MASK(56),
 -      .flags  = CLOCK_SOURCE_IS_CONTINUOUS,
 +      .flags  = CLOCK_SOURCE_IS_CONTINUOUS | CLOCK_SOURCE_SUSPEND_NONSTOP,
  };
  
  static struct cyclecounter cyclecounter = {
@@@ -476,33 -461,6 +477,33 @@@ static struct notifier_block arch_timer
        .notifier_call = arch_timer_cpu_notify,
  };
  
 +#ifdef CONFIG_CPU_PM
 +static unsigned int saved_cntkctl;
 +static int arch_timer_cpu_pm_notify(struct notifier_block *self,
 +                                  unsigned long action, void *hcpu)
 +{
 +      if (action == CPU_PM_ENTER)
 +              saved_cntkctl = arch_timer_get_cntkctl();
 +      else if (action == CPU_PM_ENTER_FAILED || action == CPU_PM_EXIT)
 +              arch_timer_set_cntkctl(saved_cntkctl);
 +      return NOTIFY_OK;
 +}
 +
 +static struct notifier_block arch_timer_cpu_pm_notifier = {
 +      .notifier_call = arch_timer_cpu_pm_notify,
 +};
 +
 +static int __init arch_timer_cpu_pm_init(void)
 +{
 +      return cpu_pm_register_notifier(&arch_timer_cpu_pm_notifier);
 +}
 +#else
 +static int __init arch_timer_cpu_pm_init(void)
 +{
 +      return 0;
 +}
 +#endif
 +
  static int __init arch_timer_register(void)
  {
        int err;
                goto out;
        }
  
+       clocksource_register_hz(&clocksource_counter, arch_timer_rate);
+       cyclecounter.mult = clocksource_counter.mult;
+       cyclecounter.shift = clocksource_counter.shift;
+       timecounter_init(&timecounter, &cyclecounter,
+                        arch_counter_get_cntvct());
+       /* 56 bits minimum, so we assume worst case rollover */
+       sched_clock_register(arch_timer_read_counter, 56, arch_timer_rate);
        if (arch_timer_use_virtual) {
                ppi = arch_timer_ppi[VIRT_PPI];
                err = request_percpu_irq(ppi, arch_timer_handler_virt,
        if (err)
                goto out_free_irq;
  
 +      err = arch_timer_cpu_pm_init();
 +      if (err)
 +              goto out_unreg_notify;
 +
        /* Immediately configure the timer on the boot CPU */
        arch_timer_setup(this_cpu_ptr(arch_timer_evt));
  
        return 0;
  
 +out_unreg_notify:
 +      unregister_cpu_notifier(&arch_timer_cpu_nb);
  out_free_irq:
        if (arch_timer_use_virtual)
                free_percpu_irq(arch_timer_ppi[VIRT_PPI], arch_timer_evt);