Skip to contentSkip to conversation

Remove ARM local timer API

PATCH Superseded Stephen Boyd 6 participants 24 messages May 13, 2013 – Jun 3, 2013

Subsystems (14)

v6 of 7 Superseded Latest is v7 →

lore
Share & tools
lore
#0 lore raw

v6 cover Remove ARM local timer API

In light of Mark Rutland's recent work on divorcing the ARM architected timers from the ARM local timer API and introducing a generic arch hook for broadcast it seems that we should remove the local timer API entirely. Doing so will reduce the architecture dependencies of our timer drivers, reduce code in ARM core, and simplify timer drivers because they no longer go through an architecture layer that is essentially a hotplug notifier.

Previous attempts have been made[1] unsuccessfully. I'm hoping this can be accepted now so that we can clean up the timer drivers that are used in both UP and SMP situations. Right now these drivers have to ignore the timer setup callback on the boot CPU to avoid registering clockevents twice. This is not very symmetric and causes convuluted code that does the same thing in two places.

Patches based on next-20130418

I'm still looking for Acks/Tested-by on EXYNOS and PRIMA2.

[1] http://article.gmane.org/gmane.linux.ports.arm.kernel/145705

Note: A hotplug notifier is used by both x86 for the apb_timer (see apbt_cpuhp_notify) and by metag (see arch_timer_cpu_notify in metag_generic.c) so this is not new.

Changes since v5:
* Rebased onto v3.10-rc1
* Rebase caused minor updates to mct patch

Changes since v4:
* Rebased onto next-20130418
* Rebase caused minor updates to mct patch and twd Kconfig

Changes since v3:
* New patch to fix SMP with dummy timers registered after a global timer
* Push this_cpu_ptr lower to avoid preemptible false positive warnings
* Collected acks/tested-bys

Changes since v2:
* Bug fixes in smp_twd from Tony Lindgren's testing
* Move smp_twd to use late_time_init hook
* Collected Acks

Changes since v1:
* Picked up Mark's generic dummy timer driver
* Split out omap changes into new patch

Mark Rutland (1):
clocksource: add generic dummy timer driver

Stephen Boyd (10):
clockevents: Prefer CPU local devices over global devices
ARM: smp: Remove duplicate dummy timer implementation
ARM: smp_twd: Divorce smp_twd from local timer API
ARM: OMAP2+: Divorce from local timer API
ARM: EXYNOS4: Divorce mct from local timer API
ARM: PRIMA2: Divorce timer-marco from local timer API
ARM: msm: Divorce msm_timer from local timer API
clocksource: time-armada-370-xp: Fix sparse warning
clocksource: time-armada-370-xp: Divorce from local timer API
ARM: smp: Remove local timer API

 arch/arm/Kconfig                         |  12 +--
 arch/arm/include/asm/localtimer.h        |  34 ---------
 arch/arm/kernel/smp.c                    |  87 ---------------------
 arch/arm/kernel/smp_twd.c                |  64 ++++++++++------
 arch/arm/mach-highbank/Kconfig           |   2 +-
 arch/arm/mach-imx/Kconfig                |   2 +-
 arch/arm/mach-msm/timer.c                | 126 +++++++++++++++++--------------
 arch/arm/mach-omap2/Kconfig              |   3 +-
 arch/arm/mach-omap2/timer.c              |   7 --
 arch/arm/mach-realview/Kconfig           |   8 +-
 arch/arm/mach-spear/Kconfig              |   2 +-
 arch/arm/mach-tegra/Kconfig              |   2 +-
 arch/arm/mach-ux500/Kconfig              |   2 +-
 arch/arm/mach-vexpress/Kconfig           |   2 +-
 arch/arm/mach-zynq/Kconfig               |   2 +-
 drivers/clocksource/Makefile             |   1 +
 drivers/clocksource/dummy_timer.c        |  69 +++++++++++++++++
 drivers/clocksource/exynos_mct.c         |  60 ++++++++++-----
 drivers/clocksource/time-armada-370-xp.c |  92 +++++++++++-----------
 drivers/clocksource/timer-marco.c        | 100 +++++++++++++-----------
 include/linux/time-armada-370-xp.h       |   4 +-
 kernel/time/tick-common.c                |   5 +-
 22 files changed, 340 insertions(+), 346 deletions(-)
 delete mode 100644 arch/arm/include/asm/localtimer.h
 create mode 100644 drivers/clocksource/dummy_timer.c
Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation
#1 lore raw

PATCH v6 1/11 clockevents: Prefer CPU local devices over global devices

On an SMP system with only one global clockevent and a dummy clockevent per CPU we run into problems. We want the dummy clockevents to be registered as the per CPU tick devices, but we can only achieve that if we register the dummy clockevents before the global clockevent or if we artificially inflate the rating of the dummy clockevents to be higher than the rating of the global clockevent. Failure to do so leads to boot hangs when the dummy timers are registered on all other CPUs besides the CPU that accepted the global clockevent as its tick device and there is no broadcast timer to poke the dummy devices.

If we're registering multiple clockevents and one clockevent is global and the other is local to a particular CPU we should choose to use the local clockevent regardless of the rating of the device. This way, if the clockevent is a dummy it will take the tick device duty as long as there isn't a higher rated tick device and any global clockevent will be bumped out into broadcast mode, fixing the problem described above.

---
 kernel/time/tick-common.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
kernel/time/tick-common.c +3 -2
index 5d3fb10..3da62de 100644
@@ -254,9 +254,10 @@ static int tick_check_new_device(struct clock_event_device *newdev)
 		    !(newdev->features & CLOCK_EVT_FEAT_ONESHOT))
 			goto out_bc;
 		/*
-		 * Check the rating
+		 * Check the rating, but prefer CPU local devices
 		 */
-		if (curdev->rating >= newdev->rating)
+		if (curdev->rating >= newdev->rating &&
+		    cpumask_equal(curdev->cpumask, newdev->cpumask))
 			goto out_bc;
 	}
 
Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation
Tested-by on v6 1/11
#2 lore raw

Re: [PATCHv6 01/11] clockevents: Prefer CPU local devices over global devices

Quoted 20 lines · Stephen Boyd

On an SMP system with only one global clockevent and a dummy clockevent per CPU we run into problems. We want the dummy clockevents to be registered as the per CPU tick devices, but we can only achieve that if we register the dummy clockevents before the global clockevent or if we artificially inflate the rating of the dummy clockevents to be higher than the rating of the global clockevent. Failure to do so leads to boot hangs when the dummy timers are registered on all other CPUs besides the CPU that accepted the global clockevent as its tick device and there is no broadcast timer to poke the dummy devices.

If we're registering multiple clockevents and one clockevent is global and the other is local to a particular CPU we should choose to use the local clockevent regardless of the rating of the device. This way, if the clockevent is a dummy it will take the tick device duty as long as there isn't a higher rated tick device and any global clockevent will be bumped out into broadcast mode, fixing the problem described above.

Quoted 5 lines

I tested this on Zynq. Zynq uses the ARM twd timer as clockevent devices when available. When I remove the twd nodes from DT the clockevent device is a timer common to both CPUs. Without this patch this seems to stall the second CPU resulting in the system to hang sooner or later.

[   65.360000] INFO: rcu_preempt detected stalls on CPUs/tasks:
[   65.360000]  1: (1 GPs behind) idle=56e/0/0 softirq=0/0 
[   65.360000]  (detected by 0, t=6502 jiffies, g=4294966997, c=4294966996, q=6844)
[   65.360000] Task dump for CPU 1:
[   65.360000] swapper/1       R running      0     0      1 0x00000000

With this patch everything looks fine.

S?ren

#3 lore raw

PATCH v6 2/11 clocksource: add generic dummy timer driver

In reply to Stephen Boyd

From: Mark Rutland <[email protected]>

Several architectures have a dummy timer driver tightly coupled with their broadcast code to support machines without cpu-local timers (or where there is a lack of driver support).

Since 12ad100046: "clockevents: Add generic timer broadcast function" it's been possible to write broadcast-capable timer drivers decoupled from the broadcast mechanism. We can use this functionality to implement a generic dummy timer driver that can be shared by all architectures with generic tick broadcast (ARCH_HAS_TICK_BROADCAST).

This patch implements a generic dummy timer using this facility.

Cc John Stultz <[email protected]>
Cc Thomas Gleixner <[email protected]>

[sboyd: Make percpu data static, use __this_cpu_ptr(), move to
early_initcall to properly register on each CPU, only register if more than one CPU possible]

---
 drivers/clocksource/Makefile      |  1 +
 drivers/clocksource/dummy_timer.c | 69 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 70 insertions(+)
 create mode 100644 drivers/clocksource/dummy_timer.c
