All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v1 00/18] Allow local timers to be registered at runtime
@ 2011-06-03 14:57 Marc Zyngier
  2011-06-03 14:57 ` [PATCH v1 01/18] ARM: Move local timer support out of smp.c Marc Zyngier
                   ` (17 more replies)
  0 siblings, 18 replies; 19+ messages in thread
From: Marc Zyngier @ 2011-06-03 14:57 UTC (permalink / raw)
  To: linux-arm-kernel

The current local timer implementation assumes that a kernel image
only contains a single local timer implementation by enforcing global
function names. This is one of the many problems to be solve for a
single kernel binary supporting multiple platforms.

This series (based on an earlier one for the A15 timers) implements a
registration interface for local timers, and converts existing ones to
this new interface. It also moves the local timer support out of
smp.c, as other local timer implementations may use local timers even
in UP configurations (A15 being such an exemple).

Patches based on v3.0-rc1 + my previously sent "Consolidating GIC
per-cpu interrupts" series (though the changes are largely
orthogonal). Tested on PB-11MP, Pandaboard, SMDK-V310 and Versatile
Express.

Marc Zyngier (18):
  ARM: Move local timer support out of smp.c
  ARM: local timers: Add runtime registration interface
  ARM: omap2: remove stubbed twd_timer_setup call
  ARM: exynos4: remove stubbed twd_timer_setup call
  ARM: shmobile: remove stubbed twd_timer_setup call
  ARM: tegra: remove stubbed twd_timer_setup call
  ARM: ux500: remove stubbed twd_timer_setup call
  ARM: versatile: remove stubbed twd_timer_setup call
  ARM: remove unused twd_timer_setup stub
  ARM: versatile/vexpress: dynamically register local timer setup
    function
  ARM: msm: dynamically register local timer setup function
  ARM: omap4: dynamically register local timer setup function
  ARM: exynos4: dynamically register local timer setup function
  ARM: shmobile: dynamically register local timer setup function
  ARM: tegra: dynamically register local timer setup function
  ARM: ux500: dynamically register local timer setup function
  ARM: simplify percpu_timer_setup
  ARM: simplify percpu_timer_ack

 arch/arm/Kconfig                                  |    6 +-
 arch/arm/include/asm/localtimer.h                 |   50 +++++---
 arch/arm/include/asm/smp.h                        |    4 +
 arch/arm/include/asm/smp_twd.h                    |   14 ++-
 arch/arm/kernel/Makefile                          |    1 +
 arch/arm/kernel/percpu_timer.c                    |  126 +++++++++++++++++++++
 arch/arm/kernel/smp.c                             |   74 +------------
 arch/arm/kernel/smp_twd.c                         |   21 +++-
 arch/arm/mach-exynos4/Makefile                    |    1 -
 arch/arm/mach-exynos4/localtimer.c                |   27 -----
 arch/arm/mach-exynos4/mct.c                       |   17 +++-
 arch/arm/mach-exynos4/time.c                      |   12 ++
 arch/arm/mach-msm/timer.c                         |   27 +++--
 arch/arm/mach-omap2/Makefile                      |    1 -
 arch/arm/mach-omap2/timer-gp.c                    |   14 ++-
 arch/arm/mach-omap2/timer-mpu.c                   |   40 -------
 arch/arm/mach-realview/realview_eb.c              |    4 +-
 arch/arm/mach-realview/realview_pb11mp.c          |    4 +-
 arch/arm/mach-realview/realview_pbx.c             |    5 +-
 arch/arm/mach-shmobile/Makefile                   |    1 -
 arch/arm/mach-shmobile/localtimer.c               |   27 -----
 arch/arm/mach-shmobile/timer.c                    |   16 +++-
 arch/arm/mach-tegra/Makefile                      |    2 +-
 arch/arm/mach-tegra/localtimer.c                  |   27 -----
 arch/arm/mach-tegra/timer.c                       |   12 ++
 arch/arm/mach-ux500/Makefile                      |    1 -
 arch/arm/mach-ux500/cpu.c                         |   14 +++
 arch/arm/mach-ux500/localtimer.c                  |   30 -----
 arch/arm/mach-vexpress/v2m.c                      |    4 +
 arch/arm/plat-versatile/include/plat/localtimer.h |    6 +
 arch/arm/plat-versatile/localtimer.c              |   11 ++-
 31 files changed, 325 insertions(+), 274 deletions(-)
 create mode 100644 arch/arm/kernel/percpu_timer.c
 delete mode 100644 arch/arm/mach-exynos4/localtimer.c
 delete mode 100644 arch/arm/mach-omap2/timer-mpu.c
 delete mode 100644 arch/arm/mach-shmobile/localtimer.c
 delete mode 100644 arch/arm/mach-tegra/localtimer.c
 delete mode 100644 arch/arm/mach-ux500/localtimer.c
 create mode 100644 arch/arm/plat-versatile/include/plat/localtimer.h

^ permalink raw reply	[flat|nested] 19+ messages in thread

* [PATCH v1 01/18] ARM: Move local timer support out of smp.c
  2011-06-03 14:57 [PATCH v1 00/18] Allow local timers to be registered at runtime Marc Zyngier
