Merge tag 'remove-local-timers' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorOlof Johansson <olof@lixom.net>
Tue, 23 Jul 2013 21:51:34 +0000 (14:51 -0700)
committerOlof Johansson <olof@lixom.net>
Tue, 23 Jul 2013 23:54:15 +0000 (16:54 -0700)
From Stephen Boyd:

Now that we have a generic arch hook for broadcast we can remove the
local timer API entirely. Doing so will reduce code in ARM core, reduce
the architecture dependencies of our timer drivers, and simplify the code
because we no longer go through an architecture layer that is essentially
a hotplug notifier.

* tag 'remove-local-timers' of git://git.kernel.org/pub/scm/linux/kernel/git/davidb/linux-msm:
  ARM: smp: Remove local timer API
  clocksource: time-armada-370-xp: Divorce from local timer API
  clocksource: time-armada-370-xp: Fix sparse warning
  ARM: msm: Divorce msm_timer from local timer API
  ARM: PRIMA2: Divorce timer-marco from local timer API
  ARM: EXYNOS4: Divorce mct from local timer API
  ARM: OMAP2+: Divorce from local timer API
  ARM: smp_twd: Divorce smp_twd from local timer API
  ARM: smp: Remove duplicate dummy timer implementation

Resolved a large number of conflicts due to __cpuinit cleanups, etc.

Signed-off-by: Olof Johansson <olof@lixom.net>
13 files changed:
1  2 
arch/arm/Kconfig
arch/arm/kernel/smp.c
arch/arm/kernel/smp_twd.c
arch/arm/mach-imx/Kconfig
arch/arm/mach-msm/timer.c
arch/arm/mach-omap2/Kconfig
arch/arm/mach-omap2/timer.c
arch/arm/mach-tegra/Kconfig
arch/arm/mach-ux500/Kconfig
arch/arm/mach-vexpress/Kconfig
drivers/clocksource/exynos_mct.c
drivers/clocksource/time-armada-370-xp.c
drivers/clocksource/timer-marco.c