drivers/clocksource/Makefile +1 -0
index 8d979c7..1a17d76 100644
@@ -29,3 +29,4 @@ obj-$(CONFIG_CLKSRC_SAMSUNG_PWM)	+= samsung_pwm_timer.o
 
 obj-$(CONFIG_ARM_ARCH_TIMER)		+= arm_arch_timer.o
 obj-$(CONFIG_CLKSRC_METAG_GENERIC)	+= metag_generic.o
+obj-$(CONFIG_ARCH_HAS_TICK_BROADCAST)	+= dummy_timer.o
drivers/clocksource/dummy_timer.c new file +69 -0

69 lines not on this page · raw message

Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation
#4 lore raw

PATCH v6 3/11 ARM: smp: Remove duplicate dummy timer implementation

In reply to Stephen Boyd

Drop ARM's version of the dummy timer now that we have a generic implementation in drivers/clocksource.

---
 arch/arm/kernel/smp.c | 22 ++--------------------
 1 file changed, 2 insertions(+), 20 deletions(-)
arch/arm/kernel/smp.c +2 -20
index 47ab905..4dc883a 100644
@@ -503,24 +503,6 @@ void tick_broadcast(const struct cpumask *mask)
 }
 #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	= 100;
-	evt->mult	= 1;
-	evt->set_mode	= broadcast_timer_set_mode;
-
-	clockevents_register_device(evt);
-}
-
 static struct local_timer_ops *lt_ops;
 
 #ifdef CONFIG_LOCAL_TIMERS
@@ -544,8 +526,8 @@ static void __cpuinit percpu_timer_setup(void)
 
 	evt->cpumask = cpumask_of(cpu);
 
-	if (!lt_ops || lt_ops->setup(evt))
-		broadcast_timer_setup(evt);
+	if (lt_ops)
+		lt_ops->setup(evt);
 }
 
 #ifdef CONFIG_HOTPLUG_CPU
Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation
#5 lore raw

Re: [PATCHv6 03/11] ARM: smp: Remove duplicate dummy timer implementation

Quoted 5 lines · Stephen Boyd

Drop ARM's version of the dummy timer now that we have a generic implementation in drivers/clocksource.

Russell, can you please ack this patch and patch #11?

Quoted 44 lines
---
 arch/arm/kernel/smp.c | 22 ++--------------------
 1 file changed, 2 insertions(+), 20 deletions(-)
arch/arm/kernel/smp.c +2 -20
index 47ab905..4dc883a 100644
@@ -503,24 +503,6 @@ void tick_broadcast(const struct cpumask *mask)
 }
 #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	= 100;
-	evt->mult	= 1;
-	evt->set_mode	= broadcast_timer_set_mode;
-
-	clockevents_register_device(evt);
-}
-
 static struct local_timer_ops *lt_ops;
 
 #ifdef CONFIG_LOCAL_TIMERS
@@ -544,8 +526,8 @@ static void __cpuinit percpu_timer_setup(void)
 
 	evt->cpumask = cpumask_of(cpu);
 
-	if (!lt_ops || lt_ops->setup(evt))
-		broadcast_timer_setup(evt);
+	if (lt_ops)
+		lt_ops->setup(evt);
 }
 
 #ifdef CONFIG_HOTPLUG_CPU
Signature · 2 lines
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation
#6 lore raw

PATCH v6 4/11 ARM: smp_twd: Divorce smp_twd from local timer API

In reply to Stephen Boyd

Separate the smp_twd timers from the local timer API. This will allow us to remove ARM local timer support in the near future and gets us closer to moving this driver to drivers/clocksource.

---
 arch/arm/Kconfig               |  2 +-
 arch/arm/kernel/smp_twd.c      | 64 ++++++++++++++++++++++++++++--------------
 arch/arm/mach-highbank/Kconfig |  2 +-
 arch/arm/mach-imx/Kconfig      |  2 +-
 arch/arm/mach-omap2/Kconfig    |  2 +-
 arch/arm/mach-realview/Kconfig |  8 +++---
 arch/arm/mach-spear/Kconfig    |  2 +-
 arch/arm/mach-tegra/Kconfig    |  2 +-
 arch/arm/mach-ux500/Kconfig    |  2 +-
 arch/arm/mach-vexpress/Kconfig |  2 +-
 arch/arm/mach-zynq/Kconfig     |  2 +-
 11 files changed, 56 insertions(+), 34 deletions(-)
arch/arm/Kconfig +1 -1
index d423d58..177cb39 100644
@@ -636,7 +636,7 @@ config ARCH_SHMOBILE
 	select CLKDEV_LOOKUP
 	select GENERIC_CLOCKEVENTS
 	select HAVE_ARM_SCU if SMP
-	select HAVE_ARM_TWD if LOCAL_TIMERS
+	select HAVE_ARM_TWD if SMP
 	select HAVE_CLK
 	select HAVE_MACH_CLKDEV
 	select HAVE_SMP
arch/arm/kernel/smp_twd.c +43 -21

163 lines not on this page · raw message

arch/arm/mach-highbank/Kconfig +1 -1
index cd9fcb1..6acbdab 100644
@@ -12,7 +12,7 @@ config ARCH_HIGHBANK
 	select CPU_V7
 	select GENERIC_CLOCKEVENTS
 	select HAVE_ARM_SCU
-	select HAVE_ARM_TWD if LOCAL_TIMERS
+	select HAVE_ARM_TWD if SMP
 	select HAVE_SMP
 	select MAILBOX
 	select PL320_MBOX
arch/arm/mach-imx/Kconfig +1 -1
index ba44328..c8adc79 100644
@@ -798,7 +798,7 @@ config SOC_IMX6Q
 	select COMMON_CLK
 	select CPU_V7
 	select HAVE_ARM_SCU if SMP
-	select HAVE_ARM_TWD if LOCAL_TIMERS
+	select HAVE_ARM_TWD if SMP
 	select HAVE_CAN_FLEXCAN if CAN
 	select HAVE_IMX_ANATOP
 	select HAVE_IMX_GPC
arch/arm/mach-omap2/Kconfig +1 -1
index f49cd51..edb950a 100644
@@ -90,7 +90,7 @@ config ARCH_OMAP4
 	select CACHE_L2X0
 	select CPU_V7
 	select HAVE_ARM_SCU if SMP
-	select HAVE_ARM_TWD if LOCAL_TIMERS
+	select HAVE_ARM_TWD if SMP
 	select HAVE_SMP
 	select LOCAL_TIMERS if SMP
 	select OMAP_INTERCONNECT
arch/arm/mach-realview/Kconfig +4 -4
index d210c0f9..9db2029 100644
@@ -13,7 +13,7 @@ config REALVIEW_EB_A9MP
 	depends on MACH_REALVIEW_EB
 	select CPU_V7
 	select HAVE_ARM_SCU if SMP
-	select HAVE_ARM_TWD if LOCAL_TIMERS
+	select HAVE_ARM_TWD if SMP
 	select HAVE_SMP
 	select MIGHT_HAVE_CACHE_L2X0
 	help
@@ -26,7 +26,7 @@ config REALVIEW_EB_ARM11MP
 	select ARCH_HAS_BARRIERS if SMP
 	select CPU_V6K
 	select HAVE_ARM_SCU if SMP
-	select HAVE_ARM_TWD if LOCAL_TIMERS
+	select HAVE_ARM_TWD if SMP
 	select HAVE_SMP
 	select MIGHT_HAVE_CACHE_L2X0
 	help
@@ -48,7 +48,7 @@ config MACH_REALVIEW_PB11MP
 	select ARM_GIC
 	select CPU_V6K
 	select HAVE_ARM_SCU if SMP
-	select HAVE_ARM_TWD if LOCAL_TIMERS
+	select HAVE_ARM_TWD if SMP
 	select HAVE_PATA_PLATFORM
 	select HAVE_SMP
 	select MIGHT_HAVE_CACHE_L2X0
@@ -92,7 +92,7 @@ config MACH_REALVIEW_PBX
 	select ARCH_SPARSEMEM_ENABLE if CPU_V7 && !REALVIEW_HIGH_PHYS_OFFSET
 	select ARM_GIC
 	select HAVE_ARM_SCU if SMP
-	select HAVE_ARM_TWD if LOCAL_TIMERS
+	select HAVE_ARM_TWD if SMP
 	select HAVE_PATA_PLATFORM
 	select HAVE_SMP
 	select MIGHT_HAVE_CACHE_L2X0
arch/arm/mach-spear/Kconfig +1 -1
index 442917e..df0d59a 100644
@@ -23,7 +23,7 @@ config ARCH_SPEAR13XX
 	select CPU_V7
 	select GPIO_SPEAR_SPICS
 	select HAVE_ARM_SCU if SMP