@ 2011-06-03 14:57 ` Marc Zyngier
  2011-06-03 14:57 ` [PATCH v1 02/18] ARM: local timers: Add runtime registration interface Marc Zyngier
                   ` (16 subsequent siblings)
  17 siblings, 0 replies; 19+ messages in thread
From: Marc Zyngier @ 2011-06-03 14:57 UTC (permalink / raw)
  To: linux-arm-kernel

Historically, local timer support has been tied to SMP.
This is less true these days, as some cores have local timers
even in UP configuration. Furthermore, it is desirable to have
converging implementations for both UP and SMP.

As a result of the above, move the timer code out of smp.c to
percpu_timer.c. Very little else is changed.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm/Kconfig                  |    6 +-
 arch/arm/include/asm/localtimer.h |    9 ++++
 arch/arm/include/asm/smp.h        |    4 ++
 arch/arm/kernel/Makefile          |    1 +
 arch/arm/kernel/percpu_timer.c    |   89 +++++++++++++++++++++++++++++++++++++
 arch/arm/kernel/smp.c             |   74 ++-----------------------------
 6 files changed, 110 insertions(+), 73 deletions(-)
 create mode 100644 arch/arm/kernel/percpu_timer.c

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 6094268..eda2230 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1315,6 +1315,7 @@ config SMP
 	select USE_GENERIC_SMP_HELPERS
 	select ARM_GIC_VPPI
 	select HAVE_ARM_SCU if !ARCH_MSM_SCORPIONMP
+	select HAVE_ARM_TWD if (!ARCH_MSM_SCORPIONMP && !EXYNOS4_MCT)
 	help
 	  This enables support for systems with more than one CPU. If you have
 	  a system with only one CPU, like most personal computers, say N. If
@@ -1395,10 +1396,9 @@ config HOTPLUG_CPU
 	  can be controlled through /sys/devices/system/cpu.
 
 config LOCAL_TIMERS
-	bool "Use local timer interrupts"
-	depends on SMP
+	bool
+	depends on SMP || ARCH_MSM_SCORPIONMP
 	default y
-	select HAVE_ARM_TWD if (!ARCH_MSM_SCORPIONMP && !EXYNOS4_MCT)
 	help
 	  Enable support for local timers on SMP platforms, rather then the
 	  legacy IPI broadcast method.  Local timers allows the system
diff --git a/arch/arm/include/asm/localtimer.h b/arch/arm/include/asm/localtimer.h
index 5c8acb4..b3fd6ea 100644
--- a/arch/arm/include/asm/localtimer.h
+++ b/arch/arm/include/asm/localtimer.h
@@ -24,6 +24,11 @@ void percpu_timer_setup(void);
  */
 irqreturn_t percpu_timer_handler(int irq, void *dev_id);
 
+/*
+ * Kick per-cpu timer event_handler
+ */
+void percpu_timer_run(void);
+
 #ifdef CONFIG_LOCAL_TIMERS
 
 #ifdef CONFIG_HAVE_ARM_TWD
@@ -41,6 +46,10 @@ irqreturn_t percpu_timer_handler(int irq, void *dev_id);
 int local_timer_ack(void);
 
 #endif
+/*
+ * Stop a per-cpu timer
+ */
+void percpu_timer_stop(void);
 
 /*
  * Setup a local timer interrupt for a CPU.
diff --git a/arch/arm/include/asm/smp.h b/arch/arm/include/asm/smp.h
index 73ec155..030a98b 100644
--- a/arch/arm/include/asm/smp.h
+++ b/arch/arm/include/asm/smp.h
@@ -88,4 +88,8 @@ extern void platform_cpu_enable(unsigned int cpu);
 extern void arch_send_call_function_single_ipi(int cpu);
 extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
 
+#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
+void smp_timer_broadcast(const struct cpumask *mask);
+#endif
+
 #endif /* ifndef __ASM_ARM_SMP_H */
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index a5b31af..a5a5e64 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -34,6 +34,7 @@ obj-$(CONFIG_HAVE_SCHED_CLOCK)	+= sched_clock.o
 obj-$(CONFIG_SMP)		+= smp.o smp_tlb.o
 obj-$(CONFIG_HAVE_ARM_SCU)	+= smp_scu.o
 obj-$(CONFIG_HAVE_ARM_TWD)	+= smp_twd.o
+obj-$(CONFIG_LOCAL_TIMERS)	+= percpu_timer.o
 obj-$(CONFIG_DYNAMIC_FTRACE)	+= ftrace.o
 obj-$(CONFIG_FUNCTION_GRAPH_TRACER)	+= ftrace.o
 obj-$(CONFIG_KEXEC)		+= machine_kexec.o relocate_kernel.o
diff --git a/arch/arm/kernel/percpu_timer.c b/arch/arm/kernel/percpu_timer.c
new file mode 100644
index 0000000..4b6e230
--- /dev/null
+++ b/arch/arm/kernel/percpu_timer.c
@@ -0,0 +1,89 @@
+/*
+ *  linux/arch/arm/kernel/percpu_timer.c
+ *
+ *  Copyright (C) 2011 ARM Ltd.
+ *  All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/clockchips.h>
+
+#include <asm/localtimer.h>
+
+#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
+static void broadcast_timer_set_mode(enum clock_event_mode mode,
+	struct clock_event_device *evt)
+{
+}
+#else
+#define broadcast_timer_set_mode	NULL
+#define smp_timer_broadcast		NULL
+#endif
+
+static void broadcast_timer_setup(struct clock_event_device *evt)
+{
+	evt->name	= "dummy_timer";
+	evt->features	= CLOCK_EVT_FEAT_ONESHOT |
+			  CLOCK_EVT_FEAT_PERIODIC |
+			  CLOCK_EVT_FEAT_DUMMY;
+	evt->rating	= 400;
+	evt->mult	= 1;
+	evt->set_mode	= broadcast_timer_set_mode;
+	evt->broadcast	= smp_timer_broadcast;
+
+	clockevents_register_device(evt);
+}
+
+/*
+ * Timer (local or broadcast) support
+ */
+static DEFINE_PER_CPU(struct clock_event_device, percpu_clockevent);
+
+irqreturn_t percpu_timer_handler(int irq, void *dev_id)
+{
+	struct clock_event_device *evt = dev_id;
+
+	if (local_timer_ack()) {
+		evt->event_handler(evt);
+		return IRQ_HANDLED;
+	}
+
+	return IRQ_NONE;
+}
+
+void percpu_timer_run(void)
+{
+	struct clock_event_device *evt = &__get_cpu_var(percpu_clockevent);
+	percpu_timer_handler(0, evt);
+}
+
+void __cpuinit percpu_timer_setup(void)
+{
+	unsigned int cpu = smp_processor_id();
+	struct clock_event_device *evt = &per_cpu(percpu_clockevent, cpu);
+
+	evt->cpumask = cpumask_of(cpu);
+	evt->broadcast = smp_timer_broadcast;
+
+	if (local_timer_setup(evt))
+		broadcast_timer_setup(evt);
+}
+
+#ifdef CONFIG_HOTPLUG_CPU
+/*
+ * The generic clock events code purposely does not stop the local timer
+ * on CPU_DEAD/CPU_DEAD_FROZEN hotplug events, so we have to do it
+ * manually here.
+ */
+void percpu_timer_stop(void)
+{
+	unsigned int cpu = smp_processor_id();
+	struct clock_event_device *evt = &per_cpu(percpu_clockevent, cpu);
+
+	evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt);
+}
+#endif
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 476cbff..34b5eeb 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -154,8 +154,6 @@ int __cpuinit __cpu_up(unsigned int cpu)
 }
 
 #ifdef CONFIG_HOTPLUG_CPU
-static void percpu_timer_stop(void);
-
 /*
  * __cpu_disable runs on the processor to be shutdown.
  */
@@ -424,84 +422,20 @@ u64 smp_irq_stat_cpu(unsigned int cpu)
 }
 
 /*
- * Timer (local or broadcast) support
+ * Broadcast timer support
  */
-static DEFINE_PER_CPU(struct clock_event_device, percpu_clockevent);
-
+#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
 static void ipi_timer(void)
 {
-	struct clock_event_device *evt = &__get_cpu_var(percpu_clockevent);
 	irq_enter();
-	evt->event_handler(evt);
+	percpu_timer_run();
 	irq_exit();
 }
 
-#ifdef CONFIG_LOCAL_TIMERS
-irqreturn_t percpu_timer_handler(int irq, void *dev_id)
-{
-	struct clock_event_device *evt = dev_id;
-
-	if (local_timer_ack()) {
-		evt->event_handler(evt);
-		return IRQ_HANDLED;
-	}
-
-	return IRQ_NONE;
-}
-#endif
-
-#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
-static void smp_timer_broadcast(const struct cpumask *mask)
+void smp_timer_broadcast(const struct cpumask *mask)
 {
 	smp_cross_call(mask, IPI_TIMER);
 }
-#else
-#define smp_timer_broadcast	NULL
-#endif
-
-static void broadcast_timer_set_mode(enum clock_event_mode mode,
-	struct clock_event_device *evt)
-{
-}
-
-static void __cpuinit broadcast_timer_setup(struct clock_event_device *evt)
-{
-	evt->name	= "dummy_timer";
-	evt->features	= CLOCK_EVT_FEAT_ONESHOT |
-			  CLOCK_EVT_FEAT_PERIODIC |
-			  CLOCK_EVT_FEAT_DUMMY;
-	evt->rating	= 400;
-	evt->mult	= 1;
-	evt->set_mode	= broadcast_timer_set_mode;
-
-	clockevents_register_device(evt);
-}
-
-void __cpuinit percpu_timer_setup(void)
-{
-	unsigned int cpu = smp_processor_id();
-	struct clock_event_device *evt = &per_cpu(percpu_clockevent, cpu);
-
-	evt->cpumask = cpumask_of(cpu);
-	evt->broadcast = smp_timer_broadcast;
-
-	if (local_timer_setup(evt))
-		broadcast_timer_setup(evt);
-}
-
-#ifdef CONFIG_HOTPLUG_CPU
-/*
- * The generic clock events code purposely does not stop the local timer
- * on CPU_DEAD/CPU_DEAD_FROZEN hotplug events, so we have to do it
- * manually here.
- */
-static void percpu_timer_stop(void)
-{
-	unsigned int cpu = smp_processor_id();
-	struct clock_event_device *evt = &per_cpu(percpu_clockevent, cpu);
-
-	evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt);
-}
 #endif
 
 static DEFINE_SPINLOCK(stop_lock);
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v1 02/18] ARM: local timers: Add runtime registration interface
  2011-06-03 14:57 [PATCH v1 00/18] Allow local timers to be registered at runtime Marc Zyngier
  2011-06-03 14:57 ` [PATCH v1 01/18] ARM: Move local timer support out of smp.c Marc Zyngier