Simple merge
Simple merge
@@@ -265,9 -267,9 +267,9 @@@ static void twd_get_clock(struct device
  /*
   * Setup the local clock events for a CPU.
   */
- static int twd_timer_setup(struct clock_event_device *clk)
 -static void __cpuinit twd_timer_setup(void)
++static void twd_timer_setup(void)
  {
-       struct clock_event_device **this_cpu_clk;
+       struct clock_event_device *clk = __this_cpu_ptr(twd_evt);
        int cpu = smp_processor_id();
  
        /*
        clockevents_config_and_register(clk, twd_timer_rate,
                                        0xf, 0xffffffff);
        enable_percpu_irq(clk->irq, 0);
+ }
  
-       return 0;
 -static int __cpuinit twd_timer_cpu_notify(struct notifier_block *self,
 -                                         unsigned long action, void *hcpu)
++static int twd_timer_cpu_notify(struct notifier_block *self,
++                              unsigned long action, void *hcpu)
+ {
+       switch (action & ~CPU_TASKS_FROZEN) {
+       case CPU_STARTING:
+               twd_timer_setup();
+               break;
+       case CPU_DYING:
+               twd_timer_stop();
+               break;
+       }
+       return NOTIFY_OK;
  }
  
- static struct local_timer_ops twd_lt_ops = {
-       .setup  = twd_timer_setup,
-       .stop   = twd_timer_stop,
 -static struct notifier_block twd_timer_cpu_nb __cpuinitdata = {
++static struct notifier_block twd_timer_cpu_nb = {
+       .notifier_call = twd_timer_cpu_notify,
  };
  
  static int __init twd_local_timer_common_register(struct device_node *np)
Simple merge
@@@ -138,23 -127,34 +127,34 @@@ static struct clocksource msm_clocksour
        .flags  = CLOCK_SOURCE_IS_CONTINUOUS,
  };
  
- #ifdef CONFIG_LOCAL_TIMERS
+ static int msm_timer_irq;
+ static int msm_timer_has_ppi;
 -static int __cpuinit msm_local_timer_setup(struct clock_event_device *evt)
 +static int msm_local_timer_setup(struct clock_event_device *evt)
  {
-       /* Use existing clock_event for cpu 0 */
-       if (!smp_processor_id())
-               return 0;
-       evt->irq = msm_clockevent.irq;
-       evt->name = "local_timer";
-       evt->features = msm_clockevent.features;
-       evt->rating = msm_clockevent.rating;
+       int cpu = smp_processor_id();
+       int err;
+       evt->irq = msm_timer_irq;
+       evt->name = "msm_timer";
+       evt->features = CLOCK_EVT_FEAT_ONESHOT;
+       evt->rating = 200;
        evt->set_mode = msm_timer_set_mode;
        evt->set_next_event = msm_timer_set_next_event;
+       evt->cpumask = cpumask_of(cpu);
+       clockevents_config_and_register(evt, GPT_HZ, 4, 0xffffffff);
+       if (msm_timer_has_ppi) {
+               enable_percpu_irq(evt->irq, IRQ_TYPE_EDGE_RISING);
+       } else {
+               err = request_irq(evt->irq, msm_timer_interrupt,
+                               IRQF_TIMER | IRQF_NOBALANCING |
+                               IRQF_TRIGGER_RISING, "gp_timer", evt);
+               if (err)
+                       pr_err("request_irq failed\n");
+       }
  
-       *__this_cpu_ptr(msm_evt.percpu_evt) = evt;
-       clockevents_config_and_register(evt, GPT_HZ, 4, 0xf0000000);
-       enable_percpu_irq(evt->irq, IRQ_TYPE_EDGE_RISING);
        return 0;
  }
  
@@@ -164,11 -164,28 +164,28 @@@ static void msm_local_timer_stop(struc
        disable_percpu_irq(evt->irq);
  }
  
- static struct local_timer_ops msm_local_timer_ops = {
-       .setup  = msm_local_timer_setup,
-       .stop   = msm_local_timer_stop,
 -static int __cpuinit msm_timer_cpu_notify(struct notifier_block *self,
++static int msm_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:
+               msm_local_timer_setup(this_cpu_ptr(msm_evt));
+               break;
+       case CPU_DYING:
+               msm_local_timer_stop(this_cpu_ptr(msm_evt));
+               break;
+       }
+       return NOTIFY_OK;
+ }
 -static struct notifier_block msm_timer_cpu_nb __cpuinitdata = {
++static struct notifier_block msm_timer_cpu_nb = {
+       .notifier_call = msm_timer_cpu_notify,
  };
- #endif /* CONFIG_LOCAL_TIMERS */
  
  static notrace u32 msm_sched_clock_read(void)
  {
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
@@@ -448,11 -462,32 +445,32 @@@ static void exynos4_local_timer_stop(st
                disable_percpu_irq(mct_irqs[MCT_L0_IRQ]);
  }
  
- static struct local_timer_ops exynos4_mct_tick_ops = {
-       .setup  = exynos4_local_timer_setup,
-       .stop   = exynos4_local_timer_stop,
 -static int __cpuinit exynos4_mct_cpu_notify(struct notifier_block *self,
++static int exynos4_mct_cpu_notify(struct notifier_block *self,
+                                          unsigned long action, void *hcpu)
+ {
+       struct mct_clock_event_device *mevt;
+       /*
+        * Grab cpu pointer in each case to avoid spurious
+        * preemptible warnings
+        */
+       switch (action & ~CPU_TASKS_FROZEN) {
+       case CPU_STARTING:
+               mevt = this_cpu_ptr(&percpu_mct_tick);
+               exynos4_local_timer_setup(&mevt->evt);
+               break;
+       case CPU_DYING:
+               mevt = this_cpu_ptr(&percpu_mct_tick);
+               exynos4_local_timer_stop(&mevt->evt);
+               break;
+       }
+       return NOTIFY_OK;
+ }
 -static struct notifier_block exynos4_mct_cpu_nb __cpuinitdata = {
++static struct notifier_block exynos4_mct_cpu_nb = {
+       .notifier_call = exynos4_mct_cpu_notify,
  };
- #endif /* CONFIG_LOCAL_TIMERS */
  
  static void __init exynos4_timer_resources(struct device_node *np, void __iomem *base)
  {
@@@ -199,15 -188,33 +188,33 @@@ static int armada_370_xp_timer_setup(st
        return 0;
  }
  
- static void  armada_370_xp_timer_stop(struct clock_event_device *evt)
 -static void __cpuinit armada_370_xp_timer_stop(struct clock_event_device *evt)
++static void armada_370_xp_timer_stop(struct clock_event_device *evt)
  {
        evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt);
        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 __cpuinit armada_370_xp_timer_cpu_notify(struct notifier_block *self,
++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 __cpuinitdata = {
++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)
@@@ -184,43 -175,69 +175,69 @@@ static struct irqaction sirfsoc_timer1_
        .handler = sirfsoc_timer_interrupt,
  };
  
 -static int __cpuinit sirfsoc_local_timer_setup(struct clock_event_device *ce)
 +static int sirfsoc_local_timer_setup(struct clock_event_device *ce)
  {
-       /* Use existing clock_event for cpu 0 */
-       if (!smp_processor_id())
-               return 0;
+       int cpu = smp_processor_id();
+       struct irqaction *action;
+       if (cpu == 0)
+               action = &sirfsoc_timer_irq;
+       else
+               action = &sirfsoc_timer1_irq;
  
-       ce->irq = sirfsoc_timer1_irq.irq;
+       ce->irq = action->irq;
        ce->name = "local_timer";
-       ce->features = sirfsoc_clockevent.features;
-       ce->rating = sirfsoc_clockevent.rating;
+       ce->features = CLOCK_EVT_FEAT_ONESHOT;
+       ce->rating = 200;
        ce->set_mode = sirfsoc_timer_set_mode;
        ce->set_next_event = sirfsoc_timer_set_next_event;
-       ce->shift = sirfsoc_clockevent.shift;
-       ce->mult = sirfsoc_clockevent.mult;
-       ce->max_delta_ns = sirfsoc_clockevent.max_delta_ns;
-       ce->min_delta_ns = sirfsoc_clockevent.min_delta_ns;
+       clockevents_calc_mult_shift(ce, CLOCK_TICK_RATE, 60);
+       ce->max_delta_ns = clockevent_delta2ns(-2, ce);
+       ce->min_delta_ns = clockevent_delta2ns(2, ce);
+       ce->cpumask = cpumask_of(cpu);
  
-       sirfsoc_timer1_irq.dev_id = ce;
-       BUG_ON(setup_irq(ce->irq, &sirfsoc_timer1_irq));
-       irq_set_affinity(sirfsoc_timer1_irq.irq, cpumask_of(1));
+       action->dev_id = ce;
+       BUG_ON(setup_irq(ce->irq, action));
+       irq_set_affinity(action->irq, cpumask_of(cpu));
  
        clockevents_register_device(ce);
        return 0;
  }
  
 -static void __cpuinit sirfsoc_local_timer_stop(struct clock_event_device *ce)
 +static void sirfsoc_local_timer_stop(struct clock_event_device *ce)
  {
+       int cpu = smp_processor_id();
        sirfsoc_timer_count_disable(1);
  
-       remove_irq(sirfsoc_timer1_irq.irq, &sirfsoc_timer1_irq);
+       if (cpu == 0)
+               remove_irq(sirfsoc_timer_irq.irq, &sirfsoc_timer_irq);
+       else
+               remove_irq(sirfsoc_timer1_irq.irq, &sirfsoc_timer1_irq);
  }
  
- static struct local_timer_ops sirfsoc_local_timer_ops = {
-       .setup  = sirfsoc_local_timer_setup,
-       .stop   = sirfsoc_local_timer_stop,
 -static int __cpuinit sirfsoc_cpu_notify(struct notifier_block *self,
 -                                         unsigned long action, void *hcpu)
++static int sirfsoc_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:
+               sirfsoc_local_timer_setup(this_cpu_ptr(sirfsoc_clockevent));
+               break;
+       case CPU_DYING:
+               sirfsoc_local_timer_stop(this_cpu_ptr(sirfsoc_clockevent));
+               break;
+       }
+       return NOTIFY_OK;
+ }
 -static struct notifier_block sirfsoc_cpu_nb __cpuinitdata = {
++static struct notifier_block sirfsoc_cpu_nb = {
+       .notifier_call = sirfsoc_cpu_notify,
  };
- #endif /* CONFIG_LOCAL_TIMERS */
  
  static void __init sirfsoc_clockevent_init(void)
  {