]> git.proxmox.com Git - mirror_ubuntu-disco-kernel.git/commitdiff
Merge branch 'timers/core' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 16 Sep 2013 20:10:26 +0000 (16:10 -0400)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 16 Sep 2013 20:10:26 +0000 (16:10 -0400)
Pull timer code update from Thomas Gleixner:
 - armada SoC clocksource overhaul with a trivial merge conflict
 - Minor improvements to various SoC clocksource drivers

* 'timers/core' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  clocksource: armada-370-xp: Add detailed clock requirements in devicetree binding
  clocksource: armada-370-xp: Get reference fixed-clock by name
  clocksource: armada-370-xp: Replace WARN_ON with BUG_ON
  clocksource: armada-370-xp: Fix device-tree binding
  clocksource: armada-370-xp: Introduce new compatibles
  clocksource: armada-370-xp: Use CLOCKSOURCE_OF_DECLARE
  clocksource: armada-370-xp: Simplify TIMER_CTRL register access
  clocksource: armada-370-xp: Use BIT()
  ARM: timer-sp: Set dynamic irq affinity
  ARM: nomadik: add dynamic irq flag to the timer
  clocksource: sh_cmt: 32-bit control register support
  clocksource: em_sti: Convert to devm_* managed helpers

1  2 
arch/arm/mach-mvebu/armada-370-xp.c
drivers/clocksource/time-armada-370-xp.c