@ 2011-06-03 14:57 ` Marc Zyngier
  2011-06-03 14:57 ` [PATCH v1 03/18] ARM: omap2: remove stubbed twd_timer_setup call Marc Zyngier
                   ` (15 subsequent siblings)
  17 siblings, 0 replies; 19+ messages in thread
From: Marc Zyngier @ 2011-06-03 14:57 UTC (permalink / raw)
  To: linux-arm-kernel

Current local timer code suffers from being resolved at link time,
preventing from having multiple implementations supported by the
same kernel.

Introduce a registration interface that the platform can call at
runtime. smp_twd.c now returns a set of operations that percpu_timer.c
can call.

Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm/include/asm/localtimer.h |   48 +++++++++++++++-----------
 arch/arm/include/asm/smp_twd.h    |   27 +++++++++++++--
 arch/arm/kernel/percpu_timer.c    |   67 +++++++++++++++++++++++++++++++++++--
 arch/arm/kernel/smp_twd.c         |   29 +++++++++++++++-
 4 files changed, 142 insertions(+), 29 deletions(-)

diff --git a/arch/arm/include/asm/localtimer.h b/arch/arm/include/asm/localtimer.h
index b3fd6ea..f95e527 100644
--- a/arch/arm/include/asm/localtimer.h
+++ b/arch/arm/include/asm/localtimer.h
@@ -29,39 +29,47 @@ irqreturn_t percpu_timer_handler(int irq, void *dev_id);
  */
 void percpu_timer_run(void);
 
-#ifdef CONFIG_LOCAL_TIMERS
-
-#ifdef CONFIG_HAVE_ARM_TWD
-
-#include "smp_twd.h"
-
-#define local_timer_ack()	twd_timer_ack()
-
-#else
-
-/*
- * Platform provides this to acknowledge a local timer IRQ.
- * Returns true if the local timer IRQ is to be processed.
- */
-int local_timer_ack(void);
-
-#endif
 /*
  * Stop a per-cpu timer
  */
 void percpu_timer_stop(void);
 
+struct local_timer_ops {
+	void	(*const pre_setup)(struct clock_event_device *clk);
+	int	(*plat_setup)(struct clock_event_device *clk);
+	void	(*plat_teardown)(struct clock_event_device *clk);
+	void	(*const setup)(struct clock_event_device *clk);
+	int	(*const ack)(void);
+};
+
+#ifdef CONFIG_LOCAL_TIMERS
 /*
  * Setup a local timer interrupt for a CPU.
  */
 int local_timer_setup(struct clock_event_device *);
 
+/*
+ * Register a local timer.
+ */
+void percpu_timer_register(struct local_timer_ops *);
 #else
-
-static inline int local_timer_setup(struct clock_event_device *evt)
+static inline void percpu_timer_register(void *dummy)
 {
-	return -ENXIO;
 }
 #endif
 
+static inline int percpu_timer_register_setup(struct local_timer_ops *ops,
+					      int (*plat_setup)(struct clock_event_device *),
+					      void (*plat_teardown)(struct clock_event_device *))
+{
+	if (ops) {
+		ops->plat_setup = plat_setup;
+		ops->plat_teardown = plat_teardown;
+		percpu_timer_register(ops);
+		return 0;
+	}
+
+	return -ENODEV;
+}
+
 #endif
diff --git a/arch/arm/include/asm/smp_twd.h b/arch/arm/include/asm/smp_twd.h
index fed9981..4096736 100644
--- a/arch/arm/include/asm/smp_twd.h
+++ b/arch/arm/include/asm/smp_twd.h
@@ -1,6 +1,8 @@
 #ifndef __ASMARM_SMP_TWD_H
 #define __ASMARM_SMP_TWD_H
 
+#include <linux/clockchips.h>
+
 #define TWD_TIMER_LOAD			0x00
 #define TWD_TIMER_COUNTER		0x04
 #define TWD_TIMER_CONTROL		0x08
@@ -18,11 +20,28 @@
 #define TWD_TIMER_CONTROL_PERIODIC	(1 << 1)
 #define TWD_TIMER_CONTROL_IT_ENABLE	(1 << 2)
 
-struct clock_event_device;
-
 extern void __iomem *twd_base;
 
-int twd_timer_ack(void);
-void twd_timer_setup(struct clock_event_device *);
+#ifdef CONFIG_HAVE_ARM_TWD
+struct local_timer_ops *local_timer_get_twd_ops(void);
+int twd_timer_register_setup(int (*setup)(struct clock_event_device *));
+#else
+static inline struct local_timer_ops *local_timer_get_twd_ops(void)
+{
+	return NULL;
+}
+
+static inline int twd_timer_register_setup(int (*setup)(struct clock_event_device *))
+{
+	return -ENODEV;
+}
+#endif
+
+/*
+ * Dummy function, to be removed once there is no in-tree user anymore.
+ */
+static inline void twd_timer_setup(void *dummy)
+{
+}
 
 #endif
diff --git a/arch/arm/kernel/percpu_timer.c b/arch/arm/kernel/percpu_timer.c
index 4b6e230..94315f5 100644
--- a/arch/arm/kernel/percpu_timer.c
+++ b/arch/arm/kernel/percpu_timer.c
@@ -9,10 +9,13 @@
  * published by the Free Software Foundation.
  */
 
+#include <linux/irq.h>
+#include <linux/seq_file.h>
 #include <linux/interrupt.h>
 #include <linux/clockchips.h>
 
 #include <asm/localtimer.h>
+#include <asm/smp_twd.h>
 
 #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
 static void broadcast_timer_set_mode(enum clock_event_mode mode,
@@ -38,6 +41,44 @@ static void broadcast_timer_setup(struct clock_event_device *evt)
 	clockevents_register_device(evt);
 }
 
+static struct local_timer_ops broadcast_timer_ops = {
+	.setup	= broadcast_timer_setup,
+};
+
+static struct local_timer_ops *timer_ops;
+
+int __attribute__ ((weak)) local_timer_setup(struct clock_event_device *evt)
+{
+	return -ENXIO;
+}
+
+void percpu_timer_register(struct local_timer_ops *ops)
+{
+	timer_ops = ops;
+}
+
+/*
+ * local_timer_ack: checks for a local timer interrupt.
+ *
+ * If a local timer interrupt has occurred, acknowledge and return 1.
+ * Otherwise, return 0.
+ *
+ * This can be overloaded by platform code that doesn't provide its
+ * timer in timer_fns way (msm at the moment). Once all platforms have
+ * migrated, the weak alias can be removed.
+ * If no ack() function has been registered, consider the acknowledgement
+ * to be done.
+ */
+static int percpu_timer_ack(void)
+{
+	if (timer_ops->ack)
+		return timer_ops->ack();
+
+	return 1;
+}
+
+int local_timer_ack(void) __attribute__ ((weak, alias("percpu_timer_ack")));
+
 /*
  * Timer (local or broadcast) support
  */
@@ -63,14 +104,32 @@ void percpu_timer_run(void)
 
 void __cpuinit percpu_timer_setup(void)
 {
+	int ret = 0;
 	unsigned int cpu = smp_processor_id();
 	struct clock_event_device *evt = &per_cpu(percpu_clockevent, cpu);
 
+	/*
+	 * All this can go away once we've migrated all users to
+	 * properly register the timer they use, and broadcast can
+	 * become the fallback.
+	 */
+	if (!timer_ops)
+		timer_ops = local_timer_get_twd_ops();
+	if (!timer_ops)
+		timer_ops = &broadcast_timer_ops;
+	if (!timer_ops->plat_setup)
+		timer_ops->plat_setup = local_timer_setup;
+
 	evt->cpumask = cpumask_of(cpu);
-	evt->broadcast = smp_timer_broadcast;
 
-	if (local_timer_setup(evt))
-		broadcast_timer_setup(evt);
+	if (timer_ops->pre_setup)
+		timer_ops->pre_setup(evt);
+	if (timer_ops->plat_setup)
+		ret = timer_ops->plat_setup(evt);
+	if (ret)	/* Fallback to broadcast */
+		timer_ops = &broadcast_timer_ops;
+	if (timer_ops->setup)
+		timer_ops->setup(evt);
 }
 
 #ifdef CONFIG_HOTPLUG_CPU
@@ -85,5 +144,7 @@ void percpu_timer_stop(void)
 	struct clock_event_device *evt = &per_cpu(percpu_clockevent, cpu);
 
 	evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt);
+	if (timer_ops->plat_teardown)
+		timer_ops->plat_teardown(evt);
 }
 #endif
diff --git a/arch/arm/kernel/smp_twd.c b/arch/arm/kernel/smp_twd.c
index aa99656..91296df 100644
--- a/arch/arm/kernel/smp_twd.c
+++ b/arch/arm/kernel/smp_twd.c
@@ -18,6 +18,7 @@
 #include <linux/interrupt.h>
 #include <linux/io.h>
 
+#include <asm/localtimer.h>
 #include <asm/smp_twd.h>
 #include <asm/localtimer.h>
 #include <asm/hardware/gic.h>
@@ -74,7 +75,7 @@ static int twd_set_next_event(unsigned long evt,
  * If a local timer interrupt has occurred, acknowledge and return 1.
  * Otherwise, return 0.
  */
-int twd_timer_ack(void)
+static int twd_timer_ack(void)
 {
 	if (__raw_readl(twd_base + TWD_TIMER_INTSTAT)) {
 		__raw_writel(1, twd_base + TWD_TIMER_INTSTAT);
@@ -126,7 +127,7 @@ static void __cpuinit twd_calibrate_rate(void)
 /*
  * Setup the local clock events for a CPU.
  */
-void __cpuinit twd_timer_setup(struct clock_event_device *clk)
+static void __cpuinit twd_setup(struct clock_event_device *clk)
 {
 	int err;
 	bool *reqd;
@@ -161,3 +162,27 @@ void __cpuinit twd_timer_setup(struct clock_event_device *clk)
 
 	clockevents_register_device(clk);
 }
+
+static struct local_timer_ops twd_timer_ops = {
+	.setup		= twd_setup,
+	.ack		= twd_timer_ack,
+};
+
+struct local_timer_ops *local_timer_get_twd_ops(void)
+{
+	if (!twd_base) {
+		pr_warn("TWD base address not set\n");
+		return NULL;
+	}
+
+	return &twd_timer_ops;
+}
+
+int __init twd_timer_register_setup(int (*setup)(struct clock_event_device *))
+{
+	if (!twd_base)
+		return -ENODEV;
+
+	percpu_timer_register_setup(&twd_timer_ops, setup, NULL);
+	return 0;
+}
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v1 03/18] ARM: omap2: remove stubbed twd_timer_setup call
  2011-06-03 14:57 [PATCH v1 00/18] Allow local timers to be registered at runtime Marc Zyngier
  2011-06-03 14:57 ` [PATCH v1 01/18] ARM: Move local timer support out of smp.c Marc Zyngier
  2011-06-03 14:57 ` [PATCH v1 02/18] ARM: local timers: Add runtime registration interface Marc Zyngier
@ 2011-06-03 14:57 ` Marc Zyngier
  2011-06-03 14:57 ` [PATCH v1 04/18] ARM: exynos4: " Marc Zyngier
                   ` (14 subsequent siblings)
  17 siblings, 0 replies; 19+ messages in thread
From: Marc Zyngier @ 2011-06-03 14:57 UTC (permalink / raw)
  To: linux-arm-kernel

Cc: Tony Lindgren <tony@atomide.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm/mach-omap2/timer-mpu.c |    3 ---
 1 files changed, 0 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-omap2/timer-mpu.c b/arch/arm/mach-omap2/timer-mpu.c
index 1fd5ca5..c91b1c1 100644
--- a/arch/arm/mach-omap2/timer-mpu.c
+++ b/arch/arm/mach-omap2/timer-mpu.c
@@ -17,10 +17,8 @@
  * published by the Free Software Foundation.
  */
 #include <linux/init.h>
-#include <linux/smp.h>
 #include <linux/clockchips.h>
 #include <asm/irq.h>
-#include <asm/smp_twd.h>
 #include <asm/localtimer.h>
 #include <asm/hardware/gic.h>
 
@@ -34,7 +32,6 @@ int __cpuinit local_timer_setup(struct clock_event_device *evt)
 		return -ENXIO;
 
 	evt->irq = gic_ppi_to_vppi(OMAP44XX_IRQ_LOCALTIMER);
-	twd_timer_setup(evt);
 	return 0;
 }
 
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v1 04/18] ARM: exynos4: remove stubbed twd_timer_setup call
  2011-06-03 14:57 [PATCH v1 00/18] Allow local timers to be registered at runtime Marc Zyngier
                   ` (2 preceding siblings ...)
  2011-06-03 14:57 ` [PATCH v1 03/18] ARM: omap2: remove stubbed twd_timer_setup call Marc Zyngier
@ 2011-06-03 14:57 ` Marc Zyngier
  2011-06-03 14:57 ` [PATCH v1 05/18] ARM: shmobile: " Marc Zyngier
                   ` (13 subsequent siblings)
  17 siblings, 0 replies; 19+ messages in thread
From: Marc Zyngier @ 2011-06-03 14:57 UTC (permalink / raw)
  To: linux-arm-kernel

Cc: Kukjin Kim <kgene.kim@samsung.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm/mach-exynos4/localtimer.c |    1 -
 1 files changed, 0 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-exynos4/localtimer.c b/arch/arm/mach-exynos4/localtimer.c
index 315de6f..6184e29 100644
--- a/arch/arm/mach-exynos4/localtimer.c
+++ b/arch/arm/mach-exynos4/localtimer.c
@@ -22,6 +22,5 @@
 int __cpuinit local_timer_setup(struct clock_event_device *evt)
 {
 	evt->irq = gic_ppi_to_vppi(IRQ_LOCALTIMER);
-	twd_timer_setup(evt);
 	return 0;
 }
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v1 05/18] ARM: shmobile: remove stubbed twd_timer_setup call
  2011-06-03 14:57 [PATCH v1 00/18] Allow local timers to be registered at runtime Marc Zyngier
                   ` (3 preceding siblings ...)
  2011-06-03 14:57 ` [PATCH v1 04/18] ARM: exynos4: " Marc Zyngier
@ 2011-06-03 14:57 ` Marc Zyngier
  2011-06-03 14:57 ` [PATCH v1 06/18] ARM: tegra: " Marc Zyngier
                   ` (12 subsequent siblings)
  17 siblings, 0 replies; 19+ messages in thread
From: Marc Zyngier @ 2011-06-03 14:57 UTC (permalink / raw)
  To: linux-arm-kernel

Cc: Paul Mundt <lethal@linux-sh.org>
Cc: Magnus Damm <magnus.damm@gmail.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm/mach-shmobile/localtimer.c |    1 -
 1 files changed, 0 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-shmobile/localtimer.c b/arch/arm/mach-shmobile/localtimer.c
index 8a67b1c..e09fdd1 100644
--- a/arch/arm/mach-shmobile/localtimer.c
+++ b/arch/arm/mach-shmobile/localtimer.c
@@ -22,6 +22,5 @@
 int __cpuinit local_timer_setup(struct clock_event_device *evt)
 {
 	evt->irq = gic_ppi_to_vppi(29);
-	twd_timer_setup(evt);
 	return 0;
 }
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v1 06/18] ARM: tegra: remove stubbed twd_timer_setup call
  2011-06-03 14:57 [PATCH v1 00/18] Allow local timers to be registered at runtime Marc Zyngier
                   ` (4 preceding siblings ...)
  2011-06-03 14:57 ` [PATCH v1 05/18] ARM: shmobile: " Marc Zyngier