-	select HAVE_ARM_TWD if LOCAL_TIMERS
+	select HAVE_ARM_TWD if SMP
 	select HAVE_SMP
 	select MIGHT_HAVE_CACHE_L2X0
 	select PINCTRL
arch/arm/mach-tegra/Kconfig +1 -1
index 84d72fc..1f3ea1f 100644
@@ -8,7 +8,7 @@ config ARCH_TEGRA
 	select COMMON_CLK
 	select GENERIC_CLOCKEVENTS
 	select HAVE_ARM_SCU if SMP
-	select HAVE_ARM_TWD if LOCAL_TIMERS
+	select HAVE_ARM_TWD if SMP
 	select HAVE_CLK
 	select HAVE_SMP
 	select MIGHT_HAVE_CACHE_L2X0
arch/arm/mach-ux500/Kconfig +1 -1
index 6a4387e..0614ee2 100644
@@ -8,7 +8,7 @@ config ARCH_U8500
 	select CPU_V7
 	select GENERIC_CLOCKEVENTS
 	select HAVE_ARM_SCU if SMP
-	select HAVE_ARM_TWD if LOCAL_TIMERS
+	select HAVE_ARM_TWD if SMP
 	select HAVE_SMP
 	select MIGHT_HAVE_CACHE_L2X0
 	help
arch/arm/mach-vexpress/Kconfig +1 -1
index 5907e10..5bfdd73 100644
@@ -10,7 +10,7 @@ config ARCH_VEXPRESS
 	select CPU_V7
 	select GENERIC_CLOCKEVENTS
 	select HAVE_ARM_SCU if SMP
-	select HAVE_ARM_TWD if LOCAL_TIMERS
+	select HAVE_ARM_TWD if SMP
 	select HAVE_CLK
 	select HAVE_PATA_PLATFORM
 	select HAVE_SMP
arch/arm/mach-zynq/Kconfig +1 -1
index c1d61f2..04f8a4a 100644
@@ -6,7 +6,7 @@ config ARCH_ZYNQ
 	select CPU_V7
 	select GENERIC_CLOCKEVENTS
 	select HAVE_ARM_SCU if SMP
-	select HAVE_ARM_TWD if LOCAL_TIMERS
+	select HAVE_ARM_TWD if SMP
 	select ICST
 	select MIGHT_HAVE_CACHE_L2X0
 	select USE_OF
Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation
#7 lore raw

PATCH v6 5/11 ARM: OMAP2+: Divorce from local timer API

In reply to Stephen Boyd

Now that the TWD doesn't rely on the local timer API, OMAP can stop selecting it in Kconfig and relying on the config option to decide if it should call smp_twd functions.

---
 arch/arm/mach-omap2/Kconfig | 1 -
 arch/arm/mach-omap2/timer.c | 7 -------
 2 files changed, 8 deletions(-)
arch/arm/mach-omap2/Kconfig +0 -1
index edb950a..4e0049a 100644
@@ -92,7 +92,6 @@ config ARCH_OMAP4
 	select HAVE_ARM_SCU if SMP
 	select HAVE_ARM_TWD if SMP
 	select HAVE_SMP
-	select LOCAL_TIMERS if SMP
 	select OMAP_INTERCONNECT
 	select PL310_ERRATA_588369
 	select PL310_ERRATA_727915
arch/arm/mach-omap2/timer.c +0 -7
index f8b23b8..60e9cf8 100644
@@ -600,7 +600,6 @@ static OMAP_SYS_32K_TIMER_INIT(4, 1, "timer_32k_ck", "ti,timer-alwon",
 #endif
 
 #ifdef CONFIG_ARCH_OMAP4
-#ifdef CONFIG_LOCAL_TIMERS
 static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, OMAP44XX_LOCAL_TWD_BASE, 29);
 void __init omap4_local_timer_init(void)
 {
@@ -619,12 +618,6 @@ void __init omap4_local_timer_init(void)
 			pr_err("twd_local_timer_register failed %d\n", err);
 	}
 }
-#else /* CONFIG_LOCAL_TIMERS */
-void __init omap4_local_timer_init(void)
-{
-	omap4_sync32k_timer_init();
-}
-#endif /* CONFIG_LOCAL_TIMERS */
 #endif /* CONFIG_ARCH_OMAP4 */
 
 #ifdef CONFIG_SOC_OMAP5
Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation
#8 lore raw

PATCH v6 6/11 ARM: EXYNOS4: Divorce mct from local timer API

In reply to Stephen Boyd

Separate the mct local timers from the local timer API. This will allow us to remove ARM local timer support in the near future and gets us closer to moving this driver to drivers/clocksource.

Cc Kukjin Kim <[email protected]>
Cc Thomas Abraham <[email protected]>
---
 drivers/clocksource/exynos_mct.c | 60 ++++++++++++++++++++++++++++------------
 1 file changed, 43 insertions(+), 17 deletions(-)
drivers/clocksource/exynos_mct.c +43 -17
index 662fcc0..1c3f5a6 100644
@@ -16,6 +16,7 @@
 #include <linux/err.h>
 #include <linux/clk.h>
 #include <linux/clockchips.h>
+#include <linux/cpu.h>
 #include <linux/platform_device.h>
 #include <linux/delay.h>
 #include <linux/percpu.h>
@@ -24,7 +25,6 @@
 #include <linux/of_address.h>
 #include <linux/clocksource.h>
 
-#include <asm/localtimer.h>
 #include <asm/mach/time.h>
 
 #define EXYNOS4_MCTREG(x)		(x)
@@ -80,7 +80,7 @@ static unsigned int mct_int_type;
 static int mct_irqs[MCT_NR_IRQS];
 
 struct mct_clock_event_device {
-	struct clock_event_device *evt;
+	struct clock_event_device evt;
 	unsigned long base;
 	char name[10];
 };
@@ -295,8 +295,6 @@ static void exynos4_clockevent_init(void)
 	setup_irq(mct_irqs[MCT_G0_IRQ], &mct_comp_event_irq);
 }
 
-#ifdef CONFIG_LOCAL_TIMERS
-
 static DEFINE_PER_CPU(struct mct_clock_event_device, percpu_mct_tick);
 
 /* Clock event handling */