index 829b5730632864b7da0158e8e6c6f833e421e579,4ea03ad4117971060d3807d7a5f88f3460a02ef6..e2acff98e750a013dd54356249306259cb055091
@@@ -37,9 -37,41 +37,9 @@@ static void __init armada_370_xp_map_io
  static void __init armada_370_xp_timer_and_clk_init(void)
  {
        of_clk_init(NULL);
-       armada_370_xp_timer_init();
+       clocksource_of_init();
        coherency_init();
 -      armada_370_xp_mbus_init();
 +      BUG_ON(mvebu_mbus_dt_init());
  #ifdef CONFIG_CACHE_L2X0
        l2x0_of_init(0, ~0UL);
  #endif
index 847cab6f6e31009f9a97560642ee4685497ead18,44c4fff2f58cc086f8bcd5e94c9bd7b7c8e1fd55..0198504ef6b02388c8847bc4897eca4e58328479
@@@ -29,9 -41,9 +42,8 @@@
  #include <linux/irq.h>
  #include <linux/module.h>
  #include <linux/sched_clock.h>
 -
 -#include <asm/localtimer.h>
  #include <linux/percpu.h>
- #include <linux/time-armada-370-xp.h>
 +
  /*
   * Timer block registers.
   */
@@@ -70,8 -82,20 +82,20 @@@ static bool timer25Mhz = true
   */
  static u32 ticks_per_jiffy;
  
 -static struct clock_event_device __percpu **percpu_armada_370_xp_evt;
 +static struct clock_event_device __percpu *armada_370_xp_evt;
  
+ static void timer_ctrl_clrset(u32 clr, u32 set)
+ {
+       writel((readl(timer_base + TIMER_CTRL_OFF) & ~clr) | set,
+               timer_base + TIMER_CTRL_OFF);
+ }
+ static void local_timer_ctrl_clrset(u32 clr, u32 set)
+ {
+       writel((readl(local_base + TIMER_CTRL_OFF) & ~clr) | set,
+               local_base + TIMER_CTRL_OFF);
+ }
  static u32 notrace armada_370_xp_read_sched_clock(void)
  {
        return ~readl(timer_base + TIMER0_VAL_OFF);
@@@ -163,25 -184,30 +177,25 @@@ static irqreturn_t armada_370_xp_timer_
   */
  static int armada_370_xp_timer_setup(struct clock_event_device *evt)
  {
-       u32 u;
+       u32 clr = 0, set = 0;
        int cpu = smp_processor_id();
  
-       u = readl(local_base + TIMER_CTRL_OFF);
 -      /* Use existing clock_event for cpu 0 */
 -      if (!smp_processor_id())
 -              return 0;
 -
        if (timer25Mhz)
-               writel(u | TIMER0_25MHZ, local_base + TIMER_CTRL_OFF);
+               set = TIMER0_25MHZ;
        else
-               writel(u & ~TIMER0_25MHZ, local_base + TIMER_CTRL_OFF);
+               clr = TIMER0_25MHZ;
+       local_timer_ctrl_clrset(clr, set);
  
 -      evt->name               = armada_370_xp_clkevt.name;
 -      evt->irq                = armada_370_xp_clkevt.irq;
 -      evt->features           = armada_370_xp_clkevt.features;
 -      evt->shift              = armada_370_xp_clkevt.shift;
 -      evt->rating             = armada_370_xp_clkevt.rating,
 +      evt->name               = "armada_370_xp_per_cpu_tick",
 +      evt->features           = CLOCK_EVT_FEAT_ONESHOT |
 +                                CLOCK_EVT_FEAT_PERIODIC;
 +      evt->shift              = 32,
 +      evt->rating             = 300,
        evt->set_next_event     = armada_370_xp_clkevt_next_event,
        evt->set_mode           = armada_370_xp_clkevt_mode,
 +      evt->irq                = armada_370_xp_clkevt_irq;
        evt->cpumask            = cpumask_of(cpu);
  
 -      *__this_cpu_ptr(percpu_armada_370_xp_evt) = evt;
 -
        clockevents_config_and_register(evt, timer_clk, 1, 0xfffffffe);
        enable_percpu_irq(evt->irq, 0);
  
@@@ -194,59 -220,26 +208,44 @@@ static void armada_370_xp_timer_stop(st
        disable_percpu_irq(evt->irq);
  }
  
 -static struct local_timer_ops armada_370_xp_local_timer_ops = {
 -      .setup  = armada_370_xp_timer_setup,
 -      .stop   =  armada_370_xp_timer_stop,
 +static int armada_370_xp_timer_cpu_notify(struct notifier_block *self,
 +                                         unsigned long action, void *hcpu)
 +{
 +      /*
 +       * Grab cpu pointer in each case to avoid spurious
 +       * preemptible warnings
 +       */
 +      switch (action & ~CPU_TASKS_FROZEN) {
 +      case CPU_STARTING:
 +              armada_370_xp_timer_setup(this_cpu_ptr(armada_370_xp_evt));
 +              break;
 +      case CPU_DYING:
 +              armada_370_xp_timer_stop(this_cpu_ptr(armada_370_xp_evt));
 +              break;
 +      }
 +
 +      return NOTIFY_OK;
 +}
 +
 +static struct notifier_block armada_370_xp_timer_cpu_nb = {
 +      .notifier_call = armada_370_xp_timer_cpu_notify,
  };
  
void __init armada_370_xp_timer_init(void)
static void __init armada_370_xp_timer_common_init(struct device_node *np)
  {
-       u32 u;
-       struct device_node *np;
+       u32 clr = 0, set = 0;
        int res;
  
-       np = of_find_compatible_node(NULL, NULL, "marvell,armada-370-xp-timer");
        timer_base = of_iomap(np, 0);
        WARN_ON(!timer_base);
        local_base = of_iomap(np, 1);
  
-       if (of_find_property(np, "marvell,timer-25Mhz", NULL)) {
-               /* The fixed 25MHz timer is available so let's use it */
-               u = readl(timer_base + TIMER_CTRL_OFF);
-               writel(u | TIMER0_25MHZ,
-                      timer_base + TIMER_CTRL_OFF);
-               timer_clk = 25000000;
-       } else {
-               unsigned long rate = 0;
-               struct clk *clk = of_clk_get(np, 0);
-               WARN_ON(IS_ERR(clk));
-               rate =  clk_get_rate(clk);
-               u = readl(timer_base + TIMER_CTRL_OFF);
-               writel(u & ~(TIMER0_25MHZ),
-                      timer_base + TIMER_CTRL_OFF);
-               timer_clk = rate / TIMER_DIVIDER;
-               timer25Mhz = false;
-       }
+       if (timer25Mhz)
 -              set = TIMER0_25MHZ;
++              set = TIMER0_25MHZ;             
+       else
+               clr = TIMER0_25MHZ;
+       timer_ctrl_clrset(clr, set);
+       local_timer_ctrl_clrset(clr, set);
  
        /*
         * We use timer 0 as clocksource, and private(local) timer 0
        /*
         * Setup clockevent timer (interrupt-driven).
         */
 -      *__this_cpu_ptr(percpu_armada_370_xp_evt) = &armada_370_xp_clkevt;
 -      res = request_percpu_irq(armada_370_xp_clkevt.irq,
 +      res = request_percpu_irq(armada_370_xp_clkevt_irq,
                                armada_370_xp_timer_interrupt,
 -                              armada_370_xp_clkevt.name,
 -                              percpu_armada_370_xp_evt);
 -      if (!res) {
 -              enable_percpu_irq(armada_370_xp_clkevt.irq, 0);
 -#ifdef CONFIG_LOCAL_TIMERS
 -              local_timer_register(&armada_370_xp_local_timer_ops);
 -#endif
 -      }
 +                              "armada_370_xp_per_cpu_tick",
 +                              armada_370_xp_evt);
 +      /* Immediately configure the timer on the boot CPU */
 +      if (!res)
 +              armada_370_xp_timer_setup(this_cpu_ptr(armada_370_xp_evt));
  }
+ static void __init armada_xp_timer_init(struct device_node *np)
+ {
+       struct clk *clk = of_clk_get_by_name(np, "fixed");
+       /* The 25Mhz fixed clock is mandatory, and must always be available */
+       BUG_ON(IS_ERR(clk));
+       timer_clk = clk_get_rate(clk);
+       armada_370_xp_timer_common_init(np);
+ }
+ CLOCKSOURCE_OF_DECLARE(armada_xp, "marvell,armada-xp-timer",
+                      armada_xp_timer_init);
+ static void __init armada_370_timer_init(struct device_node *np)
+ {
+       struct clk *clk = of_clk_get(np, 0);
+       BUG_ON(IS_ERR(clk));
+       timer_clk = clk_get_rate(clk) / TIMER_DIVIDER;
+       timer25Mhz = false;
+       armada_370_xp_timer_common_init(np);
+ }
+ CLOCKSOURCE_OF_DECLARE(armada_370, "marvell,armada-370-timer",
+                      armada_370_timer_init);