@ 2011-06-03 14:57 ` Marc Zyngier
  2011-06-03 14:57 ` [PATCH v1 07/18] ARM: ux500: " Marc Zyngier
                   ` (11 subsequent siblings)
  17 siblings, 0 replies; 19+ messages in thread
From: Marc Zyngier @ 2011-06-03 14:57 UTC (permalink / raw)
  To: linux-arm-kernel

Cc: Colin Cross <ccross@android.com>
Cc: Erik Gilling <konkers@android.com>
Cc: Olof Johansson <olof@lixom.net>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm/mach-tegra/localtimer.c |    4 +---
 1 files changed, 1 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-tegra/localtimer.c b/arch/arm/mach-tegra/localtimer.c
index 97cd0a9..590f1cc 100644
--- a/arch/arm/mach-tegra/localtimer.c
+++ b/arch/arm/mach-tegra/localtimer.c
@@ -9,10 +9,9 @@
  * published by the Free Software Foundation.
  */
 #include <linux/init.h>
-#include <linux/smp.h>
 #include <linux/clockchips.h>
+
 #include <asm/irq.h>
-#include <asm/smp_twd.h>
 #include <asm/localtimer.h>
 #include <asm/hardware/gic.h>
 
@@ -22,6 +21,5 @@
 int __cpuinit local_timer_setup(struct clock_event_device *evt)
 {
 	evt->irq = gic_ppi_to_vppi(IRQ_LOCALTIMER);
-	twd_timer_setup(evt);
 	return 0;
 }
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v1 07/18] ARM: ux500: remove stubbed twd_timer_setup call
  2011-06-03 14:57 [PATCH v1 00/18] Allow local timers to be registered at runtime Marc Zyngier
                   ` (5 preceding siblings ...)
  2011-06-03 14:57 ` [PATCH v1 06/18] ARM: tegra: " Marc Zyngier
@ 2011-06-03 14:57 ` Marc Zyngier
  2011-06-03 14:57 ` [PATCH v1 08/18] ARM: versatile: " Marc Zyngier
                   ` (10 subsequent siblings)
  17 siblings, 0 replies; 19+ messages in thread
From: Marc Zyngier @ 2011-06-03 14:57 UTC (permalink / raw)
  To: linux-arm-kernel

Cc: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com>
Cc: Linus Walleij <linus.walleij@stericsson.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm/mach-ux500/localtimer.c |    3 ---
 1 files changed, 0 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-ux500/localtimer.c b/arch/arm/mach-ux500/localtimer.c
index f027cef..2697f4e 100644
--- a/arch/arm/mach-ux500/localtimer.c
+++ b/arch/arm/mach-ux500/localtimer.c
@@ -11,11 +11,9 @@
  * published by the Free Software Foundation.
  */
 #include <linux/init.h>
-#include <linux/smp.h>
 #include <linux/clockchips.h>
 
 #include <asm/irq.h>
-#include <asm/smp_twd.h>
 #include <asm/localtimer.h>
 #include <asm/hardware/gic.h>
 
@@ -25,6 +23,5 @@
 int __cpuinit local_timer_setup(struct clock_event_device *evt)
 {
 	evt->irq = gic_ppi_to_vppi(IRQ_LOCALTIMER);
-	twd_timer_setup(evt);
 	return 0;
 }
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v1 08/18] ARM: versatile: remove stubbed twd_timer_setup call
  2011-06-03 14:57 [PATCH v1 00/18] Allow local timers to be registered at runtime Marc Zyngier
                   ` (6 preceding siblings ...)
  2011-06-03 14:57 ` [PATCH v1 07/18] ARM: ux500: " Marc Zyngier
@ 2011-06-03 14:57 ` Marc Zyngier
  2011-06-03 14:57 ` [PATCH v1 09/18] ARM: remove unused twd_timer_setup stub Marc Zyngier
                   ` (9 subsequent siblings)
  17 siblings, 0 replies; 19+ messages in thread
From: Marc Zyngier @ 2011-06-03 14:57 UTC (permalink / raw)
  To: linux-arm-kernel

Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm/plat-versatile/localtimer.c |    3 ---
 1 files changed, 0 insertions(+), 3 deletions(-)

diff --git a/arch/arm/plat-versatile/localtimer.c b/arch/arm/plat-versatile/localtimer.c
index a76daf4..a8e8b85 100644
--- a/arch/arm/plat-versatile/localtimer.c
+++ b/arch/arm/plat-versatile/localtimer.c
@@ -9,10 +9,8 @@
  * published by the Free Software Foundation.
  */
 #include <linux/init.h>
-#include <linux/smp.h>
 #include <linux/clockchips.h>
 
-#include <asm/smp_twd.h>
 #include <asm/localtimer.h>
 #include <asm/hardware/gic.h>
 #include <mach/irqs.h>
@@ -23,6 +21,5 @@
 int __cpuinit local_timer_setup(struct clock_event_device *evt)
 {
 	evt->irq = gic_ppi_to_vppi(IRQ_LOCALTIMER);
-	twd_timer_setup(evt);
 	return 0;
 }
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v1 09/18] ARM: remove unused twd_timer_setup stub
  2011-06-03 14:57 [PATCH v1 00/18] Allow local timers to be registered at runtime Marc Zyngier
                   ` (7 preceding siblings ...)
  2011-06-03 14:57 ` [PATCH v1 08/18] ARM: versatile: " Marc Zyngier
@ 2011-06-03 14:57 ` Marc Zyngier
  2011-06-03 14:57 ` [PATCH v1 10/18] ARM: versatile/vexpress: dynamically register local timer setup function Marc Zyngier
                   ` (8 subsequent siblings)
  17 siblings, 0 replies; 19+ messages in thread
From: Marc Zyngier @ 2011-06-03 14:57 UTC (permalink / raw)
  To: linux-arm-kernel

Now that there is no in-tree users of twd_timer_setup() anymore,
remove it completely.

Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm/include/asm/smp_twd.h |    7 -------
 1 files changed, 0 insertions(+), 7 deletions(-)

diff --git a/arch/arm/include/asm/smp_twd.h b/arch/arm/include/asm/smp_twd.h
index 4096736..d2abe52 100644
--- a/arch/arm/include/asm/smp_twd.h
+++ b/arch/arm/include/asm/smp_twd.h
@@ -37,11 +37,4 @@ static inline int twd_timer_register_setup(int (*setup)(struct clock_event_devic
 }
 #endif
 
-/*
- * Dummy function, to be removed once there is no in-tree user anymore.
- */
-static inline void twd_timer_setup(void *dummy)
-{
-}
-
 #endif
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v1 10/18] ARM: versatile/vexpress: dynamically register local timer setup function
  2011-06-03 14:57 [PATCH v1 00/18] Allow local timers to be registered at runtime Marc Zyngier
                   ` (8 preceding siblings ...)
  2011-06-03 14:57 ` [PATCH v1 09/18] ARM: remove unused twd_timer_setup stub Marc Zyngier