@@ -369,7 +367,7 @@ static inline void exynos4_tick_set_mode(enum clock_event_mode mode,
 
 static int exynos4_mct_tick_clear(struct mct_clock_event_device *mevt)
 {
-	struct clock_event_device *evt = mevt->evt;
+	struct clock_event_device *evt = &mevt->evt;
 
 	/*
 	 * This is for supporting oneshot mode.
@@ -391,7 +389,7 @@ static int exynos4_mct_tick_clear(struct mct_clock_event_device *mevt)
 static irqreturn_t exynos4_mct_tick_isr(int irq, void *dev_id)
 {
 	struct mct_clock_event_device *mevt = dev_id;
-	struct clock_event_device *evt = mevt->evt;
+	struct clock_event_device *evt = &mevt->evt;
 
 	exynos4_mct_tick_clear(mevt);
 
@@ -417,8 +415,7 @@ static int __cpuinit exynos4_local_timer_setup(struct clock_event_device *evt)
 	struct mct_clock_event_device *mevt;
 	unsigned int cpu = smp_processor_id();
 
-	mevt = this_cpu_ptr(&percpu_mct_tick);
-	mevt->evt = evt;
+	mevt = container_of(evt, struct mct_clock_event_device, evt);
 
 	mevt->base = EXYNOS4_MCT_L_BASE(cpu);
 	sprintf(mevt->name, "mct_tick%d", cpu);
@@ -452,7 +449,7 @@ static int __cpuinit exynos4_local_timer_setup(struct clock_event_device *evt)
 	return 0;
 }
 
-static void exynos4_local_timer_stop(struct clock_event_device *evt)
+static void __cpuinit exynos4_local_timer_stop(struct clock_event_device *evt)
 {
 	unsigned int cpu = smp_processor_id();
 	evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt);
@@ -465,14 +462,37 @@ static void exynos4_local_timer_stop(struct clock_event_device *evt)
 		disable_percpu_irq(mct_irqs[MCT_L0_IRQ]);
 }
 
-static struct local_timer_ops exynos4_mct_tick_ops __cpuinitdata = {
-	.setup	= exynos4_local_timer_setup,
-	.stop	= exynos4_local_timer_stop,
+static int __cpuinit 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 = {
+	.notifier_call = exynos4_mct_cpu_notify,
 };
-#endif /* CONFIG_LOCAL_TIMERS */
 
 static void __init exynos4_timer_resources(struct device_node *np, void __iomem *base)
 {
+	int err;
+	struct mct_clock_event_device *mevt = this_cpu_ptr(&percpu_mct_tick);
 	struct clk *mct_clk, *tick_clk;
 
 	tick_clk = np ? of_clk_get_by_name(np, "fin_pll") :
@@ -490,9 +510,7 @@ static void __init exynos4_timer_resources(struct device_node *np, void __iomem
 	if (!reg_base)
 		panic("%s: unable to ioremap mct address space\n", __func__);
 
-#ifdef CONFIG_LOCAL_TIMERS
 	if (mct_int_type == MCT_INT_PPI) {
-		int err;
 
 		err = request_percpu_irq(mct_irqs[MCT_L0_IRQ],
 					 exynos4_mct_tick_isr, "MCT",
@@ -501,8 +519,16 @@ static void __init exynos4_timer_resources(struct device_node *np, void __iomem
 		     mct_irqs[MCT_L0_IRQ], err);
 	}
 
-	local_timer_register(&exynos4_mct_tick_ops);
-#endif /* CONFIG_LOCAL_TIMERS */
+	err = register_cpu_notifier(&exynos4_mct_cpu_nb);
+	if (err)
+		goto out_irq;
+
+	/* Immediately configure the timer on the boot CPU */
+	exynos4_local_timer_setup(&mevt->evt);
+	return;
+
+out_irq:
+	free_percpu_irq(mct_irqs[MCT_L0_IRQ], &percpu_mct_tick);
 }
 
 void __init mct_init(void __iomem *base, int irq_g0, int irq_l0, int irq_l1)
Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation
Acked-by on v6 6/11
#9 lore raw

RE: [PATCHv6 06/11] ARM: EXYNOS4: Divorce mct from local timer API

Quoted 6 lines · Stephen Boyd

Separate the mct local timers from the local timer API. This will allow us to remove ARM local timer support in the near future and gets us closer to moving this driver to drivers/clocksource.

Cc Kukjin Kim <[email protected]>

Looks good to me after looking at this series,

Sorry for late response :-)

Thanks for your gentle reminder.

- Kukjin

Quoted 135 lines
Cc Thomas Abraham <[email protected]>
---
 drivers/clocksource/exynos_mct.c | 60 ++++++++++++++++++++++++++++-------
-----
 1 file changed, 43 insertions(+), 17 deletions(-)
drivers/clocksource/exynos_mct.c +3 -5
index 662fcc0..1c3f5a6 100644
@@ -16,6 +16,7 @@
 #include <linux/err.h>
 #include <linux/clk.h>
 #include <linux/clockchips.h>
+#include <linux/cpu.h>
 #include <linux/platform_device.h>
 #include <linux/delay.h>
 #include <linux/percpu.h>
@@ -24,7 +25,6 @@
 #include <linux/of_address.h>
 #include <linux/clocksource.h>
 
-#include <asm/localtimer.h>
 #include <asm/mach/time.h>
 
 #define EXYNOS4_MCTREG(x)		(x)
@@ -80,7 +80,7 @@ static unsigned int mct_int_type;
 static int mct_irqs[MCT_NR_IRQS];
 
 struct mct_clock_event_device {
-	struct clock_event_device *evt;
+	struct clock_event_device evt;
 	unsigned long base;
 	char name[10];
 };
@@ -295,8 +295,6 @@ static void exynos4_clockevent_init(void)
 	setup_irq(mct_irqs[MCT_G0_IRQ], &mct_comp_event_irq);
 }
 
-#ifdef CONFIG_LOCAL_TIMERS
-
 static DEFINE_PER_CPU(struct mct_clock_event_device, percpu_mct_tick);
 
 /* Clock event handling */
@@ -369,7 +367,7 @@ static inline void exynos4_tick_set_mode(enum
 clock_event_mode mode,
 
 static int exynos4_mct_tick_clear(struct mct_clock_event_device *mevt)
 {
-	struct clock_event_device *evt = mevt->evt;
+	struct clock_event_device *evt = &mevt->evt;
 
 	/*
drivers/clocksource/exynos_mct.c +2 -3
 	 * This is for supporting oneshot mode.
@@ -391,7 +389,7 @@ static int exynos4_mct_tick_clear(struct
 mct_clock_event_device *mevt)
 static irqreturn_t exynos4_mct_tick_isr(int irq, void *dev_id)
 {
 	struct mct_clock_event_device *mevt = dev_id;
-	struct clock_event_device *evt = mevt->evt;
+	struct clock_event_device *evt = &mevt->evt;
 
 	exynos4_mct_tick_clear(mevt);
@@ -417,8 +415,7 @@ static int __cpuinit exynos4_local_timer_setup(struct
 clock_event_device *evt)
 	struct mct_clock_event_device *mevt;
 	unsigned int cpu = smp_processor_id();
 
-	mevt = this_cpu_ptr(&percpu_mct_tick);
-	mevt->evt = evt;
+	mevt = container_of(evt, struct mct_clock_event_device, evt);
 
 	mevt->base = EXYNOS4_MCT_L_BASE(cpu);
drivers/clocksource/exynos_mct.c +1 -1
 	sprintf(mevt->name, "mct_tick%d", cpu);
@@ -452,7 +449,7 @@ static int __cpuinit exynos4_local_timer_setup(struct
 clock_event_device *evt)
 	return 0;
 }
 
-static void exynos4_local_timer_stop(struct clock_event_device *evt)
+static void __cpuinit exynos4_local_timer_stop(struct clock_event_device
 *evt)
 {
drivers/clocksource/exynos_mct.c +27 -4
 	unsigned int cpu = smp_processor_id();
 	evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt);
@@ -465,14 +462,37 @@ static void exynos4_local_timer_stop(struct
 clock_event_device *evt)
 		disable_percpu_irq(mct_irqs[MCT_L0_IRQ]);
 }
 
-static struct local_timer_ops exynos4_mct_tick_ops __cpuinitdata = {
-	.setup	= exynos4_local_timer_setup,
-	.stop	= exynos4_local_timer_stop,
+static int __cpuinit 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 = {
+	.notifier_call = exynos4_mct_cpu_notify,
 };
-#endif /* CONFIG_LOCAL_TIMERS */
 
 static void __init exynos4_timer_resources(struct device_node *np, void
 __iomem *base)
 {
+	int err;
+	struct mct_clock_event_device *mevt =
 this_cpu_ptr(&percpu_mct_tick);
drivers/clocksource/exynos_mct.c +0 -0
 	struct clk *mct_clk, *tick_clk;
 
 	tick_clk = np ? of_clk_get_by_name(np, "fin_pll") :
@@ -490,9 +510,7 @@ static void __init exynos4_timer_resources(struct

device_node *np, void __iomem

drivers/clocksource/exynos_mct.c

Quoted 2 lines
drivers/clocksource/exynos_mct.c +0 -0
 	if (!reg_base)
 		panic("%s: unable to ioremap mct address space\n",

__func__);

Quoted 31 lines
drivers/clocksource/exynos_mct.c +0 -2
-#ifdef CONFIG_LOCAL_TIMERS
 	if (mct_int_type == MCT_INT_PPI) {
-		int err;
 
 		err = request_percpu_irq(mct_irqs[MCT_L0_IRQ],
 					 exynos4_mct_tick_isr, "MCT",
@@ -501,8 +519,16 @@ static void __init exynos4_timer_resources(struct

device_node *np, void __iomem

drivers/clocksource/exynos_mct.c +10 -2
 		     mct_irqs[MCT_L0_IRQ], err);
 	}
 
-	local_timer_register(&exynos4_mct_tick_ops);
-#endif /* CONFIG_LOCAL_TIMERS */
+	err = register_cpu_notifier(&exynos4_mct_cpu_nb);
+	if (err)
+		goto out_irq;
+
+	/* Immediately configure the timer on the boot CPU */
+	exynos4_local_timer_setup(&mevt->evt);
+	return;
+
+out_irq:
+	free_percpu_irq(mct_irqs[MCT_L0_IRQ], &percpu_mct_tick);
 }
 
 void __init mct_init(void __iomem *base, int irq_g0, int irq_l0, int

irq_l1)
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation

#10 lore raw

PATCH v6 7/11 ARM: PRIMA2: Divorce timer-marco from local timer API

In reply to Stephen Boyd

Separate the marco local timers from the local timer API. This will allow us to remove ARM local timer support in the near future and gets us closer to moving this driver to drivers/clocksource.

---
 drivers/clocksource/timer-marco.c | 100 ++++++++++++++++++++------------------
 1 file changed, 54 insertions(+), 46 deletions(-)
drivers/clocksource/timer-marco.c +54 -46
index 97738db..ba97bc1 100644
@@ -10,6 +10,7 @@
 #include <linux/interrupt.h>
 #include <linux/clockchips.h>
 #include <linux/clocksource.h>
+#include <linux/cpu.h>
 #include <linux/bitops.h>
 #include <linux/irq.h>
 #include <linux/clk.h>
@@ -18,7 +19,6 @@
 #include <linux/of_irq.h>
 #include <linux/of_address.h>
 #include <asm/sched_clock.h>
-#include <asm/localtimer.h>
 #include <asm/mach/time.h>
 
 #define SIRFSOC_TIMER_32COUNTER_0_CTRL			0x0000
@@ -151,13 +151,7 @@ static void sirfsoc_clocksource_resume(struct clocksource *cs)
 		BIT(1) | BIT(0), sirfsoc_timer_base + SIRFSOC_TIMER_64COUNTER_CTRL);
 }
 
-static struct clock_event_device sirfsoc_clockevent = {
-	.name = "sirfsoc_clockevent",
-	.rating = 200,
-	.features = CLOCK_EVT_FEAT_ONESHOT,
-	.set_mode = sirfsoc_timer_set_mode,
-	.set_next_event = sirfsoc_timer_set_next_event,
-};
+static struct clock_event_device __percpu *sirfsoc_clockevent;
 
 static struct clocksource sirfsoc_clocksource = {
 	.name = "sirfsoc_clocksource",
@@ -173,11 +167,8 @@ static struct irqaction sirfsoc_timer_irq = {
 	.name = "sirfsoc_timer0",
 	.flags = IRQF_TIMER | IRQF_NOBALANCING,
 	.handler = sirfsoc_timer_interrupt,
-	.dev_id = &sirfsoc_clockevent,
 };
 
-#ifdef CONFIG_LOCAL_TIMERS
-
 static struct irqaction sirfsoc_timer1_irq = {
 	.name = "sirfsoc_timer1",
 	.flags = IRQF_TIMER | IRQF_NOBALANCING,
@@ -186,56 +177,77 @@ static struct irqaction sirfsoc_timer1_irq = {
 
 static int __cpuinit 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 sirfsoc_local_timer_stop(struct clock_event_device *ce)
+static void __cpuinit 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 __cpuinitdata = {
-	.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)
+{
+	/*
+	 * 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 = {
+	.notifier_call = sirfsoc_cpu_notify,
 };
-#endif /* CONFIG_LOCAL_TIMERS */
 
 static void __init sirfsoc_clockevent_init(void)
 {
-	clockevents_calc_mult_shift(&sirfsoc_clockevent, CLOCK_TICK_RATE, 60);
-
-	sirfsoc_clockevent.max_delta_ns =
-		clockevent_delta2ns(-2, &sirfsoc_clockevent);
-	sirfsoc_clockevent.min_delta_ns =
-		clockevent_delta2ns(2, &sirfsoc_clockevent);
-
-	sirfsoc_clockevent.cpumask = cpumask_of(0);
-	clockevents_register_device(&sirfsoc_clockevent);
-#ifdef CONFIG_LOCAL_TIMERS
-	local_timer_register(&sirfsoc_local_timer_ops);
-#endif
+	sirfsoc_clockevent = alloc_percpu(struct clock_event_device);
+	BUG_ON(!sirfsoc_clockevent);
+
+	BUG_ON(register_cpu_notifier(&sirfsoc_cpu_nb));
+
+	/* Immediately configure the timer on the boot CPU */
+	sirfsoc_local_timer_setup(this_cpu_ptr(sirfsoc_clockevent));
 }
 
 /* initialize the kernel jiffy timer source */
@@ -273,8 +285,6 @@ static void __init sirfsoc_marco_timer_init(void)
 
 	BUG_ON(clocksource_register_hz(&sirfsoc_clocksource, CLOCK_TICK_RATE));
 
-	BUG_ON(setup_irq(sirfsoc_timer_irq.irq, &sirfsoc_timer_irq));
-
 	sirfsoc_clockevent_init();
 }
 
@@ -288,11 +298,9 @@ static void __init sirfsoc_of_timer_init(struct device_node *np)
 	if (!sirfsoc_timer_irq.irq)
 		panic("No irq passed for timer0 via DT\n");
 
-#ifdef CONFIG_LOCAL_TIMERS
 	sirfsoc_timer1_irq.irq = irq_of_parse_and_map(np, 1);
 	if (!sirfsoc_timer1_irq.irq)
 		panic("No irq passed for timer1 via DT\n");
-#endif
 
 	sirfsoc_marco_timer_init();
 }
Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation
#11 lore raw

Re: [PATCHv6 07/11] ARM: PRIMA2: Divorce timer-marco from local timer API

Quoted 7 lines · Stephen Boyd

Separate the marco local timers from the local timer API. This will allow us to remove ARM local timer support in the near future and gets us closer to moving this driver to drivers/clocksource.

---

Barry, have you been able to test this patch?

Signature · 2 lines
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation
#12 lore raw

PATCH v6 8/11 ARM: msm: Divorce msm_timer from local timer API

In reply to Stephen Boyd

Separate the msm_timer from the local timer API. This will allow us to remove ARM local timer support in the near future and gets us closer to moving this driver to drivers/clocksource.

---
 arch/arm/mach-msm/timer.c | 126 +++++++++++++++++++++++++---------------------
 1 file changed, 70 insertions(+), 56 deletions(-)
arch/arm/mach-msm/timer.c +70 -56
index 284313f..df947aa 100644
@@ -16,6 +16,7 @@
 
 #include <linux/clocksource.h>
 #include <linux/clockchips.h>
+#include <linux/cpu.h>
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
@@ -25,7 +26,6 @@
 #include <linux/of_irq.h>
 
 #include <asm/mach/time.h>
-#include <asm/localtimer.h>
 #include <asm/sched_clock.h>
 
 #include "common.h"
@@ -49,7 +49,7 @@ static void __iomem *sts_base;
 
 static irqreturn_t msm_timer_interrupt(int irq, void *dev_id)
 {
-	struct clock_event_device *evt = *(struct clock_event_device **)dev_id;
+	struct clock_event_device *evt = dev_id;
 	/* Stop the timer tick */
 	if (evt->mode == CLOCK_EVT_MODE_ONESHOT) {
 		u32 ctrl = readl_relaxed(event_base + TIMER_ENABLE);
@@ -101,18 +101,7 @@ static void msm_timer_set_mode(enum clock_event_mode mode,
 	writel_relaxed(ctrl, event_base + TIMER_ENABLE);
 }
 
-static struct clock_event_device msm_clockevent = {
-	.name		= "gp_timer",
-	.features	= CLOCK_EVT_FEAT_ONESHOT,
-	.rating		= 200,
-	.set_next_event	= msm_timer_set_next_event,
-	.set_mode	= msm_timer_set_mode,
-};
-
-static union {
-	struct clock_event_device *evt;
-	struct clock_event_device * __percpu *percpu_evt;
-} msm_evt;
+static struct clock_event_device __percpu *msm_evt;
 
 static void __iomem *source_base;
 
@@ -138,37 +127,65 @@ static struct clocksource msm_clocksource = {
 	.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)
 {
-	/* 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;
 }
 
-static void msm_local_timer_stop(struct clock_event_device *evt)
+static void __cpuinit msm_local_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 msm_local_timer_ops __cpuinitdata = {
-	.setup	= msm_local_timer_setup,
-	.stop	= msm_local_timer_stop,
+static int __cpuinit 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 = {
+	.notifier_call = msm_timer_cpu_notify,
 };
-#endif /* CONFIG_LOCAL_TIMERS */
 
 static notrace u32 msm_sched_clock_read(void)
 {
@@ -178,38 +195,35 @@ static notrace u32 msm_sched_clock_read(void)
 static void __init msm_timer_init(u32 dgt_hz, int sched_bits, int irq,
 				  bool percpu)
 {
-	struct clock_event_device *ce = &msm_clockevent;
 	struct clocksource *cs = &msm_clocksource;
-	int res;
+	int res = 0;
+
+	msm_timer_irq = irq;
+	msm_timer_has_ppi = percpu;
+
+	msm_evt = alloc_percpu(struct clock_event_device);
+	if (!msm_evt) {
+		pr_err("memory allocation failed for clockevents\n");
+		goto err;
+	}
 
-	ce->cpumask = cpumask_of(0);
-	ce->irq = irq;
+	if (percpu)
+		res = request_percpu_irq(irq, msm_timer_interrupt,
+					 "gp_timer", msm_evt);
 
-	clockevents_config_and_register(ce, GPT_HZ, 4, 0xffffffff);
-	if (percpu) {
-		msm_evt.percpu_evt = alloc_percpu(struct clock_event_device *);
-		if (!msm_evt.percpu_evt) {
-			pr_err("memory allocation failed for %s\n", ce->name);
+	if (res) {
+		pr_err("request_percpu_irq failed\n");
+	} else {
+		res = register_cpu_notifier(&msm_timer_cpu_nb);
+		if (res) {
+			free_percpu_irq(irq, msm_evt);
 			goto err;
 		}
-		*__this_cpu_ptr(msm_evt.percpu_evt) = ce;
-		res = request_percpu_irq(ce->irq, msm_timer_interrupt,
-					 ce->name, msm_evt.percpu_evt);
-		if (!res) {
-			enable_percpu_irq(ce->irq, IRQ_TYPE_EDGE_RISING);
-#ifdef CONFIG_LOCAL_TIMERS
-			local_timer_register(&msm_local_timer_ops);
-#endif
-		}
-	} else {
-		msm_evt.evt = ce;
-		res = request_irq(ce->irq, msm_timer_interrupt,
-				  IRQF_TIMER | IRQF_NOBALANCING |
-				  IRQF_TRIGGER_RISING, ce->name, &msm_evt.evt);
+
+		/* Immediately configure the timer on the boot CPU */
+		msm_local_timer_setup(__this_cpu_ptr(msm_evt));
 	}
 
-	if (res)
-		pr_err("request_irq failed for %s\n", ce->name);
 err:
 	writel_relaxed(TIMER_ENABLE_EN, source_base + TIMER_ENABLE);
 	res = clocksource_register_hz(cs, dgt_hz);
Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation
#13 lore raw

PATCH v6 9/11 clocksource: time-armada-370-xp: Fix sparse warning

In reply to Stephen Boyd

drivers/clocksource/time-armada-370-xp.c:217:13: warning: symbol 'armada_370_xp_timer_init' was not declared. Should it be static?

Also remove the __init marking in the prototype as it's unnecessary and drop the init.h file.

---
 drivers/clocksource/time-armada-370-xp.c | 3 ++-
 include/linux/time-armada-370-xp.h       | 4 +---
 2 files changed, 3 insertions(+), 4 deletions(-)
drivers/clocksource/time-armada-370-xp.c +2 -1
index 47a6730..efe4aef 100644
@@ -27,10 +27,11 @@
 #include <linux/of_address.h>
 #include <linux/irq.h>
 #include <linux/module.h>
+#include <linux/percpu.h>
+#include <linux/time-armada-370-xp.h>
 
 #include <asm/sched_clock.h>
 #include <asm/localtimer.h>
-#include <linux/percpu.h>
 /*
  * Timer block registers.
  */
include/linux/time-armada-370-xp.h +1 -3
index dfdfdc0..6fb0856 100644
@@ -11,8 +11,6 @@
 #ifndef __TIME_ARMADA_370_XPPRCMU_H
 #define __TIME_ARMADA_370_XPPRCMU_H
 
-#include <linux/init.h>
-
-void __init armada_370_xp_timer_init(void);
+void armada_370_xp_timer_init(void);
 
 #endif
Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation
#14 lore raw

PATCH v6 10/11 clocksource: time-armada-370-xp: Divorce from local timer API

In reply to Stephen Boyd

Separate the armada 370xp local timers from the local timer API. This will allow us to remove ARM local timer support in the near future and makes this driver multi-architecture friendly.

---
 drivers/clocksource/time-armada-370-xp.c | 89 +++++++++++++++-----------------
 1 file changed, 41 insertions(+), 48 deletions(-)
drivers/clocksource/time-armada-370-xp.c +41 -48
index efe4aef..4a31e86 100644
@@ -19,6 +19,7 @@
 #include <linux/platform_device.h>
 #include <linux/kernel.h>
 #include <linux/clk.h>
+#include <linux/cpu.h>
 #include <linux/timer.h>
 #include <linux/clockchips.h>
 #include <linux/interrupt.h>
@@ -31,7 +32,6 @@
 #include <linux/time-armada-370-xp.h>
 
 #include <asm/sched_clock.h>
-#include <asm/localtimer.h>
 /*
  * Timer block registers.
  */
@@ -70,7 +70,7 @@ 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 u32 notrace armada_370_xp_read_sched_clock(void)
 {
@@ -143,21 +143,14 @@ armada_370_xp_clkevt_mode(enum clock_event_mode mode,
 	}
 }
 
-static struct clock_event_device armada_370_xp_clkevt = {
-	.name		= "armada_370_xp_per_cpu_tick",
-	.features	= CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC,
-	.shift		= 32,
-	.rating		= 300,
-	.set_next_event	= armada_370_xp_clkevt_next_event,
-	.set_mode	= armada_370_xp_clkevt_mode,
-};
+static int armada_370_xp_clkevt_irq;
 
 static irqreturn_t armada_370_xp_timer_interrupt(int irq, void *dev_id)
 {
 	/*
 	 * ACK timer interrupt and call event handler.
 	 */
-	struct clock_event_device *evt = *(struct clock_event_device **)dev_id;
+	struct clock_event_device *evt = dev_id;
 
 	writel(TIMER0_CLR_MASK, local_base + LCL_TIMER_EVENTS_STATUS);
 	evt->event_handler(evt);
@@ -173,42 +166,55 @@ static int __cpuinit armada_370_xp_timer_setup(struct clock_event_device *evt)
 	u32 u;
 	int cpu = smp_processor_id();
 
-	/* Use existing clock_event for cpu 0 */
-	if (!smp_processor_id())
-		return 0;
-
 	u = readl(local_base + TIMER_CTRL_OFF);
 	if (timer25Mhz)
 		writel(u | TIMER0_25MHZ, local_base + TIMER_CTRL_OFF);
 	else
 		writel(u & ~TIMER0_25MHZ, local_base + TIMER_CTRL_OFF);
 
-	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);
 
 	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)
 {
 	evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt);
 	disable_percpu_irq(evt->irq);
 }
 
-static struct local_timer_ops armada_370_xp_local_timer_ops __cpuinitdata = {
-	.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,
+					   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 = {
+	.notifier_call = armada_370_xp_timer_cpu_notify,
 };
 
 void __init armada_370_xp_timer_init(void)
@@ -224,9 +230,6 @@ void __init armada_370_xp_timer_init(void)
 
 	if (of_find_property(np, "marvell,timer-25Mhz", NULL)) {
 		/* The fixed 25MHz timer is available so let's use it */
-		u = readl(local_base + TIMER_CTRL_OFF);
-		writel(u | TIMER0_25MHZ,
-		       local_base + TIMER_CTRL_OFF);
 		u = readl(timer_base + TIMER_CTRL_OFF);
 		writel(u | TIMER0_25MHZ,
 		       timer_base + TIMER_CTRL_OFF);
@@ -236,9 +239,6 @@ void __init armada_370_xp_timer_init(void)
 		struct clk *clk = of_clk_get(np, 0);
 		WARN_ON(IS_ERR(clk));
 		rate =  clk_get_rate(clk);
-		u = readl(local_base + TIMER_CTRL_OFF);
-		writel(u & ~(TIMER0_25MHZ),
-		       local_base + TIMER_CTRL_OFF);
 
 		u = readl(timer_base + TIMER_CTRL_OFF);
 		writel(u & ~(TIMER0_25MHZ),
@@ -252,7 +252,7 @@ void __init armada_370_xp_timer_init(void)
 	 * We use timer 0 as clocksource, and private(local) timer 0
 	 * for clockevents
 	 */
-	armada_370_xp_clkevt.irq = irq_of_parse_and_map(np, 4);
+	armada_370_xp_clkevt_irq = irq_of_parse_and_map(np, 4);
 
 	ticks_per_jiffy = (timer_clk + HZ / 2) / HZ;
 
@@ -277,26 +277,19 @@ void __init armada_370_xp_timer_init(void)
 			      "armada_370_xp_clocksource",
 			      timer_clk, 300, 32, clocksource_mmio_readl_down);
 
-	/* Register the clockevent on the private timer of CPU 0 */
-	armada_370_xp_clkevt.cpumask = cpumask_of(0);
-	clockevents_config_and_register(&armada_370_xp_clkevt,
-					timer_clk, 1, 0xfffffffe);
+	register_cpu_notifier(&armada_370_xp_timer_cpu_nb);
 
-	percpu_armada_370_xp_evt = alloc_percpu(struct clock_event_device *);
+	armada_370_xp_evt = alloc_percpu(struct clock_event_device);
 
 
 	/*
 	 * 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));
 }
Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation
#15 lore raw

PATCH v6 11/11 ARM: smp: Remove local timer API

In reply to Stephen Boyd

There are no more users of this API, remove it.

---
 arch/arm/Kconfig                  | 10 ------
 arch/arm/include/asm/localtimer.h | 34 -------------------
 arch/arm/kernel/smp.c             | 69 ---------------------------------------
 3 files changed, 113 deletions(-)
 delete mode 100644 arch/arm/include/asm/localtimer.h
arch/arm/Kconfig +0 -10
index 177cb39..626a272 100644
@@ -1542,16 +1542,6 @@ config ARM_PSCI
 	  0022A ("Power State Coordination Interface System Software on
 	  ARM processors").
 
-config LOCAL_TIMERS
-	bool "Use local timer interrupts"
-	depends on SMP
-	default y
-	help
-	  Enable support for local timers on SMP platforms, rather then the
-	  legacy IPI broadcast method.  Local timers allows the system
-	  accounting to be spread across the timer interval, preventing a
-	  "thundering herd" at every timer tick.
-
 # The GPIO number here must be sorted by descending number. In case of
 # a multiplatform kernel, we just want the highest value required by the
 # selected platforms.
arch/arm/include/asm/localtimer.h deleted +0 -34
deleted file mode 100644
index f77ffc1..0000000
@@ -1,34 +0,0 @@
-/*
- *  arch/arm/include/asm/localtimer.h
- *
- *  Copyright (C) 2004-2005 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.
- */
-#ifndef __ASM_ARM_LOCALTIMER_H
-#define __ASM_ARM_LOCALTIMER_H
-
-#include <linux/errno.h>
-
-struct clock_event_device;
-
-struct local_timer_ops {
-	int  (*setup)(struct clock_event_device *);
-	void (*stop)(struct clock_event_device *);
-};
-
-#ifdef CONFIG_LOCAL_TIMERS
-/*
- * Register a local timer driver
- */
-int local_timer_register(struct local_timer_ops *);
-#else
-static inline int local_timer_register(struct local_timer_ops *ops)
-{
-	return -ENXIO;
-}
-#endif
-
-#endif
arch/arm/kernel/smp.c +0 -69

117 lines not on this page · raw message

Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation
#16 lore raw
In reply to Stephen Boyd

Comments have been light for this round so I think we're about ready to merge. John/Thomas, can you pick up these patches or shall I route them through arm-soc or something else?

Quoted 95 lines · Stephen Boyd

In light of Mark Rutland's recent work on divorcing the ARM architected timers from the ARM local timer API and introducing a generic arch hook for broadcast it seems that we should remove the local timer API entirely. Doing so will reduce the architecture dependencies of our timer drivers, reduce code in ARM core, and simplify timer drivers because they no longer go through an architecture layer that is essentially a hotplug notifier.

Previous attempts have been made[1] unsuccessfully. I'm hoping this can be accepted now so that we can clean up the timer drivers that are used in both UP and SMP situations. Right now these drivers have to ignore the timer setup callback on the boot CPU to avoid registering clockevents twice. This is not very symmetric and causes convuluted code that does the same thing in two places.

Patches based on next-20130418

I'm still looking for Acks/Tested-by on EXYNOS and PRIMA2.

[1] http://article.gmane.org/gmane.linux.ports.arm.kernel/145705

Note: A hotplug notifier is used by both x86 for the apb_timer (see apbt_cpuhp_notify) and by metag (see arch_timer_cpu_notify in metag_generic.c) so this is not new.

Changes since v5:
* Rebased onto v3.10-rc1
* Rebase caused minor updates to mct patch

Changes since v4:
* Rebased onto next-20130418
* Rebase caused minor updates to mct patch and twd Kconfig

Changes since v3:
* New patch to fix SMP with dummy timers registered after a global timer
* Push this_cpu_ptr lower to avoid preemptible false positive warnings
* Collected acks/tested-bys

Changes since v2:
* Bug fixes in smp_twd from Tony Lindgren's testing
* Move smp_twd to use late_time_init hook
* Collected Acks

Changes since v1:
* Picked up Mark's generic dummy timer driver
* Split out omap changes into new patch

Mark Rutland (1):
clocksource: add generic dummy timer driver

Stephen Boyd (10):
clockevents: Prefer CPU local devices over global devices
ARM: smp: Remove duplicate dummy timer implementation
ARM: smp_twd: Divorce smp_twd from local timer API
ARM: OMAP2+: Divorce from local timer API
ARM: EXYNOS4: Divorce mct from local timer API
ARM: PRIMA2: Divorce timer-marco from local timer API
ARM: msm: Divorce msm_timer from local timer API
clocksource: time-armada-370-xp: Fix sparse warning
clocksource: time-armada-370-xp: Divorce from local timer API
ARM: smp: Remove local timer API

 arch/arm/Kconfig                         |  12 +--
 arch/arm/include/asm/localtimer.h        |  34 ---------
 arch/arm/kernel/smp.c                    |  87 ---------------------
 arch/arm/kernel/smp_twd.c                |  64 ++++++++++------
 arch/arm/mach-highbank/Kconfig           |   2 +-
 arch/arm/mach-imx/Kconfig                |   2 +-
 arch/arm/mach-msm/timer.c                | 126 +++++++++++++++++--------------
 arch/arm/mach-omap2/Kconfig              |   3 +-
 arch/arm/mach-omap2/timer.c              |   7 --
 arch/arm/mach-realview/Kconfig           |   8 +-
 arch/arm/mach-spear/Kconfig              |   2 +-
 arch/arm/mach-tegra/Kconfig              |   2 +-
 arch/arm/mach-ux500/Kconfig              |   2 +-
 arch/arm/mach-vexpress/Kconfig           |   2 +-
 arch/arm/mach-zynq/Kconfig               |   2 +-
 drivers/clocksource/Makefile             |   1 +
 drivers/clocksource/dummy_timer.c        |  69 +++++++++++++++++
 drivers/clocksource/exynos_mct.c         |  60 ++++++++++-----
 drivers/clocksource/time-armada-370-xp.c |  92 +++++++++++-----------
 drivers/clocksource/timer-marco.c        | 100 +++++++++++++-----------
 include/linux/time-armada-370-xp.h       |   4 +-
 kernel/time/tick-common.c                |   5 +-
 22 files changed, 340 insertions(+), 346 deletions(-)
 delete mode 100644 arch/arm/include/asm/localtimer.h
 create mode 100644 drivers/clocksource/dummy_timer.c
Signature · 7 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation

--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Signature · 2 lines
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation
#17 lore raw
Quoted 3 lines · Stephen Boyd

Comments have been light for this round so I think we're about ready to merge. John/Thomas, can you pick up these patches or shall I route them through arm-soc or something else?

So there looks to be a fair amount of additions in the ARM tree, do those already have acks from Arnd/Olof/other folks? (I think I was only cc'ed on the first two patches).

Daniel (cc'ed) has just started helping out here, and should be able to review and hopefully ack or pick up the timer related drivers/clocksource changes to feed to Thomas' tree. Not sure if he's got them in his mailbox so you might want to resend them and make sure he's CC'ed.

If Arnd/Olof/whomever else from the arm side has acked things, Daniel probably could queue the arm changes too, but it might be better just to get Daniel's ack on the drivers/clocksource changes and then queue things via arm-soc?

thanks
-john

Quoted 96 lines · Stephen Boyd
Quoted 95 lines

In light of Mark Rutland's recent work on divorcing the ARM architected timers from the ARM local timer API and introducing a generic arch hook for broadcast it seems that we should remove the local timer API entirely. Doing so will reduce the architecture dependencies of our timer drivers, reduce code in ARM core, and simplify timer drivers because they no longer go through an architecture layer that is essentially a hotplug notifier.

Previous attempts have been made[1] unsuccessfully. I'm hoping this can be accepted now so that we can clean up the timer drivers that are used in both UP and SMP situations. Right now these drivers have to ignore the timer setup callback on the boot CPU to avoid registering clockevents twice. This is not very symmetric and causes convuluted code that does the same thing in two places.

Patches based on next-20130418

I'm still looking for Acks/Tested-by on EXYNOS and PRIMA2.

[1] http://article.gmane.org/gmane.linux.ports.arm.kernel/145705

Note: A hotplug notifier is used by both x86 for the apb_timer (see apbt_cpuhp_notify) and by metag (see arch_timer_cpu_notify in metag_generic.c) so this is not new.

Changes since v5:
* Rebased onto v3.10-rc1
* Rebase caused minor updates to mct patch

Changes since v4:
* Rebased onto next-20130418
* Rebase caused minor updates to mct patch and twd Kconfig

Changes since v3:
* New patch to fix SMP with dummy timers registered after a global timer
* Push this_cpu_ptr lower to avoid preemptible false positive warnings
* Collected acks/tested-bys

Changes since v2:
* Bug fixes in smp_twd from Tony Lindgren's testing
* Move smp_twd to use late_time_init hook
* Collected Acks

Changes since v1:
* Picked up Mark's generic dummy timer driver
* Split out omap changes into new patch

Mark Rutland (1):
clocksource: add generic dummy timer driver

Stephen Boyd (10):
clockevents: Prefer CPU local devices over global devices
ARM: smp: Remove duplicate dummy timer implementation
ARM: smp_twd: Divorce smp_twd from local timer API
ARM: OMAP2+: Divorce from local timer API
ARM: EXYNOS4: Divorce mct from local timer API
ARM: PRIMA2: Divorce timer-marco from local timer API
ARM: msm: Divorce msm_timer from local timer API
clocksource: time-armada-370-xp: Fix sparse warning
clocksource: time-armada-370-xp: Divorce from local timer API
ARM: smp: Remove local timer API

  arch/arm/Kconfig                         |  12 +--
  arch/arm/include/asm/localtimer.h        |  34 ---------
  arch/arm/kernel/smp.c                    |  87 ---------------------
  arch/arm/kernel/smp_twd.c                |  64 ++++++++++------
  arch/arm/mach-highbank/Kconfig           |   2 +-
  arch/arm/mach-imx/Kconfig                |   2 +-
  arch/arm/mach-msm/timer.c                | 126 +++++++++++++++++--------------
  arch/arm/mach-omap2/Kconfig              |   3 +-
  arch/arm/mach-omap2/timer.c              |   7 --
  arch/arm/mach-realview/Kconfig           |   8 +-
  arch/arm/mach-spear/Kconfig              |   2 +-
  arch/arm/mach-tegra/Kconfig              |   2 +-
  arch/arm/mach-ux500/Kconfig              |   2 +-
  arch/arm/mach-vexpress/Kconfig           |   2 +-
  arch/arm/mach-zynq/Kconfig               |   2 +-
  drivers/clocksource/Makefile             |   1 +
  drivers/clocksource/dummy_timer.c        |  69 +++++++++++++++++
  drivers/clocksource/exynos_mct.c         |  60 ++++++++++-----
  drivers/clocksource/time-armada-370-xp.c |  92 +++++++++++-----------
  drivers/clocksource/timer-marco.c        | 100 +++++++++++++-----------
  include/linux/time-armada-370-xp.h       |   4 +-
  kernel/time/tick-common.c                |   5 +-
  22 files changed, 340 insertions(+), 346 deletions(-)

delete mode 100644 arch/arm/include/asm/localtimer.h create mode 100644 drivers/clocksource/dummy_timer.c

Signature · 7 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation

--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#18 lore raw
Quoted 9 lines · John Stultz
Quoted 3 lines · Stephen Boyd

Comments have been light for this round so I think we're about ready to merge. John/Thomas, can you pick up these patches or shall I route them through arm-soc or something else?

So there looks to be a fair amount of additions in the ARM tree, do those already have acks from Arnd/Olof/other folks? (I think I was only cc'ed on the first two patches).

I'm still missing acks from Kukjin and Barry.

Quoted 11 lines

Daniel (cc'ed) has just started helping out here, and should be able to review and hopefully ack or pick up the timer related drivers/clocksource changes to feed to Thomas' tree. Not sure if he's got them in his mailbox so you might want to resend them and make sure he's CC'ed.

If Arnd/Olof/whomever else from the arm side has acked things, Daniel probably could queue the arm changes too, but it might be better just to get Daniel's ack on the drivers/clocksource changes and then queue things via arm-soc?

Either way works for me. I would just like to see this merged into 3.11. I guess I will resend one more time.

Signature · 2 lines
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation
#19 lore raw
Quoted 20 lines · Stephen Boyd
Quoted 9 lines · John Stultz
Quoted 3 lines · Stephen Boyd

Comments have been light for this round so I think we're about ready to merge. John/Thomas, can you pick up these patches or shall I route them through arm-soc or something else?

So there looks to be a fair amount of additions in the ARM tree, do those already have acks from Arnd/Olof/other folks? (I think I was only cc'ed on the first two patches).

I'm still missing acks from Kukjin and Barry.

Quoted 7 lines

Daniel (cc'ed) has just started helping out here, and should be able to review and hopefully ack or pick up the timer related drivers/clocksource changes to feed to Thomas' tree. Not sure if he's got them in his mailbox so you might want to resend them and make sure he's CC'ed.

Quoted 7 lines
Quoted 4 lines

If Arnd/Olof/whomever else from the arm side has acked things, Daniel probably could queue the arm changes too, but it might be better just to get Daniel's ack on the drivers/clocksource changes and then queue things via arm-soc?

Either way works for me. I would just like to see this merged into 3.11. I guess I will resend one more time.

Yes please, resend. I will review them.

queuing the patches via arm-soc makes sense for me, but I prefer to review them before we decide to which tree we get them merged.

Thanks
-- Daniel

Signature · 5 lines
 <http://www.linaro.org/> Linaro.org ? Open source software for ARM SoCs

Follow Linaro:  <http://www.facebook.com/pages/Linaro> Facebook |
<http://twitter.com/#!/linaroorg> Twitter |
<http://www.linaro.org/linaro-blog/> Blog
Acked-by
#20 lore raw
In reply to Stephen Boyd
Quoted 7 lines · Stephen Boyd
Quoted 6 lines · John Stultz
Quoted 3 lines · Stephen Boyd

Comments have been light for this round so I think we're about ready to merge. John/Thomas, can you pick up these patches or shall I route them through arm-soc or something else?

Quoted 5 lines
Quoted 3 lines

So there looks to be a fair amount of additions in the ARM tree, do those already have acks from Arnd/Olof/other folks? (I think I was only cc'ed on the first two patches).

I'm still missing acks from Kukjin and Barry.

I don't think that should hold off the patch series. It's been tested on most other platforms over the course of several months. If the platform maintainers aren't responsive enough, fixing the issues becomes their problem.

FWIW, have my

	M.
Signature · 1 line
Jazz is not dead. It just smells funny...
#21 lore raw
Quoted 9 lines · Marc Zyngier
Quoted 7 lines · Stephen Boyd
Quoted 6 lines · John Stultz
Quoted 3 lines · Stephen Boyd

Comments have been light for this round so I think we're about ready to merge. John/Thomas, can you pick up these patches or shall I route them through arm-soc or something else?

Quoted 6 lines
Quoted 5 lines
Quoted 3 lines

So there looks to be a fair amount of additions in the ARM tree, do those already have acks from Arnd/Olof/other folks? (I think I was only cc'ed on the first two patches).

I'm still missing acks from Kukjin and Barry.

Stephen, I replied on exynos stuff in this series.

Quoted 5 lines

I don't think that should hold off the patch series. It's been tested on most other platforms over the course of several months. If the platform maintainers aren't responsive enough, fixing the issues becomes their problem.

Marc, I understand what you're saying. Let me look at the regarding exynos stuff carefully.

Thanks.

- Kukjin

#22 lore raw
In reply to Marc Zyngier
Quoted 10 lines · Marc Zyngier
Quoted 9 lines · Stephen Boyd
Quoted 8 lines · John Stultz
Quoted 3 lines · Stephen Boyd

Comments have been light for this round so I think we're about ready to merge. John/Thomas, can you pick up these patches or shall I route them through arm-soc or something else?

So there looks to be a fair amount of additions in the ARM tree, do those already have acks from Arnd/Olof/other folks? (I think I was only cc'ed on the first two patches).

Quoted 8 lines
Quoted 1 line

I'm still missing acks from Kukjin and Barry.

I don't think that should hold off the patch series. It's been tested on most other platforms over the course of several months. If the platform maintainers aren't responsive enough, fixing the issues becomes their problem.

FWIW, have my

Thanks Marc. Any particular patches or should I add this to all of them?

Signature · 2 lines
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation
#23 lore raw
Quoted 8 lines · Stephen Boyd
Quoted 7 lines · Marc Zyngier
Quoted 6 lines · Stephen Boyd
Quoted 5 lines · John Stultz
Quoted 3 lines · Stephen Boyd

Comments have been light for this round so I think we're about ready to merge. John/Thomas, can you pick up these patches or shall I route them through arm-soc or something else?

Quoted 5 lines
Quoted 5 lines
Quoted 4 lines
Quoted 3 lines

So there looks to be a fair amount of additions in the ARM tree, do those already have acks from Arnd/Olof/other folks? (I think I was only cc'ed on the first two patches).

I'm still missing acks from Kukjin and Barry.

I don't think that should hold off the patch series. It's been tested

on

Quoted 8 lines
Quoted 6 lines

most other platforms over the course of several months. If the platform maintainers aren't responsive enough, fixing the issues becomes their problem.

FWIW, have my

Thanks Marc. Any particular patches or should I add this to all of them?

All of them. I'm not that subtle... ;-)

        M.
Signature · 1 line
Fast, cheap, reliable. Pick two.