/*
* 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)
.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;
}
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)
{
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)
{
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)
.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)
{