@ 2011-06-03 14:57 ` Marc Zyngier
  2011-06-03 14:57 ` [PATCH v1 11/18] ARM: msm: dynamically register local timer Marc Zyngier
                   ` (7 subsequent siblings)
  17 siblings, 0 replies; 19+ messages in thread
From: Marc Zyngier @ 2011-06-03 14:57 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm/mach-realview/realview_eb.c              |    4 +++-
 arch/arm/mach-realview/realview_pb11mp.c          |    4 +++-
 arch/arm/mach-realview/realview_pbx.c             |    5 +++--
 arch/arm/mach-vexpress/v2m.c                      |    4 ++++
 arch/arm/plat-versatile/include/plat/localtimer.h |    6 ++++++
 arch/arm/plat-versatile/localtimer.c              |   10 +++++++++-
 6 files changed, 28 insertions(+), 5 deletions(-)
 create mode 100644 arch/arm/plat-versatile/include/plat/localtimer.h

diff --git a/arch/arm/mach-realview/realview_eb.c b/arch/arm/mach-realview/realview_eb.c
index 10e75fa..e17e985 100644
--- a/arch/arm/mach-realview/realview_eb.c
+++ b/arch/arm/mach-realview/realview_eb.c
@@ -45,6 +45,8 @@
 #include <mach/board-eb.h>
 #include <mach/irqs.h>
 
+#include <plat/localtimer.h>
+
 #include "core.h"
 
 static struct map_desc realview_eb_io_desc[] __initdata = {
@@ -402,7 +404,7 @@ static void __init realview_eb_timer_init(void)
 
 	if (core_tile_eb11mp() || core_tile_a9mp()) {
 #ifdef CONFIG_LOCAL_TIMERS
-		twd_base = __io_address(REALVIEW_EB11MP_TWD_BASE);
+		versatile_local_timer_init(__io_address(REALVIEW_EB11MP_TWD_BASE));
 #endif
 		timer_irq = IRQ_EB11MP_TIMER0_1;
 	} else
diff --git a/arch/arm/mach-realview/realview_pb11mp.c b/arch/arm/mach-realview/realview_pb11mp.c
index b2985fc..76da67d 100644
--- a/arch/arm/mach-realview/realview_pb11mp.c
+++ b/arch/arm/mach-realview/realview_pb11mp.c
@@ -46,6 +46,8 @@
 #include <mach/board-pb11mp.h>
 #include <mach/irqs.h>
 
+#include <plat/localtimer.h>
+
 #include "core.h"
 
 static struct map_desc realview_pb11mp_io_desc[] __initdata = {
@@ -306,7 +308,7 @@ static void __init realview_pb11mp_timer_init(void)
 	timer3_va_base = __io_address(REALVIEW_PB11MP_TIMER2_3_BASE) + 0x20;
 
 #ifdef CONFIG_LOCAL_TIMERS
-	twd_base = __io_address(REALVIEW_TC11MP_TWD_BASE);
+	versatile_local_timer_init(__io_address(REALVIEW_TC11MP_TWD_BASE));
 #endif
 	realview_timer_init(IRQ_TC11MP_TIMER0_1);
 }
diff --git a/arch/arm/mach-realview/realview_pbx.c b/arch/arm/mach-realview/realview_pbx.c
index 92ace2c..280befd 100644
--- a/arch/arm/mach-realview/realview_pbx.c
+++ b/arch/arm/mach-realview/realview_pbx.c
@@ -31,7 +31,6 @@
 #include <asm/leds.h>
 #include <asm/mach-types.h>
 #include <asm/pmu.h>
-#include <asm/smp_twd.h>
 #include <asm/pgtable.h>
 #include <asm/hardware/gic.h>
 #include <asm/hardware/cache-l2x0.h>
@@ -44,6 +43,8 @@
 #include <mach/board-pbx.h>
 #include <mach/irqs.h>
 
+#include <plat/localtimer.h>
+
 #include "core.h"
 
 static struct map_desc realview_pbx_io_desc[] __initdata = {
@@ -310,7 +311,7 @@ static void __init realview_pbx_timer_init(void)
 
 #ifdef CONFIG_LOCAL_TIMERS
 	if (core_tile_pbx11mp() || core_tile_pbxa9mp())
-		twd_base = __io_address(REALVIEW_PBX_TILE_TWD_BASE);
+		versatile_local_timer_init(__io_address(REALVIEW_PBX_TILE_TWD_BASE));
 #endif
 	realview_timer_init(IRQ_PBX_TIMER0_1);
 }
diff --git a/arch/arm/mach-vexpress/v2m.c b/arch/arm/mach-vexpress/v2m.c
index 9e6b93b..3a1497e 100644
--- a/arch/arm/mach-vexpress/v2m.c
+++ b/arch/arm/mach-vexpress/v2m.c
@@ -28,6 +28,7 @@
 #include <mach/motherboard.h>
 
 #include <plat/sched_clock.h>
+#include <plat/localtimer.h>
 
 #include "core.h"
 
@@ -50,6 +51,9 @@ static void __init v2m_timer_init(void)
 {
 	u32 scctrl;
 
+	/* twd_base is assigned in the tile code */
+	versatile_local_timer_init(NULL);
+
 	/* Select 1MHz TIMCLK as the reference clock for SP804 timers */
 	scctrl = readl(MMIO_P2V(V2M_SYSCTL + SCCTRL));
 	scctrl |= SCCTRL_TIMEREN0SEL_TIMCLK;
diff --git a/arch/arm/plat-versatile/include/plat/localtimer.h b/arch/arm/plat-versatile/include/plat/localtimer.h
new file mode 100644
index 0000000..1246fc2
--- /dev/null
+++ b/arch/arm/plat-versatile/include/plat/localtimer.h
@@ -0,0 +1,6 @@
+#ifndef ARM_PLAT_LOCALTIMER_H
+#define ARM_PLAT_LOCALTIMER_H
+
+void versatile_local_timer_init(void __iomem *base);
+
+#endif
diff --git a/arch/arm/plat-versatile/localtimer.c b/arch/arm/plat-versatile/localtimer.c
index a8e8b85..22603a5 100644
--- a/arch/arm/plat-versatile/localtimer.c
+++ b/arch/arm/plat-versatile/localtimer.c
@@ -11,6 +11,7 @@
 #include <linux/init.h>
 #include <linux/clockchips.h>
 
+#include <asm/smp_twd.h>
 #include <asm/localtimer.h>
 #include <asm/hardware/gic.h>
 #include <mach/irqs.h>
@@ -18,8 +19,15 @@
 /*
  * Setup the local clock events for a CPU.
  */
-int __cpuinit local_timer_setup(struct clock_event_device *evt)
+static int __cpuinit versatile_local_timer_setup(struct clock_event_device *evt)
 {
 	evt->irq = gic_ppi_to_vppi(IRQ_LOCALTIMER);
 	return 0;
 }
+
+void __init versatile_local_timer_init(void __iomem *base)
+{
+	if (base)
+		twd_base = base;
+	twd_timer_register_setup(versatile_local_timer_setup);
+}
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v1 11/18] ARM: msm: dynamically register local timer
  2011-06-03 14:57 [PATCH v1 00/18] Allow local timers to be registered at runtime Marc Zyngier
                   ` (9 preceding siblings ...)
  2011-06-03 14:57 ` [PATCH v1 10/18] ARM: versatile/vexpress: dynamically register local timer setup function Marc Zyngier
@ 2011-06-03 14:57 ` Marc Zyngier
  2011-06-03 14:57 ` [PATCH v1 12/18] ARM: omap4: dynamically register local timer setup function Marc Zyngier
                   ` (6 subsequent siblings)
  17 siblings, 0 replies; 19+ messages in thread
From: Marc Zyngier @ 2011-06-03 14:57 UTC (permalink / raw)
  To: linux-arm-kernel

Cc: David Brown <davidb@codeaurora.org>
Cc: Daniel Walker <dwalker@fifo99.com>
Cc: Bryan Huntsman <bryanh@codeaurora.org>
Cc: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm/mach-msm/timer.c |   27 ++++++++++++++++++---------
 1 files changed, 18 insertions(+), 9 deletions(-)

diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c
index b2747cc..8595b83 100644
--- a/arch/arm/mach-msm/timer.c
+++ b/arch/arm/mach-msm/timer.c
@@ -22,9 +22,11 @@
 #include <linux/delay.h>
 #include <linux/io.h>
 
+#include <asm/localtimer.h>
 #include <asm/mach/time.h>
 #include <asm/hardware/gic.h>
 #include <mach/msm_iomap.h>
+
 #include <mach/cpu.h>
 
 #define TIMER_MATCH_VAL         0x0000
@@ -188,6 +190,17 @@ static struct msm_clock msm_clocks[] = {
 	}
 };
 
+#ifdef CONFIG_SMP
+static void __cpuinit msm_local_timer_setup(struct clock_event_device *evt);
+
+static struct local_timer_ops msm_timer_ops = {
+	.setup	= msm_local_timer_setup,
+};
+#define msm_timer_ops_ptr	(&msm_timer_ops)
+#else
+#define msm_timer_ops_ptr	NULL
+#endif
+
 static void __init msm_timer_init(void)
 {
 	int i;
@@ -216,6 +229,8 @@ static void __init msm_timer_init(void)
 	writel(DGT_CLK_CTL_DIV_4, MSM_TMR_BASE + DGT_CLK_CTL);
 #endif
 
+	percpu_timer_register(msm_timer_ops_ptr);
+
 	for (i = 0; i < ARRAY_SIZE(msm_clocks); i++) {
 		struct msm_clock *clock = &msm_clocks[i];
 		struct clock_event_device *ce = &clock->clockevent;
@@ -254,7 +269,7 @@ static void __init msm_timer_init(void)
 }
 
 #ifdef CONFIG_SMP
-int __cpuinit local_timer_setup(struct clock_event_device *evt)
+static void __cpuinit msm_local_timer_setup(struct clock_event_device *evt)
 {
 	static bool local_timer_inited;
 	struct msm_clock *clock = &msm_clocks[MSM_GLOBAL_TIMER];
@@ -262,7 +277,7 @@ int __cpuinit local_timer_setup(struct clock_event_device *evt)
 
 	/* Use existing clock_event for cpu 0 */
 	if (!smp_processor_id())
-		return 0;
+		return;
 
 	writel(DGT_CLK_CTL_DIV_4, MSM_TMR_BASE + DGT_CLK_CTL);
 
@@ -289,19 +304,13 @@ int __cpuinit local_timer_setup(struct clock_event_device *evt)
 		if (res) {
 			pr_err("local_timer_setup: request_irq failed for %s\n",
 			       clock->clockevent.name);
-			return res;
+			return;
 		}
 		local_timer_inited = true;
 	} else
 		enable_irq(evt->irq);
 
 	clockevents_register_device(evt);
-	return 0;
-}
-
-inline int local_timer_ack(void)
-{
-	return 1;
 }
 
 #endif
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v1 12/18] ARM: omap4: dynamically register local timer setup function
  2011-06-03 14:57 [PATCH v1 00/18] Allow local timers to be registered at runtime Marc Zyngier
                   ` (10 preceding siblings ...)
  2011-06-03 14:57 ` [PATCH v1 11/18] ARM: msm: dynamically register local timer Marc Zyngier
@ 2011-06-03 14:57 ` Marc Zyngier
  2011-06-03 14:57 ` [PATCH v1 13/18] ARM: exynos4: " Marc Zyngier
                   ` (5 subsequent siblings)
  17 siblings, 0 replies; 19+ messages in thread
From: Marc Zyngier @ 2011-06-03 14:57 UTC (permalink / raw)
  To: linux-arm-kernel

Cc: Tony Lindgren <tony@atomide.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm/mach-omap2/Makefile    |    1 -
 arch/arm/mach-omap2/timer-gp.c  |   14 +++++++++++++-
 arch/arm/mach-omap2/timer-mpu.c |   37 -------------------------------------
 3 files changed, 13 insertions(+), 39 deletions(-)
 delete mode 100644 arch/arm/mach-omap2/timer-mpu.c

diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index b148077..f48c989 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -22,7 +22,6 @@ obj-$(CONFIG_TWL4030_CORE) += omap_twl.o
 
 # SMP support ONLY available for OMAP4
 obj-$(CONFIG_SMP)			+= omap-smp.o omap-headsmp.o
-obj-$(CONFIG_LOCAL_TIMERS)		+= timer-mpu.o
 obj-$(CONFIG_HOTPLUG_CPU)		+= omap-hotplug.o
 obj-$(CONFIG_ARCH_OMAP4)		+= omap44xx-smc.o omap4-common.o
 
diff --git a/arch/arm/mach-omap2/timer-gp.c b/arch/arm/mach-omap2/timer-gp.c
index 3b9cf85..b44341a 100644
--- a/arch/arm/mach-omap2/timer-gp.c
+++ b/arch/arm/mach-omap2/timer-gp.c
@@ -39,7 +39,9 @@
 #include <asm/mach/time.h>
 #include <plat/dmtimer.h>
 #include <asm/localtimer.h>
+#include <asm/smp_twd.h>
 #include <asm/sched_clock.h>
+#include <asm/hardware/gic.h>
 #include <plat/common.h>
 #include <plat/omap_hwmod.h>
 
@@ -247,12 +249,22 @@ static void __init omap2_gp_clocksource_init(void)
 }
 #endif
 
+#ifdef CONFIG_LOCAL_TIMERS
+static int __cpuinit omap4_local_timer_setup(struct clock_event_device *evt)
+{
+	evt->irq = gic_ppi_to_vppi(OMAP44XX_IRQ_LOCALTIMER);
+	return 0;
+}
+#endif
+
 static void __init omap2_gp_timer_init(void)
 {
 #ifdef CONFIG_LOCAL_TIMERS
-	if (cpu_is_omap44xx()) {
+	if (cpu_is_omap44xx() && omap_rev() != OMAP4430_REV_ES1_0) {
 		twd_base = ioremap(OMAP44XX_LOCAL_TWD_BASE, SZ_256);
 		BUG_ON(!twd_base);
+
+		twd_timer_register_setup(omap4_local_timer_setup);
 	}
 #endif
 	omap_dm_timer_init();
diff --git a/arch/arm/mach-omap2/timer-mpu.c b/arch/arm/mach-omap2/timer-mpu.c
deleted file mode 100644
index c91b1c1..0000000
--- a/arch/arm/mach-omap2/timer-mpu.c
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * The MPU local timer source file. In OMAP4, both cortex-a9 cores have
- * own timer in it's MPU domain. These timers will be driving the
- * linux kernel SMP tick framework when active. These timers are not
- * part of the wake up domain.
- *
- * Copyright (C) 2009 Texas Instruments, Inc.
- *
- * Author:
- *      Santosh Shilimkar <santosh.shilimkar@ti.com>
- *
- * This file is based on arm realview smp platform file.
- * Copyright (C) 2002 ARM Ltd.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <linux/init.h>
-#include <linux/clockchips.h>
-#include <asm/irq.h>
-#include <asm/localtimer.h>
-#include <asm/hardware/gic.h>
-
-/*
- * Setup the local clock events for a CPU.
- */
-int __cpuinit local_timer_setup(struct clock_event_device *evt)
-{
-	/* Local timers are not supprted on OMAP4430 ES1.0 */
-	if (omap_rev() == OMAP4430_REV_ES1_0)
-		return -ENXIO;
-
-	evt->irq = gic_ppi_to_vppi(OMAP44XX_IRQ_LOCALTIMER);
-	return 0;
-}
-
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v1 13/18] ARM: exynos4: dynamically register local timer setup function
  2011-06-03 14:57 [PATCH v1 00/18] Allow local timers to be registered at runtime Marc Zyngier
                   ` (11 preceding siblings ...)
  2011-06-03 14:57 ` [PATCH v1 12/18] ARM: omap4: dynamically register local timer setup function Marc Zyngier
@ 2011-06-03 14:57 ` Marc Zyngier
  2011-06-03 14:57 ` [PATCH v1 14/18] ARM: shmobile: " Marc Zyngier
                   ` (4 subsequent siblings)
  17 siblings, 0 replies; 19+ messages in thread
From: Marc Zyngier @ 2011-06-03 14:57 UTC (permalink / raw)
  To: linux-arm-kernel

Also convert MCT to the new local timers API.

Cc: Kukjin Kim <kgene.kim@samsung.com>
Cc: Changhwan Youn <chaos.youn@samsung.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm/mach-exynos4/Makefile     |    1 -
 arch/arm/mach-exynos4/localtimer.c |   26 --------------------------
 arch/arm/mach-exynos4/mct.c        |   17 +++++++++++++++--
 arch/arm/mach-exynos4/time.c       |   12 ++++++++++++
 4 files changed, 27 insertions(+), 29 deletions(-)
 delete mode 100644 arch/arm/mach-exynos4/localtimer.c

diff --git a/arch/arm/mach-exynos4/Makefile b/arch/arm/mach-exynos4/Makefile
index a9bb94f..6a0152e 100644
--- a/arch/arm/mach-exynos4/Makefile
+++ b/arch/arm/mach-exynos4/Makefile
@@ -24,7 +24,6 @@ ifeq ($(CONFIG_EXYNOS4_MCT),y)
 obj-y				+= mct.o
 else
 obj-y				+= time.o
-obj-$(CONFIG_LOCAL_TIMERS)	+= localtimer.o
 endif
 
 obj-$(CONFIG_HOTPLUG_CPU)	+= hotplug.o
diff --git a/arch/arm/mach-exynos4/localtimer.c b/arch/arm/mach-exynos4/localtimer.c
deleted file mode 100644
index 6184e29..0000000
--- a/arch/arm/mach-exynos4/localtimer.c
+++ /dev/null
@@ -1,26 +0,0 @@
-/* linux/arch/arm/mach-exynos4/localtimer.c
- *
- * Cloned from linux/arch/arm/mach-realview/localtimer.c
- *
- *  Copyright (C) 2002 ARM Ltd.
- *  All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/clockchips.h>
-
-#include <asm/irq.h>
-#include <asm/localtimer.h>
-#include <asm/hardware/gic.h>
-
-/*
- * Setup the local clock events for a CPU.
- */
-int __cpuinit local_timer_setup(struct clock_event_device *evt)
-{
-	evt->irq = gic_ppi_to_vppi(IRQ_LOCALTIMER);
-	return 0;
-}
diff --git a/arch/arm/mach-exynos4/mct.c b/arch/arm/mach-exynos4/mct.c
index 1a30278..f05e2e1 100644
--- a/arch/arm/mach-exynos4/mct.c
+++ b/arch/arm/mach-exynos4/mct.c
@@ -319,7 +319,7 @@ static inline void exynos4_tick_set_mode(enum clock_event_mode mode,
 	}
 }
 
-int local_timer_ack(void)
+static int exynos4_mct_timer_ack(void)
 {
 	unsigned int cpu = smp_processor_id();
 	struct mct_clock_event_device *mevt = &mct_tick[cpu];
@@ -339,7 +339,7 @@ int local_timer_ack(void)
 	return 1;
 }
 
-int __cpuinit local_timer_setup(struct clock_event_device *evt)
+static int __cpuinit exynos4_mct_timer_setup(struct clock_event_device *evt)
 {
 	unsigned int cpu = smp_processor_id();
 	int err = 0;
@@ -389,6 +389,18 @@ int __cpuinit local_timer_setup(struct clock_event_device *evt)
 
 	return err;
 }
+
+static struct local_timer_ops exynos4_mct_ops = {
+	.setup	= exynos4_mct_timer_setup,
+	.ack	= exynos4_mct_timer_ack,
+};
+
+#define exynos4_mct_ops_ptr	(&exynos4_mct_ops)
+
+#else
+
+#define exynos4_mct_ops_ptr	NULL
+
 #endif /* CONFIG_LOCAL_TIMERS */
 
 static void __init exynos4_timer_resources(void)
@@ -404,6 +416,7 @@ static void __init exynos4_timer_init(void)
 	exynos4_timer_resources();
 	exynos4_clocksource_init();
 	exynos4_clockevent_init();
+	percpu_timer_register(exynos4_mct_ops_ptr);
 }
 
 struct sys_timer exynos4_timer = {
diff --git a/arch/arm/mach-exynos4/time.c b/arch/arm/mach-exynos4/time.c
index 86b9fa0..40e585f 100644
--- a/arch/arm/mach-exynos4/time.c
+++ b/arch/arm/mach-exynos4/time.c
@@ -19,9 +19,12 @@
 #include <linux/clockchips.h>
 #include <linux/platform_device.h>
 
+#include <asm/localtimer.h>
 #include <asm/smp_twd.h>
+#include <asm/hardware/gic.h>
 
 #include <mach/map.h>
+#include <mach/irqs.h>
 #include <plat/regs-timer.h>
 #include <asm/mach/time.h>
 
@@ -283,10 +286,19 @@ static void __init exynos4_timer_resources(void)
 	clk_enable(tin4);
 }
 
+#ifdef CONFIG_LOCAL_TIMERS
+static int __cpuinit exynos4_local_timer_setup(struct clock_event_device *evt)
+{
+	evt->irq = gic_ppi_to_vppi(IRQ_LOCALTIMER);
+	return 0;
+}
+#endif
+
 static void __init exynos4_timer_init(void)
 {
 #ifdef CONFIG_LOCAL_TIMERS
 	twd_base = S5P_VA_TWD;
+	twd_timer_register_setup(exynos4_local_timer_setup);
 #endif
 
 	exynos4_timer_resources();
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v1 14/18] ARM: shmobile: dynamically register local timer setup function
  2011-06-03 14:57 [PATCH v1 00/18] Allow local timers to be registered at runtime Marc Zyngier
                   ` (12 preceding siblings ...)
  2011-06-03 14:57 ` [PATCH v1 13/18] ARM: exynos4: " Marc Zyngier
@ 2011-06-03 14:57 ` Marc Zyngier
  2011-06-03 14:57 ` [PATCH v1 15/18] ARM: tegra: " Marc Zyngier
                   ` (3 subsequent siblings)
  17 siblings, 0 replies; 19+ messages in thread
From: Marc Zyngier @ 2011-06-03 14:57 UTC (permalink / raw)
  To: linux-arm-kernel

Cc: Paul Mundt <lethal@linux-sh.org>
Cc: Magnus Damm <magnus.damm@gmail.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm/mach-shmobile/Makefile     |    1 -
 arch/arm/mach-shmobile/localtimer.c |   26 --------------------------
 arch/arm/mach-shmobile/timer.c      |   16 +++++++++++++++-
 3 files changed, 15 insertions(+), 28 deletions(-)
 delete mode 100644 arch/arm/mach-shmobile/localtimer.c

diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile
index 612b270..82ec6e9 100644
--- a/arch/arm/mach-shmobile/Makefile
+++ b/arch/arm/mach-shmobile/Makefile
@@ -14,7 +14,6 @@ obj-$(CONFIG_ARCH_SH73A0)	+= setup-sh73a0.o clock-sh73a0.o intc-sh73a0.o
 # SMP objects
 smp-y				:= platsmp.o headsmp.o
 smp-$(CONFIG_HOTPLUG_CPU)	+= hotplug.o
-smp-$(CONFIG_LOCAL_TIMERS)	+= localtimer.o
 smp-$(CONFIG_ARCH_SH73A0)	+= smp-sh73a0.o
 
 # Pinmux setup
diff --git a/arch/arm/mach-shmobile/localtimer.c b/arch/arm/mach-shmobile/localtimer.c
deleted file mode 100644
index e09fdd1..0000000
--- a/arch/arm/mach-shmobile/localtimer.c
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * SMP support for R-Mobile / SH-Mobile - local timer portion
- *
- * Copyright (C) 2010  Magnus Damm
- *
- * Based on vexpress, Copyright (C) 2002 ARM Ltd, All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <linux/init.h>
-#include <linux/smp.h>
-#include <linux/clockchips.h>
-#include <asm/smp_twd.h>
-#include <asm/localtimer.h>
-#include <asm/hardware/gic.h>
-
-/*
- * Setup the local clock events for a CPU.
- */
-int __cpuinit local_timer_setup(struct clock_event_device *evt)
-{
-	evt->irq = gic_ppi_to_vppi(29);
-	return 0;
-}
diff --git a/arch/arm/mach-shmobile/timer.c b/arch/arm/mach-shmobile/timer.c
index 835baa4..0d23fa3 100644
--- a/arch/arm/mach-shmobile/timer.c
+++ b/arch/arm/mach-shmobile/timer.c
@@ -19,6 +19,9 @@
  *
  */
 #include <linux/platform_device.h>
+#include <asm/localtimer.h>
+#include <asm/smp_twd.h>
+#include <asm/hardware/gic.h>
 #include <asm/mach/time.h>
 
 static void __init shmobile_late_time_init(void)
@@ -36,9 +39,20 @@ static void __init shmobile_late_time_init(void)
 	early_platform_driver_probe("earlytimer", 2, 0);
 }
 
+#ifdef CONFIG_LOCAL_TIMERS
+static int __cpuinit shmobile_local_timer_setup(struct clock_event_device *evt)
+{
+	evt->irq = gic_ppi_to_vppi(29);
+	return 0;
+}
+#else
+#define shmobile_local_timer_setup	NULL
+#endif
+
 static void __init shmobile_timer_init(void)
 {
-	arm_late_time_init = shmobile_late_time_init;
+	twd_timer_register_setup(shmobile_local_timer_setup);
+	late_time_init = shmobile_late_time_init;
 }
 
 struct sys_timer shmobile_timer = {
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v1 15/18] ARM: tegra: dynamically register local timer setup function
  2011-06-03 14:57 [PATCH v1 00/18] Allow local timers to be registered at runtime Marc Zyngier
                   ` (13 preceding siblings ...)
  2011-06-03 14:57 ` [PATCH v1 14/18] ARM: shmobile: " Marc Zyngier
@ 2011-06-03 14:57 ` Marc Zyngier
  2011-06-03 14:57 ` [PATCH v1 16/18] ARM: ux500: " Marc Zyngier
                   ` (2 subsequent siblings)
  17 siblings, 0 replies; 19+ messages in thread
From: Marc Zyngier @ 2011-06-03 14:57 UTC (permalink / raw)
  To: linux-arm-kernel

Cc: Colin Cross <ccross@android.com>
Cc: Erik Gilling <konkers@android.com>
Cc: Olof Johansson <olof@lixom.net>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm/mach-tegra/Makefile     |    2 +-
 arch/arm/mach-tegra/localtimer.c |   25 -------------------------
 arch/arm/mach-tegra/timer.c      |   12 ++++++++++++
 3 files changed, 13 insertions(+), 26 deletions(-)
 delete mode 100644 arch/arm/mach-tegra/localtimer.c

diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile
index 823c703..efbddfc 100644
--- a/arch/arm/mach-tegra/Makefile
+++ b/arch/arm/mach-tegra/Makefile
@@ -12,7 +12,7 @@ obj-$(CONFIG_ARCH_TEGRA_2x_SOC)         += clock.o
 obj-$(CONFIG_ARCH_TEGRA_2x_SOC)         += tegra2_clocks.o
 obj-$(CONFIG_ARCH_TEGRA_2x_SOC)		+= tegra2_emc.o
 obj-$(CONFIG_ARCH_TEGRA_2x_SOC)		+= pinmux-t2-tables.o
-obj-$(CONFIG_SMP)                       += platsmp.o localtimer.o headsmp.o
+obj-$(CONFIG_SMP)                       += platsmp.o headsmp.o
 obj-$(CONFIG_HOTPLUG_CPU)               += hotplug.o
 obj-$(CONFIG_TEGRA_SYSTEM_DMA)		+= dma.o
 obj-$(CONFIG_CPU_FREQ)                  += cpu-tegra.o
diff --git a/arch/arm/mach-tegra/localtimer.c b/arch/arm/mach-tegra/localtimer.c
deleted file mode 100644
index 590f1cc..0000000
--- a/arch/arm/mach-tegra/localtimer.c
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- *  arch/arm/mach-tegra/localtimer.c
- *
- *  Copyright (C) 2002 ARM Ltd.
- *  All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <linux/init.h>
-#include <linux/clockchips.h>
-
-#include <asm/irq.h>
-#include <asm/localtimer.h>
-#include <asm/hardware/gic.h>
-
-/*
- * Setup the local clock events for a CPU.
- */
-int __cpuinit local_timer_setup(struct clock_event_device *evt)
-{
-	evt->irq = gic_ppi_to_vppi(IRQ_LOCALTIMER);
-	return 0;
-}
diff --git a/arch/arm/mach-tegra/timer.c b/arch/arm/mach-tegra/timer.c
index 9035042..da30fdd 100644
--- a/arch/arm/mach-tegra/timer.c
+++ b/arch/arm/mach-tegra/timer.c
@@ -30,7 +30,9 @@
 
 #include <asm/mach/time.h>
 #include <asm/localtimer.h>
+#include <asm/smp_twd.h>
 #include <asm/sched_clock.h>
+#include <asm/hardware/gic.h>
 
 #include <mach/iomap.h>
 #include <mach/irqs.h>
@@ -179,6 +181,14 @@ static struct irqaction tegra_timer_irq = {
 	.irq		= INT_TMR3,
 };
 
+#ifdef CONFIG_HAVE_ARM_TWD
+static int __cpuinit tegra_local_timer_setup(struct clock_event_device *evt)
+{
+	evt->irq = gic_ppi_to_vppi(IRQ_LOCALTIMER);
+	return 0;
+}
+#endif
+
 static void __init tegra_init_timer(void)
 {
 	struct clk *clk;
@@ -199,6 +209,8 @@ static void __init tegra_init_timer(void)
 
 #ifdef CONFIG_HAVE_ARM_TWD
 	twd_base = IO_ADDRESS(TEGRA_ARM_PERIF_BASE + 0x600);
+
+	twd_timer_register_setup(tegra_local_timer_setup);
 #endif
 
 	switch (rate) {
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v1 16/18] ARM: ux500: dynamically register local timer setup function
  2011-06-03 14:57 [PATCH v1 00/18] Allow local timers to be registered at runtime Marc Zyngier
                   ` (14 preceding siblings ...)
  2011-06-03 14:57 ` [PATCH v1 15/18] ARM: tegra: " Marc Zyngier
@ 2011-06-03 14:57 ` Marc Zyngier
  2011-06-03 14:57 ` [PATCH v1 17/18] ARM: simplify percpu_timer_setup Marc Zyngier
  2011-06-03 14:57 ` [PATCH v1 18/18] ARM: simplify percpu_timer_ack Marc Zyngier
  17 siblings, 0 replies; 19+ messages in thread
From: Marc Zyngier @ 2011-06-03 14:57 UTC (permalink / raw)
  To: linux-arm-kernel

Cc: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com>
Cc: Linus Walleij <linus.walleij@stericsson.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm/mach-ux500/Makefile     |    1 -
 arch/arm/mach-ux500/cpu.c        |   14 ++++++++++++++
 arch/arm/mach-ux500/localtimer.c |   27 ---------------------------
 3 files changed, 14 insertions(+), 28 deletions(-)
 delete mode 100644 arch/arm/mach-ux500/localtimer.c

diff --git a/arch/arm/mach-ux500/Makefile b/arch/arm/mach-ux500/Makefile
index 1694916..2e30a80 100644
--- a/arch/arm/mach-ux500/Makefile
+++ b/arch/arm/mach-ux500/Makefile
@@ -14,7 +14,6 @@ obj-$(CONFIG_MACH_U8500)	+= board-mop500.o board-mop500-sdi.o \
 obj-$(CONFIG_MACH_U5500)	+= board-u5500.o board-u5500-sdi.o
 obj-$(CONFIG_SMP)		+= platsmp.o headsmp.o
 obj-$(CONFIG_HOTPLUG_CPU)	+= hotplug.o
-obj-$(CONFIG_LOCAL_TIMERS)	+= localtimer.o
 obj-$(CONFIG_U5500_MODEM_IRQ)	+= modem-irq-db5500.o
 obj-$(CONFIG_U5500_MBOX)	+= mbox-db5500.o
 
diff --git a/arch/arm/mach-ux500/cpu.c b/arch/arm/mach-ux500/cpu.c
index 1da23bb..64e2aae 100644
--- a/arch/arm/mach-ux500/cpu.c
+++ b/arch/arm/mach-ux500/cpu.c
@@ -8,6 +8,7 @@
 #include <linux/platform_device.h>
 #include <linux/io.h>
 #include <linux/clk.h>
+#include <linux/clockchips.h>
 #include <linux/mfd/db8500-prcmu.h>
 #include <linux/mfd/db5500-prcmu.h>
 
@@ -15,7 +16,10 @@
 #include <asm/hardware/cache-l2x0.h>
 #include <asm/hardware/gic.h>
 #include <asm/mach/map.h>
+#include <asm/irq.h>
 #include <asm/localtimer.h>
+#include <asm/smp_twd.h>
+#include <asm/hardware/gic.h>
 
 #include <plat/mtu.h>
 #include <mach/hardware.h>
@@ -120,6 +124,14 @@ static int ux500_l2x0_init(void)
 early_initcall(ux500_l2x0_init);
 #endif
 
+#ifdef CONFIG_LOCAL_TIMERS
+static int __cpuinit ux500_local_timer_setup(struct clock_event_device *evt)
+{
+	evt->irq = gic_ppi_to_vppi(IRQ_LOCALTIMER);
+	return 0;
+}
+#endif
+
 static void __init ux500_timer_init(void)
 {
 #ifdef CONFIG_LOCAL_TIMERS
@@ -130,6 +142,8 @@ static void __init ux500_timer_init(void)
 		twd_base = __io_address(U8500_TWD_BASE);
 	else
 		ux500_unknown_soc();
+
+	twd_timer_register_setup(ux500_local_timer_setup);
 #endif
 	if (cpu_is_u5500())
 		mtu_base = __io_address(U5500_MTU0_BASE);
diff --git a/arch/arm/mach-ux500/localtimer.c b/arch/arm/mach-ux500/localtimer.c
deleted file mode 100644
index 2697f4e..0000000
--- a/arch/arm/mach-ux500/localtimer.c
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2008-2009 ST-Ericsson
- * Srinidhi Kasagar <srinidhi.kasagar@stericsson.com>
- *
- * This file is heavily based on relaview platform, almost a copy.
- *
- * Copyright (C) 2002 ARM Ltd.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#include <linux/init.h>
-#include <linux/clockchips.h>
-
-#include <asm/irq.h>
-#include <asm/localtimer.h>
-#include <asm/hardware/gic.h>
-
-/*
- * Setup the local clock events for a CPU.
- */
-int __cpuinit local_timer_setup(struct clock_event_device *evt)
-{
-	evt->irq = gic_ppi_to_vppi(IRQ_LOCALTIMER);
-	return 0;
-}
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v1 17/18] ARM: simplify percpu_timer_setup
  2011-06-03 14:57 [PATCH v1 00/18] Allow local timers to be registered at runtime Marc Zyngier
                   ` (15 preceding siblings ...)
  2011-06-03 14:57 ` [PATCH v1 16/18] ARM: ux500: " Marc Zyngier
@ 2011-06-03 14:57 ` Marc Zyngier
  2011-06-03 14:57 ` [PATCH v1 18/18] ARM: simplify percpu_timer_ack Marc Zyngier
  17 siblings, 0 replies; 19+ messages in thread
From: Marc Zyngier @ 2011-06-03 14:57 UTC (permalink / raw)
  To: linux-arm-kernel

Now that all in-tree providers of local_timer_setup() are dynamically
registering their timers with the per cpu timer code, remove the
legacy timer selection code.

If no local timer is provided, a broadcast timer will be used
as a fallback.

Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm/include/asm/localtimer.h |    5 -----
 arch/arm/include/asm/smp_twd.h    |    8 +-------
 arch/arm/kernel/percpu_timer.c    |   20 +-------------------
 arch/arm/kernel/smp_twd.c         |   12 ++----------
 4 files changed, 4 insertions(+), 41 deletions(-)

diff --git a/arch/arm/include/asm/localtimer.h b/arch/arm/include/asm/localtimer.h
index f95e527..263c1cf 100644
--- a/arch/arm/include/asm/localtimer.h
+++ b/arch/arm/include/asm/localtimer.h
@@ -44,11 +44,6 @@ struct local_timer_ops {
 
 #ifdef CONFIG_LOCAL_TIMERS
 /*
- * Setup a local timer interrupt for a CPU.
- */
-int local_timer_setup(struct clock_event_device *);
-
-/*
  * Register a local timer.
  */
 void percpu_timer_register(struct local_timer_ops *);
diff --git a/arch/arm/include/asm/smp_twd.h b/arch/arm/include/asm/smp_twd.h
index d2abe52..2c01220 100644
--- a/arch/arm/include/asm/smp_twd.h
+++ b/arch/arm/include/asm/smp_twd.h
@@ -23,15 +23,9 @@
 extern void __iomem *twd_base;
 
 #ifdef CONFIG_HAVE_ARM_TWD
-struct local_timer_ops *local_timer_get_twd_ops(void);
 int twd_timer_register_setup(int (*setup)(struct clock_event_device *));
 #else
-static inline struct local_timer_ops *local_timer_get_twd_ops(void)
-{
-	return NULL;
-}
-
-static inline int twd_timer_register_setup(int (*setup)(struct clock_event_device *))
+static inline int twd_timer_register_setup(void (*setup)(struct clock_event_device *))
 {
 	return -ENODEV;
 }
diff --git a/arch/arm/kernel/percpu_timer.c b/arch/arm/kernel/percpu_timer.c
index 94315f5..f442d3f 100644
--- a/arch/arm/kernel/percpu_timer.c
+++ b/arch/arm/kernel/percpu_timer.c
@@ -15,7 +15,6 @@
 #include <linux/clockchips.h>
 
 #include <asm/localtimer.h>
-#include <asm/smp_twd.h>
 
 #ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
 static void broadcast_timer_set_mode(enum clock_event_mode mode,
@@ -45,12 +44,7 @@ static struct local_timer_ops broadcast_timer_ops = {
 	.setup	= broadcast_timer_setup,
 };
 
-static struct local_timer_ops *timer_ops;
-
-int __attribute__ ((weak)) local_timer_setup(struct clock_event_device *evt)
-{
-	return -ENXIO;
-}
+static struct local_timer_ops *timer_ops = &broadcast_timer_ops;
 
 void percpu_timer_register(struct local_timer_ops *ops)
 {
@@ -108,18 +102,6 @@ void __cpuinit percpu_timer_setup(void)
 	unsigned int cpu = smp_processor_id();
 	struct clock_event_device *evt = &per_cpu(percpu_clockevent, cpu);
 
-	/*
-	 * All this can go away once we've migrated all users to
-	 * properly register the timer they use, and broadcast can
-	 * become the fallback.
-	 */
-	if (!timer_ops)
-		timer_ops = local_timer_get_twd_ops();
-	if (!timer_ops)
-		timer_ops = &broadcast_timer_ops;
-	if (!timer_ops->plat_setup)
-		timer_ops->plat_setup = local_timer_setup;
-
 	evt->cpumask = cpumask_of(cpu);
 
 	if (timer_ops->pre_setup)
diff --git a/arch/arm/kernel/smp_twd.c b/arch/arm/kernel/smp_twd.c
index 91296df..5773955 100644
--- a/arch/arm/kernel/smp_twd.c
+++ b/arch/arm/kernel/smp_twd.c
@@ -168,20 +168,12 @@ static struct local_timer_ops twd_timer_ops = {
 	.ack		= twd_timer_ack,
 };
 
-struct local_timer_ops *local_timer_get_twd_ops(void)
+int __init twd_timer_register_setup(int (*setup)(struct clock_event_device *))
 {
 	if (!twd_base) {
 		pr_warn("TWD base address not set\n");
-		return NULL;
-	}
-
-	return &twd_timer_ops;
-}
-
-int __init twd_timer_register_setup(int (*setup)(struct clock_event_device *))
-{
-	if (!twd_base)
 		return -ENODEV;
+	}
 
 	percpu_timer_register_setup(&twd_timer_ops, setup, NULL);
 	return 0;
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [PATCH v1 18/18] ARM: simplify percpu_timer_ack
  2011-06-03 14:57 [PATCH v1 00/18] Allow local timers to be registered at runtime Marc Zyngier
                   ` (16 preceding siblings ...)
  2011-06-03 14:57 ` [PATCH v1 17/18] ARM: simplify percpu_timer_setup Marc Zyngier
@ 2011-06-03 14:57 ` Marc Zyngier
  17 siblings, 0 replies; 19+ messages in thread
From: Marc Zyngier @ 2011-06-03 14:57 UTC (permalink / raw)
  To: linux-arm-kernel

There is no provider of local_timer_ack anymore after the conversion
of msm to the percpu_timer interface. Remove the weak local_timer_ack
symbol and directly call percpu_timer_ack.

Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm/kernel/percpu_timer.c |    8 +-------
 1 files changed, 1 insertions(+), 7 deletions(-)

diff --git a/arch/arm/kernel/percpu_timer.c b/arch/arm/kernel/percpu_timer.c
index f442d3f..da796cb 100644
--- a/arch/arm/kernel/percpu_timer.c
+++ b/arch/arm/kernel/percpu_timer.c
@@ -56,10 +56,6 @@ void percpu_timer_register(struct local_timer_ops *ops)
  *
  * If a local timer interrupt has occurred, acknowledge and return 1.
  * Otherwise, return 0.
- *
- * This can be overloaded by platform code that doesn't provide its
- * timer in timer_fns way (msm at the moment). Once all platforms have
- * migrated, the weak alias can be removed.
  * If no ack() function has been registered, consider the acknowledgement
  * to be done.
  */
@@ -71,8 +67,6 @@ static int percpu_timer_ack(void)
 	return 1;
 }
 
-int local_timer_ack(void) __attribute__ ((weak, alias("percpu_timer_ack")));
-
 /*
  * Timer (local or broadcast) support
  */
@@ -82,7 +76,7 @@ irqreturn_t percpu_timer_handler(int irq, void *dev_id)
 {
 	struct clock_event_device *evt = dev_id;
 
-	if (local_timer_ack()) {
+	if (percpu_timer_ack()) {
 		evt->event_handler(evt);
 		return IRQ_HANDLED;
 	}
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2011-06-03 14:57 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-06-03 14:57 [PATCH v1 00/18] Allow local timers to be registered at runtime Marc Zyngier
2011-06-03 14:57 ` [PATCH v1 01/18] ARM: Move local timer support out of smp.c Marc Zyngier
2011-06-03 14:57 ` [PATCH v1 02/18] ARM: local timers: Add runtime registration interface Marc Zyngier
2011-06-03 14:57 ` [PATCH v1 03/18] ARM: omap2: remove stubbed twd_timer_setup call Marc Zyngier
2011-06-03 14:57 ` [PATCH v1 04/18] ARM: exynos4: " Marc Zyngier
2011-06-03 14:57 ` [PATCH v1 05/18] ARM: shmobile: " Marc Zyngier
2011-06-03 14:57 ` [PATCH v1 06/18] ARM: tegra: " Marc Zyngier
2011-06-03 14:57 ` [PATCH v1 07/18] ARM: ux500: " Marc Zyngier
2011-06-03 14:57 ` [PATCH v1 08/18] ARM: versatile: " Marc Zyngier
2011-06-03 14:57 ` [PATCH v1 09/18] ARM: remove unused twd_timer_setup stub Marc Zyngier
2011-06-03 14:57 ` [PATCH v1 10/18] ARM: versatile/vexpress: dynamically register local timer setup function Marc Zyngier
2011-06-03 14:57 ` [PATCH v1 11/18] ARM: msm: dynamically register local timer Marc Zyngier
2011-06-03 14:57 ` [PATCH v1 12/18] ARM: omap4: dynamically register local timer setup function Marc Zyngier
2011-06-03 14:57 ` [PATCH v1 13/18] ARM: exynos4: " Marc Zyngier
2011-06-03 14:57 ` [PATCH v1 14/18] ARM: shmobile: " Marc Zyngier
2011-06-03 14:57 ` [PATCH v1 15/18] ARM: tegra: " Marc Zyngier
2011-06-03 14:57 ` [PATCH v1 16/18] ARM: ux500: " Marc Zyngier
2011-06-03 14:57 ` [PATCH v1 17/18] ARM: simplify percpu_timer_setup Marc Zyngier
2011-06-03 14:57 ` [PATCH v1 18/18] ARM: simplify percpu_timer_ack Marc Zyngier

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.