Skip to contentSkip to conversation

Make SMP timers standalone

RFC PATCH Superseded Marc Zyngier 2 participants 14 messages Aug 9, 2011

Subsystems (8)

v1 of 2 Superseded Latest is v2 →

lore
Share & tools
lore
#0 lore raw

cover Make SMP timers standalone

The LOCAL_TIMERS infrastructure has a few limitations:
- It only allows one implementation to be compiled in, hence preventing a single kernel image to be booted hardware with different requirements (Tegra and MSM, for example).
- It is only supported on SMP, which is a problem on platforms where the local timer can be used on UP platforms (Cortex A15 being one).

The proposal is to convert local timer drivers to be "standalone" (not relying on the local timer infrastructure) and to use a CPU notifier to have the timer brought up or down on non-boot CPUs.

The SMP support code can then be simplified to only manage the boadcast timer, which is always installed, and leave the generic kernel code to pick the highest priority timer. CONFIG_LOCAL_TIMERS disappears in the process.

This patch series is based on my earlier series ("Consolidating GIC per-cpu interrupts"). Tested on EB11MP, VE A15, OMAP4 and Tegra.

Marc Zyngier (12):
ARM: local timers: allow smp_twd to be used standalone
ARM: local timers: switch realview to standalone smp_twd
ARM: local timers: switch vexpress to standalone smp_twd
ARM: local timers: remove localtimer.c from plat-versatile
ARM: local timers: switch tegra to standalone smp_twd
ARM: local timers: switch omap4 to standalone smp_twd
ARM: local timers: switch shmobile to standalone smp_twd
ARM: local timers: switch ux500 to standalone smp_twd
ARM: smp_twd: remove support for non-standalone version
ARM: local timers: make MSM timers standalone
ARM: local timers: make MCT timer standalone
ARM: local timers: Remove CONFIG_LOCAL_TIMERS support

 arch/arm/Kconfig                             |   15 +----
 arch/arm/include/asm/localtimer.h            |   56 -----------------
 arch/arm/include/asm/smp_twd.h               |   14 +++--
 arch/arm/kernel/smp.c                        |   56 +++++-------------
 arch/arm/kernel/smp_twd.c                    |   82 ++++++++++++++++++++++++--
 arch/arm/mach-exynos4/mct.c                  |   75 ++++++++++++++++++------
 arch/arm/mach-msm/timer.c                    |   64 +++++++++++++++-----
 arch/arm/mach-omap2/Kconfig                  |    2 +-
 arch/arm/mach-omap2/Makefile                 |    1 -
 arch/arm/mach-omap2/timer-mpu.c              |   39 ------------
 arch/arm/mach-omap2/timer.c                  |   38 ++++++++++--
 arch/arm/mach-realview/Kconfig               |    3 +
 arch/arm/mach-realview/realview_eb.c         |   33 +++++++++-
 arch/arm/mach-realview/realview_pb11mp.c     |   31 +++++++++-
 arch/arm/mach-realview/realview_pbx.c        |   30 +++++++++-
 arch/arm/mach-shmobile/Kconfig               |    1 +
 arch/arm/mach-shmobile/Makefile              |    1 -
 arch/arm/mach-shmobile/include/mach/common.h |    3 +
 arch/arm/mach-shmobile/localtimer.c          |   26 --------
 arch/arm/mach-shmobile/platsmp.c             |    1 -
 arch/arm/mach-shmobile/smp-sh73a0.c          |   32 +++++++++-
 arch/arm/mach-shmobile/timer.c               |   10 +++
 arch/arm/mach-tegra/Kconfig                  |    1 +
 arch/arm/mach-tegra/Makefile                 |    2 +-
 arch/arm/mach-tegra/localtimer.c             |   26 --------
 arch/arm/mach-tegra/timer.c                  |   34 +++++++++--
 arch/arm/mach-ux500/Kconfig                  |    1 +
 arch/arm/mach-ux500/Makefile                 |    1 -
 arch/arm/mach-ux500/cpu.c                    |   40 ++++++++++--
 arch/arm/mach-ux500/localtimer.c             |   29 ---------
 arch/arm/mach-vexpress/Kconfig               |    1 +
 arch/arm/mach-vexpress/ct-ca9x4.c            |   29 ++++++++-
 arch/arm/plat-versatile/Makefile             |    1 -
 arch/arm/plat-versatile/localtimer.c         |   27 ---------
 34 files changed, 462 insertions(+), 343 deletions(-)
 delete mode 100644 arch/arm/include/asm/localtimer.h
 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
 delete mode 100644 arch/arm/plat-versatile/localtimer.c
#1 lore raw

RFC PATCH 1/12 ARM: local timers: allow smp_twd to be used standalone

Allow smp_twd to be built in a "standalone" version, without relying on the CONFIG_LOCAL_TIMER infrastructure. It mainly relies on a CPU notifier block to stop or start the timer on the right CPU.

The CONFIG_ARM_SMP_TWD option selects the new behaviour.

---
 arch/arm/Kconfig               |    6 +++-
 arch/arm/include/asm/smp_twd.h |    9 +++++
 arch/arm/kernel/smp_twd.c      |   76 +++++++++++++++++++++++++++++++++++++++-
 3 files changed, 89 insertions(+), 2 deletions(-)
arch/arm/Kconfig +5 -1
index 2c71a8f..7ac28a3 100644
@@ -1394,6 +1394,10 @@ config HAVE_ARM_TWD
 	help
 	  This options enables support for the ARM timer and watchdog unit
 
+config ARM_SMP_TWD
+	bool
+	select HAVE_ARM_TWD if SMP
+
 choice
 	prompt "Memory split"
 	default VMSPLIT_3G
@@ -1432,7 +1436,7 @@ config HOTPLUG_CPU
 
 config LOCAL_TIMERS
 	bool "Use local timer interrupts"
-	depends on SMP
+	depends on SMP && !ARM_SMP_TWD
 	default y
 	select HAVE_ARM_TWD if (!ARCH_MSM_SCORPIONMP && !EXYNOS4_MCT)
 	help
arch/arm/include/asm/smp_twd.h +9 -0
index ef9ffba..934f1bc 100644
@@ -19,10 +19,19 @@
 #define TWD_TIMER_CONTROL_IT_ENABLE	(1 << 2)
 
 struct clock_event_device;
+struct resource;
 
 extern void __iomem *twd_base;
 
 void twd_timer_setup(struct clock_event_device *);
 void twd_timer_stop(struct clock_event_device *);
+#ifdef CONFIG_HAVE_ARM_TWD
+int twd_timer_register(struct resource *res, int res_nr);
+#else
+static inline int twd_timer_register(struct resource *res, int res_nr)
+{
+	return 0;
+}
+#endif
 
 #endif
arch/arm/kernel/smp_twd.c +75 -1

91 lines not on this page · raw message

Signature · 1 line
1.7.0.4
#2 lore raw

RFC PATCH 2/12 ARM: local timers: switch realview to standalone smp_twd

In reply to Marc Zyngier

Convert the SMP RealView platforms to the standalone version of smp_twd.c. Since the timer calibration code requires another timer to be up and running, the actual initialisation is left to the late_timer_init hook.

Tested on EB-11MP.

---
 arch/arm/mach-realview/Kconfig           |    3 ++
 arch/arm/mach-realview/realview_eb.c     |   33 ++++++++++++++++++++++++++---
 arch/arm/mach-realview/realview_pb11mp.c |   31 ++++++++++++++++++++++++---
 arch/arm/mach-realview/realview_pbx.c    |   30 ++++++++++++++++++++++++--
 4 files changed, 86 insertions(+), 11 deletions(-)
arch/arm/mach-realview/Kconfig +3 -0
index dba6d0c..135a7ea 100644
@@ -4,6 +4,7 @@ menu "RealView platform type"
 config MACH_REALVIEW_EB
 	bool "Support RealView(R) Emulation Baseboard"
 	select ARM_GIC
+	select ARM_SMP_TWD if SMP
 	help
 	  Include support for the ARM(R) RealView(R) Emulation Baseboard
 	  platform.
@@ -40,6 +41,7 @@ config MACH_REALVIEW_PB11MP
 	select ARM_GIC
 	select HAVE_PATA_PLATFORM
 	select ARCH_HAS_BARRIERS if SMP
+	select ARM_SMP_TWD if SMP
 	help
 	  Include support for the ARM(R) RealView(R) Platform Baseboard for
 	  the ARM11MPCore.  This platform has an on-board ARM11MPCore and has
@@ -80,6 +82,7 @@ config MACH_REALVIEW_PBX
 	select HAVE_PATA_PLATFORM
 	select ARCH_SPARSEMEM_ENABLE if CPU_V7 && !REALVIEW_HIGH_PHYS_OFFSET
 	select ZONE_DMA if SPARSEMEM
+	select ARM_SMP_TWD if SMP
 	help
 	  Include support for the ARM(R) RealView(R) Platform Baseboard
 	  Explore.
arch/arm/mach-realview/realview_eb.c +29 -4
index 7a4e3b1..420cc1c 100644
@@ -36,7 +36,7 @@
 #include <asm/pgtable.h>
 #include <asm/hardware/gic.h>
 #include <asm/hardware/cache-l2x0.h>
-#include <asm/localtimer.h>
+#include <asm/smp_twd.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -391,6 +391,33 @@ static void realview_eb11mp_fixup(void)
 	realview_eb_isp1761_resources[1].end	= IRQ_EB11MP_USB;
 }
 
+#ifdef CONFIG_ARM_SMP_TWD
+static struct resource twd_resources[] __initdata = {
+	{
+		.start	= REALVIEW_EB11MP_TWD_BASE,
+		.end	= REALVIEW_EB11MP_TWD_BASE + 0xff,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= IRQ_LOCALTIMER,
+		.end	= IRQ_LOCALTIMER,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static void __init realview_eb_twd_init(void)
+{
+	if (core_tile_eb11mp() || core_tile_a9mp()) {
+		int err = twd_timer_register(twd_resources,
+					     ARRAY_SIZE(twd_resources));
+		if (err)
+			pr_err("twd_timer_register failed %d\n", err);
+	}
+}
+#else
+#define realview_eb_twd_init	NULL
+#endif
+
 static void __init realview_eb_timer_init(void)
 {
 	unsigned int timer_irq;
@@ -401,9 +428,7 @@ static void __init realview_eb_timer_init(void)
 	timer3_va_base = __io_address(REALVIEW_EB_TIMER2_3_BASE) + 0x20;
 
 	if (core_tile_eb11mp() || core_tile_a9mp()) {
-#ifdef CONFIG_LOCAL_TIMERS
-		twd_base = __io_address(REALVIEW_EB11MP_TWD_BASE);
-#endif
+		late_time_init = realview_eb_twd_init;
 		timer_irq = IRQ_EB11MP_TIMER0_1;
 	} else
 		timer_irq = IRQ_EB_TIMER0_1;
arch/arm/mach-realview/realview_pb11mp.c +27 -4
index b43644b..8185022 100644
@@ -36,7 +36,7 @@
 #include <asm/pgtable.h>
 #include <asm/hardware/gic.h>
 #include <asm/hardware/cache-l2x0.h>
-#include <asm/localtimer.h>
+#include <asm/smp_twd.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/flash.h>
@@ -298,6 +298,31 @@ static void __init gic_init_irq(void)
 	gic_cascade_irq(1, IRQ_TC11MP_PB_IRQ1);
 }
 
+#ifdef CONFIG_ARM_SMP_TWD
+static struct resource realview_pb11mp_twd_resources[] __initdata = {
+	{
+		.start	= REALVIEW_TC11MP_TWD_BASE,
+		.end	= REALVIEW_TC11MP_TWD_BASE + 0x10,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= IRQ_LOCALTIMER,
+		.end	= IRQ_LOCALTIMER,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static void __init realview_pb11mp_twd_init(void)
+{
+	int err = twd_timer_register(realview_pb11mp_twd_resources,
+				     ARRAY_SIZE(realview_pb11mp_twd_resources));
+	if (err)
+		pr_err("twd_timer_register failed %d\n", err);
+}
+#else
+#define realview_pb11mp_twd_init	NULL
+#endif
+
 static void __init realview_pb11mp_timer_init(void)
 {
 	timer0_va_base = __io_address(REALVIEW_PB11MP_TIMER0_1_BASE);
@@ -305,10 +330,8 @@ static void __init realview_pb11mp_timer_init(void)
 	timer2_va_base = __io_address(REALVIEW_PB11MP_TIMER2_3_BASE);
 	timer3_va_base = __io_address(REALVIEW_PB11MP_TIMER2_3_BASE) + 0x20;
 
-#ifdef CONFIG_LOCAL_TIMERS
-	twd_base = __io_address(REALVIEW_TC11MP_TWD_BASE);
-#endif
 	realview_timer_init(IRQ_TC11MP_TIMER0_1);
+	late_time_init = realview_pb11mp_twd_init;
 }
 
 static struct sys_timer realview_pb11mp_timer = {
arch/arm/mach-realview/realview_pbx.c +27 -3
index 363b0ab..bbe4534 100644
@@ -301,6 +301,31 @@ static void __init gic_init_irq(void)
 	}
 }
 
+#ifdef CONFIG_ARM_SMP_TWD
+static struct resource realview_pbx_twd_resources[] __initdata = {
+	{
+		.start	= REALVIEW_PBX_TILE_TWD_BASE,
+		.end	= REALVIEW_PBX_TILE_TWD_BASE + 0x10,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= IRQ_LOCALTIMER,
+		.end	= IRQ_LOCALTIMER,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static void __init realview_pbx_twd_init(void)
+{
+	int err = twd_timer_register(realview_pbx_twd_resources,
+				     ARRAY_SIZE(realview_pbx_twd_resources));
+	if (err)
+		pr_err("twd_timer_register failed %d\n", err);
+}
+#else
+#define realview_pbx_twd_init	NULL
+#endif
+
 static void __init realview_pbx_timer_init(void)
 {
 	timer0_va_base = __io_address(REALVIEW_PBX_TIMER0_1_BASE);
@@ -308,10 +333,9 @@ static void __init realview_pbx_timer_init(void)
 	timer2_va_base = __io_address(REALVIEW_PBX_TIMER2_3_BASE);
 	timer3_va_base = __io_address(REALVIEW_PBX_TIMER2_3_BASE) + 0x20;
 
-#ifdef CONFIG_LOCAL_TIMERS
 	if (core_tile_pbx11mp() || core_tile_pbxa9mp())
-		twd_base = __io_address(REALVIEW_PBX_TILE_TWD_BASE);
-#endif
+		late_time_init = realview_pbx_twd_init;
+
 	realview_timer_init(IRQ_PBX_TIMER0_1);
 }
 
Signature · 1 line
1.7.0.4
#3 lore raw

RFC PATCH 3/12 ARM: local timers: switch vexpress to standalone smp_twd

In reply to Marc Zyngier

Convert the Versatile Express platform to the standalone version of smp_twd.c. Since the timer calibration code requires another timer to be up and running, the actual initialisation is left to the late_timer_init hook.

---
 arch/arm/mach-vexpress/Kconfig    |    1 +
 arch/arm/mach-vexpress/ct-ca9x4.c |   29 ++++++++++++++++++++++++++---
 2 files changed, 27 insertions(+), 3 deletions(-)
arch/arm/mach-vexpress/Kconfig +1 -0
index 9311484..13f1606 100644
@@ -5,6 +5,7 @@ config ARCH_VEXPRESS_CA9X4
 	bool "Versatile Express Cortex-A9x4 tile"
 	select CPU_V7
 	select ARM_GIC
+	select ARM_SMP_TWD
 	select ARM_ERRATA_720789
 	select ARM_ERRATA_751472
 	select ARM_ERRATA_753970
arch/arm/mach-vexpress/ct-ca9x4.c +26 -3
index bfd32f5..7141d73 100644
@@ -53,9 +53,6 @@ static struct map_desc ct_ca9x4_io_desc[] __initdata = {
 
 static void __init ct_ca9x4_map_io(void)
 {
-#ifdef CONFIG_LOCAL_TIMERS
-	twd_base = MMIO_P2V(A9_MPCORE_TWD);
-#endif
 	iotable_init(ct_ca9x4_io_desc, ARRAY_SIZE(ct_ca9x4_io_desc));
 }
 
@@ -191,9 +188,35 @@ static struct platform_device pmu_device = {
 	.resource	= pmu_resources,
 };
 
+#ifdef CONFIG_ARM_SMP_TWD
+static struct resource ca9x4_twd_resources[] __initdata = {
+	{
+		.start	= A9_MPCORE_TWD,
+		.end	= A9_MPCORE_TWD + 0x10,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= IRQ_LOCALTIMER,
+		.end	= IRQ_LOCALTIMER,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static void __init ca9x4_twd_init(void)
+{
+	int err = twd_timer_register(ca9x4_twd_resources,
+				     ARRAY_SIZE(ca9x4_twd_resources));
+	if (err)
+		pr_err("twd_timer_register failed %d\n", err);
+}
+#else
+#define ca9x4_twd_init	NULL
+#endif
+
 static void __init ct_ca9x4_init_early(void)
 {
 	clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+	late_time_init = ca9x4_twd_init;
 }
 
 static void __init ct_ca9x4_init(void)
Signature · 1 line
1.7.0.4
#4 lore raw

RFC PATCH 4/12 ARM: local timers: remove localtimer.c from plat-versatile

In reply to Marc Zyngier

As the localtimer infrastructure is not use anymore by any of the Versatile platforms, remove localtimer.c.

---
 arch/arm/plat-versatile/Makefile     |    1 -
 arch/arm/plat-versatile/localtimer.c |   27 ---------------------------
 2 files changed, 0 insertions(+), 28 deletions(-)
 delete mode 100644 arch/arm/plat-versatile/localtimer.c
arch/arm/plat-versatile/Makefile +0 -1
index 69714db..a5cb194 100644
@@ -1,5 +1,4 @@
 obj-y	:= clock.o
-obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o
 obj-$(CONFIG_PLAT_VERSATILE_CLCD) += clcd.o
 obj-$(CONFIG_PLAT_VERSATILE_FPGA_IRQ) += fpga-irq.o
 obj-$(CONFIG_PLAT_VERSATILE_LEDS) += leds.o
arch/arm/plat-versatile/localtimer.c deleted +0 -27
deleted file mode 100644
index 0fb3961..0000000
@@ -1,27 +0,0 @@
-/*
- *  linux/arch/arm/plat-versatile/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/smp.h>
-#include <linux/clockchips.h>
-
-#include <asm/smp_twd.h>
-#include <asm/localtimer.h>
-#include <mach/irqs.h>
-
-/*
- * Setup the local clock events for a CPU.
- */
-int __cpuinit local_timer_setup(struct clock_event_device *evt)
-{
-	evt->irq = IRQ_LOCALTIMER;
-	twd_timer_setup(evt);
-	return 0;
-}
Signature · 1 line
1.7.0.4
#5 lore raw

RFC PATCH 5/12 ARM: local timers: switch tegra to standalone smp_twd

In reply to Marc Zyngier

Convert the Tegra-2 platforms to the standalone version of smp_twd.c. Since the timer calibration code requires another timer to be up and running, the actual initialisation is left to the late_timer_init hook.

Tested on Harmony.

Cc Colin Cross <[email protected]>
Cc Erik Gilling <[email protected]>
Cc Olof Johansson <[email protected]>
---
 arch/arm/mach-tegra/Kconfig      |    1 +
 arch/arm/mach-tegra/Makefile     |    2 +-
 arch/arm/mach-tegra/localtimer.c |   26 --------------------------
 arch/arm/mach-tegra/timer.c      |   34 +++++++++++++++++++++++++++++-----
 4 files changed, 31 insertions(+), 32 deletions(-)
 delete mode 100644 arch/arm/mach-tegra/localtimer.c
arch/arm/mach-tegra/Kconfig +1 -0
index d82ebab..6d6c396 100644
@@ -9,6 +9,7 @@ config ARCH_TEGRA_2x_SOC
 	bool "Tegra 2 family"
 	select CPU_V7
 	select ARM_GIC
+	select ARM_SMP_TWD
 	select ARCH_REQUIRE_GPIOLIB
 	select USB_ARCH_HAS_EHCI if USB_SUPPORT
 	select USB_ULPI if USB_SUPPORT
arch/arm/mach-tegra/Makefile +1 -1
index f11b910..c6b305f 100644
@@ -11,7 +11,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
arch/arm/mach-tegra/localtimer.c deleted +0 -26
deleted file mode 100644
index e91d681..0000000
@@ -1,26 +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/smp.h>
-#include <linux/clockchips.h>
-#include <asm/irq.h>
-#include <asm/smp_twd.h>
-#include <asm/localtimer.h>
-
-/*
- * Setup the local clock events for a CPU.
- */
-int __cpuinit local_timer_setup(struct clock_event_device *evt)
-{
-	evt->irq = IRQ_LOCALTIMER;
-	twd_timer_setup(evt);
-	return 0;
-}
arch/arm/mach-tegra/timer.c +29 -5
index 9035042..d8e26c4 100644
@@ -27,9 +27,10 @@
 #include <linux/clocksource.h>
 #include <linux/clk.h>
 #include <linux/io.h>
+#include <linux/ioport.h>
 
 #include <asm/mach/time.h>
-#include <asm/localtimer.h>
+#include <asm/smp_twd.h>
 #include <asm/sched_clock.h>
 
 #include <mach/iomap.h>
@@ -179,6 +180,31 @@ static struct irqaction tegra_timer_irq = {
 	.irq		= INT_TMR3,
 };
 
+#ifdef CONFIG_ARM_SMP_TWD
+static struct resource tegra_twd_resources[] __initdata = {
+	{
+		.start	= TEGRA_ARM_PERIF_BASE + 0x600,
+		.end	= TEGRA_ARM_PERIF_BASE + 0x610,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= IRQ_LOCALTIMER,
+		.end	= IRQ_LOCALTIMER,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static void __init tegra_twd_init(void)
+{
+	int err = twd_timer_register(tegra_twd_resources,
+				     ARRAY_SIZE(tegra_twd_resources));
+	if (err)
+		pr_err("twd_timer_register failed %d\n", err);
+}
+#else
+#define tegra_twd_init	NULL
+#endif
+
 static void __init tegra_init_timer(void)
 {
 	struct clk *clk;
@@ -197,10 +223,6 @@ static void __init tegra_init_timer(void)
 	BUG_ON(IS_ERR(clk));
 	clk_enable(clk);
 
-#ifdef CONFIG_HAVE_ARM_TWD
-	twd_base = IO_ADDRESS(TEGRA_ARM_PERIF_BASE + 0x600);
-#endif
-
 	switch (rate) {
 	case 12000000:
 		timer_writel(0x000b, TIMERUS_USEC_CFG);
@@ -241,6 +263,8 @@ static void __init tegra_init_timer(void)
 	tegra_clockevent.cpumask = cpu_all_mask;
 	tegra_clockevent.irq = tegra_timer_irq.irq;
 	clockevents_register_device(&tegra_clockevent);
+
+	late_time_init = tegra_twd_init;
 }
 
 struct sys_timer tegra_timer = {
Signature · 1 line
1.7.0.4
#6 lore raw

RFC PATCH 6/12 ARM: local timers: switch omap4 to standalone smp_twd

In reply to Marc Zyngier

Convert the OMAP4 platforms to the standalone version of smp_twd.c. Since the timer calibration code requires another timer to be up and running, the actual initialisation is left to the late_timer_init hook.

Tested on a Pandaboard.

---
 arch/arm/mach-omap2/Kconfig     |    2 +-
 arch/arm/mach-omap2/Makefile    |    1 -
 arch/arm/mach-omap2/timer-mpu.c |   39 ---------------------------------------
 arch/arm/mach-omap2/timer.c     |   38 +++++++++++++++++++++++++++++++++-----
 4 files changed, 34 insertions(+), 46 deletions(-)
 delete mode 100644 arch/arm/mach-omap2/timer-mpu.c
arch/arm/mach-omap2/Kconfig +1 -1
index 4ae6257..f8c0eb7 100644
@@ -44,7 +44,7 @@ config ARCH_OMAP4
 	depends on ARCH_OMAP2PLUS
 	select CPU_V7
 	select ARM_GIC
-	select LOCAL_TIMERS if SMP
+	select ARM_SMP_TWD
 	select PL310_ERRATA_588369
 	select PL310_ERRATA_727915
 	select ARM_ERRATA_720789
arch/arm/mach-omap2/Makefile +0 -1
index f343365..40ea7e2 100644
@@ -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
 
arch/arm/mach-omap2/timer-mpu.c deleted +0 -39
deleted file mode 100644
index 31c0ac4..0000000
@@ -1,39 +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 <[email protected]>
- *
- * 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/smp.h>
-#include <linux/clockchips.h>
-#include <asm/irq.h>
-#include <asm/smp_twd.h>
-#include <asm/localtimer.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 = OMAP44XX_IRQ_LOCALTIMER;
-	twd_timer_setup(evt);
-	return 0;
-}
-
arch/arm/mach-omap2/timer.c +33 -5
index e964072..5a4ce50 100644
@@ -38,7 +38,7 @@
 
 #include <asm/mach/time.h>
 #include <plat/dmtimer.h>
-#include <asm/localtimer.h>
+#include <asm/smp_twd.h>
 #include <asm/sched_clock.h>
 #include <plat/common.h>
 #include <plat/omap_hwmod.h>
@@ -328,15 +328,43 @@ OMAP_SYS_TIMER_INIT(3_secure, OMAP3_SECURE_TIMER, OMAP3_CLKEV_SOURCE,
 OMAP_SYS_TIMER(3_secure)
 #endif
 
+#ifdef CONFIG_ARM_SMP_TWD
+static struct resource omap4_twd_resources[] __initdata = {
+	{
+		.start	= OMAP44XX_LOCAL_TWD_BASE,
+		.end	= OMAP44XX_LOCAL_TWD_BASE + 0x10,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= OMAP44XX_IRQ_LOCALTIMER,
+		.end	= OMAP44XX_IRQ_LOCALTIMER,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static void __init omap4_twd_init(void)
+{
+	int err;
+
+	/* Local timers are not supprted on OMAP4430 ES1.0 */
+	if (omap_rev() == OMAP4430_REV_ES1_0)
+		return;
+
+	err = twd_timer_register(omap4_twd_resources,
+				 ARRAY_SIZE(omap4_twd_resources));
+	if (err)
+		pr_err("twd_timer_register failed %d\n", err);
+}
+#else
+#define omap4_twd_init	NULL
+#endif
+
 #ifdef CONFIG_ARCH_OMAP4
 static void __init omap4_timer_init(void)
 {
-#ifdef CONFIG_LOCAL_TIMERS
-	twd_base = ioremap(OMAP44XX_LOCAL_TWD_BASE, SZ_256);
-	BUG_ON(!twd_base);
-#endif
 	omap2_gp_clockevent_init(1, OMAP4_CLKEV_SOURCE);
 	omap2_gp_clocksource_init(2, OMAP4_MPU_SOURCE);
+	late_time_init = omap4_twd_init;
 }
 OMAP_SYS_TIMER(4)
 #endif
Signature · 1 line
1.7.0.4
#7 lore raw

RFC PATCH 7/12 ARM: local timers: switch shmobile to standalone smp_twd

In reply to Marc Zyngier

Convert the SMP shmobile platforms to the standalone version of smp_twd.c. As shmobile is already using the late_time_init hook, a private hook is added to initialise the TWD driver once the platform timer is up and running.

Cc Paul Mundt <[email protected]>
Cc Magnus Damm <[email protected]>
---
 arch/arm/mach-shmobile/Kconfig               |    1 +
 arch/arm/mach-shmobile/Makefile              |    1 -
 arch/arm/mach-shmobile/include/mach/common.h |    3 ++
 arch/arm/mach-shmobile/localtimer.c          |   26 ---------------------
 arch/arm/mach-shmobile/platsmp.c             |    1 -
 arch/arm/mach-shmobile/smp-sh73a0.c          |   32 +++++++++++++++++++++++--
 arch/arm/mach-shmobile/timer.c               |   10 ++++++++
 7 files changed, 43 insertions(+), 31 deletions(-)
 delete mode 100644 arch/arm/mach-shmobile/localtimer.c
arch/arm/mach-shmobile/Kconfig +1 -0
index 0c8f6cf..c2999b6 100644
@@ -23,6 +23,7 @@ config ARCH_SH7372
 config ARCH_SH73A0
 	bool "SH-Mobile AG5 (R8A73A00)"
 	select CPU_V7
+	select ARM_SMP_TWD
 	select SH_CLK_CPG
 	select ARCH_WANT_OPTIONAL_GPIOLIB
 	select ARM_GIC
arch/arm/mach-shmobile/Makefile +0 -1
index 612b270..82ec6e9 100644
@@ -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
arch/arm/mach-shmobile/include/mach/common.h +3 -0
index 06aecb3..39a2637 100644
@@ -53,4 +53,7 @@ extern void sh73a0_secondary_init(unsigned int cpu);
 extern int sh73a0_boot_secondary(unsigned int cpu);
 extern void sh73a0_smp_prepare_cpus(void);
 
+struct resource;
+extern void shmobile_local_timer_register(void (*)(void));
+
 #endif /* __ARCH_MACH_COMMON_H */
arch/arm/mach-shmobile/localtimer.c deleted +0 -26
deleted file mode 100644
index ad9ccc9..0000000
@@ -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>
-
-/*
- * Setup the local clock events for a CPU.
- */
-int __cpuinit local_timer_setup(struct clock_event_device *evt)
-{
-	evt->irq = 29;
-	twd_timer_setup(evt);
-	return 0;
-}
arch/arm/mach-shmobile/platsmp.c +0 -1
index 66f9806..b5dcc57 100644
@@ -17,7 +17,6 @@
 #include <linux/smp.h>
 #include <linux/io.h>
 #include <asm/hardware/gic.h>
-#include <asm/localtimer.h>
 #include <asm/mach-types.h>
 #include <mach/common.h>
 
arch/arm/mach-shmobile/smp-sh73a0.c +29 -3
index 3ffdbc9..8506437 100644
@@ -22,6 +22,7 @@
 #include <linux/smp.h>
 #include <linux/spinlock.h>
 #include <linux/io.h>
+#include <linux/ioport.h>
 #include <mach/common.h>
 #include <asm/smp_scu.h>
 #include <asm/smp_twd.h>
@@ -41,6 +42,31 @@ static void __iomem *scu_base_addr(void)
 static DEFINE_SPINLOCK(scu_lock);
 static unsigned long tmp;
 
+#ifdef CONFIG_ARM_SMP_TWD
+static struct resource sh73a0_twd_resources[] __initdata = {
+	{
+		.start	= 0xf0000600,
+		.end	= 0xf0000600 + 0x10,
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= 29,
+		.end	= 29,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static void __init sh73a0_twd_init(void)
+{
+	int err = twd_timer_register(sh73a0_twd_resources,
+				     ARRAY_SIZE(sh73a0_twd_resources));
+	if (err)
+		pr_err("twd_timer_register failed %d\n", err);
+}
+#else
+#define sh73a0_twd_init	NULL
+#endif
+
 static void modify_scu_cpu_psr(unsigned long set, unsigned long clr)
 {
 	void __iomem *scu_base = scu_base_addr();
@@ -59,9 +85,9 @@ unsigned int __init sh73a0_get_core_count(void)
 {
 	void __iomem *scu_base = scu_base_addr();
 
-#ifdef CONFIG_HAVE_ARM_TWD
-	/* twd_base needs to be initialized before percpu_timer_setup() */
-	twd_base = (void __iomem *)0xf0000600;
+
+#ifdef CONFIG_ARM_SMP_TWD
+	shmobile_local_timer_register(sh73a0_twd_init);
 #endif
 
 	return scu_get_core_count(scu_base);
arch/arm/mach-shmobile/timer.c +10 -0
index 895794b..fad385d 100644
@@ -19,8 +19,11 @@
  *
  */
 #include <linux/platform_device.h>
+#include <mach/common.h>
 #include <asm/mach/time.h>
 
+static void (*local_timer_hook)(void) __initdata;
+
 static void __init shmobile_late_time_init(void)
 {
 	/*
@@ -34,6 +37,8 @@ static void __init shmobile_late_time_init(void)
 	 */
 	early_platform_driver_register_all("earlytimer");
 	early_platform_driver_probe("earlytimer", 2, 0);
+	if (local_timer_hook)
+		local_timer_hook();
 }
 
 static void __init shmobile_timer_init(void)
@@ -41,6 +46,11 @@ static void __init shmobile_timer_init(void)
 	late_time_init = shmobile_late_time_init;
 }
 
+void __init shmobile_local_timer_register(void (*hook)(void))
+{
+	local_timer_hook = hook;
+}
+
 struct sys_timer shmobile_timer = {
 	.init		= shmobile_timer_init,
 };
Signature · 1 line
1.7.0.4
#8 lore raw

RFC PATCH 8/12 ARM: local timers: switch ux500 to standalone smp_twd

In reply to Marc Zyngier

Convert the ux500 platforms to the standalone version of smp_twd.c. Since the timer calibration code requires another timer to be up and running, the actual initialisation is left to the late_timer_init hook.

---
 arch/arm/mach-ux500/Kconfig      |    1 +
 arch/arm/mach-ux500/Makefile     |    1 -
 arch/arm/mach-ux500/cpu.c        |   40 +++++++++++++++++++++++++++++++------
 arch/arm/mach-ux500/localtimer.c |   29 ---------------------------
 4 files changed, 34 insertions(+), 37 deletions(-)
 delete mode 100644 arch/arm/mach-ux500/localtimer.c
arch/arm/mach-ux500/Kconfig +1 -0
index 4210cb4..3b1f972 100644
@@ -4,6 +4,7 @@ config UX500_SOC_COMMON
 	bool
 	default y
 	select ARM_GIC
+	select ARM_SMP_TWD
 	select HAS_MTU
 	select ARM_ERRATA_753970
 
arch/arm/mach-ux500/Makefile +0 -1
index 1694916..2e30a80 100644
@@ -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
 
arch/arm/mach-ux500/cpu.c +33 -7
index 1da23bb..ec622b6 100644
@@ -15,7 +15,7 @@
 #include <asm/hardware/cache-l2x0.h>
 #include <asm/hardware/gic.h>
 #include <asm/mach/map.h>
-#include <asm/localtimer.h>
+#include <asm/smp_twd.h>
 
 #include <plat/mtu.h>
 #include <mach/hardware.h>
@@ -120,15 +120,40 @@ static int ux500_l2x0_init(void)
 early_initcall(ux500_l2x0_init);
 #endif
 
+#ifdef CONFIG_ARM_SMP_TWD
+static struct resource ux500_twd_resources[] __initdata = {
+	{
+		.flags	= IORESOURCE_MEM,
+	},
+	{
+		.start	= IRQ_LOCALTIMER,
+		.end	= IRQ_LOCALTIMER,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static void __init ux500_twd_init(void)
+{
+	int err = twd_timer_register(ux500_twd_resources,
+				     ARRAY_SIZE(ux500_twd_resources));
+	if (err)
+		pr_err("twd_timer_register failed %d\n", err);
+}
+#else
+#define ux500_twd_init	NULL
+#endif
+
 static void __init ux500_timer_init(void)
 {
-#ifdef CONFIG_LOCAL_TIMERS
+#ifdef CONFIG_ARM_SMP_TWD
 	/* Setup the local timer base */
-	if (cpu_is_u5500())
-		twd_base = __io_address(U5500_TWD_BASE);
-	else if (cpu_is_u8500())
-		twd_base = __io_address(U8500_TWD_BASE);
-	else
+	if (cpu_is_u5500()) {
+		ux500_twd_resources[0].start = U5500_TWD_BASE;
+		ux500_twd_resources[0]end = U5500_TWD_BASE + 0x10;
+	} else if (cpu_is_u8500()) {
+		ux500_twd_resources[0].start = U8500_TWD_BASE;
+		ux500_twd_resources[0]end = U8500_TWD_BASE + 0x10;
+	} else
 		ux500_unknown_soc();
 #endif
 	if (cpu_is_u5500())
@@ -141,6 +166,7 @@ static void __init ux500_timer_init(void)
 		ux500_unknown_soc();
 
 	nmdk_timer_init();
+	late_time_init = ux500_twd_init;
 }
 
 struct sys_timer ux500_timer = {
arch/arm/mach-ux500/localtimer.c deleted +0 -29
deleted file mode 100644
index 5ba1133..0000000
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2008-2009 ST-Ericsson
- * Srinidhi Kasagar <[email protected]>
- *
- * 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/smp.h>
-#include <linux/clockchips.h>
-
-#include <asm/irq.h>
-#include <asm/smp_twd.h>
-#include <asm/localtimer.h>
-
-/*
- * Setup the local clock events for a CPU.
- */
-int __cpuinit local_timer_setup(struct clock_event_device *evt)
-{
-	evt->irq = IRQ_LOCALTIMER;
-	twd_timer_setup(evt);
-	return 0;
-}
Signature · 1 line
1.7.0.4
#9 lore raw

RFC PATCH 8/12 ARM: local timers: switch ux500 to standalone smp_twd

Quoted 8 lines · Marc Zyngier

Convert the ux500 platforms to the standalone version of smp_twd.c. Since the timer calibration code requires another timer to be up and running, the actual initialisation is left to the late_timer_init hook.

So it switch to ioremap():ing the TWD too.
Seems like a pretty good idea.

Yours,
Linus Walleij

#10 lore raw

RFC PATCH 9/12 ARM: smp_twd: remove support for non-standalone version

In reply to Marc Zyngier

There is no in-tree platform using both CONFIG_LOCAL_TIMERS and CONFIG_HAVE_ARM_TWD. As such, some code can be removed and some exported function of smp_twd.c can be made static.

---
 arch/arm/Kconfig                  |    1 -
 arch/arm/include/asm/localtimer.h |   10 ----------
 arch/arm/include/asm/smp_twd.h    |    5 -----
 arch/arm/kernel/smp_twd.c         |   10 +++-------
 4 files changed, 3 insertions(+), 23 deletions(-)
arch/arm/Kconfig +0 -1
index 7ac28a3..12cbeba 100644
@@ -1438,7 +1438,6 @@ config LOCAL_TIMERS
 	bool "Use local timer interrupts"
 	depends on SMP && !ARM_SMP_TWD
 	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
arch/arm/include/asm/localtimer.h +0 -10
index f5e1cec..af5c371 100644
@@ -21,21 +21,11 @@ void percpu_timer_setup(void);
 
 #ifdef CONFIG_LOCAL_TIMERS
 
-#ifdef CONFIG_HAVE_ARM_TWD
-
-#include "smp_twd.h"
-
-#define local_timer_stop(c)	twd_timer_stop((c))
-
-#else
-
 /*
  * Stop the local timer
  */
 void local_timer_stop(struct clock_event_device *);
 
-#endif
-
 /*
  * Setup a local timer interrupt for a CPU.
  */
arch/arm/include/asm/smp_twd.h +0 -5
index 934f1bc..0da6438 100644
@@ -18,13 +18,8 @@
 #define TWD_TIMER_CONTROL_PERIODIC	(1 << 1)
 #define TWD_TIMER_CONTROL_IT_ENABLE	(1 << 2)
 
-struct clock_event_device;
 struct resource;
 
-extern void __iomem *twd_base;
-
-void twd_timer_setup(struct clock_event_device *);
-void twd_timer_stop(struct clock_event_device *);
 #ifdef CONFIG_HAVE_ARM_TWD
 int twd_timer_register(struct resource *res, int res_nr);
 #else
arch/arm/kernel/smp_twd.c +3 -7
index 5b6d99b..0a9106d 100644
@@ -20,11 +20,9 @@
 #include <linux/io.h>
 
 #include <asm/smp_twd.h>
-#include <asm/localtimer.h>
 #include <asm/hardware/gic.h>
 
-/* set up by the platform code */
-void __iomem *twd_base;
+static void __iomem *twd_base;
 
 static unsigned long twd_timer_rate;
 
@@ -79,7 +77,7 @@ static irqreturn_t twd_timer_handler(int irq, void *dev_id)
 	return IRQ_NONE;
 }
 
-void twd_timer_stop(struct clock_event_device *clk)
+static void twd_timer_stop(struct clock_event_device *clk)
 {
 	twd_set_mode(CLOCK_EVT_MODE_UNUSED, clk);
 	gic_free_ppi(clk->irq, clk);
@@ -127,7 +125,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_timer_setup(struct clock_event_device *clk)
 {
 	int err;
 
@@ -152,7 +150,6 @@ void __cpuinit twd_timer_setup(struct clock_event_device *clk)
 		       clk->name, clk->irq, smp_processor_id(), err);
 }
 
-#ifdef CONFIG_ARM_SMP_TWD
 static struct clock_event_device __percpu *twd_evt;
 static int twd_ppi;
 
@@ -223,4 +220,3 @@ int twd_timer_register(struct resource *res, int res_nr)
 
 	return 0;
 }
-#endif
Signature · 1 line
1.7.0.4
#11 lore raw

RFC PATCH 10/12 ARM: local timers: make MSM timers standalone

In reply to Marc Zyngier

Following the same pattern used for smp_twd, allow the MSM timers to be built in standalone, without relying on the CONFIG_LOCAL_TIMER infrastructure and use a CPU notifier block to stop or start the timer on the secondary CPU.

Cc David Brown <[email protected]>
Cc Stephen Boyd <[email protected]>
---
 arch/arm/Kconfig          |    2 +-
 arch/arm/mach-msm/timer.c |   64 +++++++++++++++++++++++++++++++++------------
 2 files changed, 48 insertions(+), 18 deletions(-)
arch/arm/Kconfig +1 -1
index 12cbeba..13cdba4 100644
@@ -1436,7 +1436,7 @@ config HOTPLUG_CPU
 
 config LOCAL_TIMERS
 	bool "Use local timer interrupts"
-	depends on SMP && !ARM_SMP_TWD
+	depends on SMP && !ARM_SMP_TWD && !ARCH_MSM
 	default y
 	help
 	  Enable support for local timers on SMP platforms, rather then the
arch/arm/mach-msm/timer.c +47 -17

116 lines not on this page · raw message

Signature · 1 line
1.7.0.4
#12 lore raw

RFC PATCH 11/12 ARM: local timers: make MCT timer standalone

In reply to Marc Zyngier

Following the same pattern used for smp_twd, allow the MCT timers to be built in standalone, without relying on the CONFIG_LOCAL_TIMER infrastructure and use a CPU notifier block to stop or start the timer on the right CPU.

---
 arch/arm/Kconfig            |    2 +-
 arch/arm/mach-exynos4/mct.c |   75 ++++++++++++++++++++++++++++++++----------
 2 files changed, 58 insertions(+), 19 deletions(-)
arch/arm/Kconfig +1 -1
index 13cdba4..ef67b64 100644
@@ -1436,7 +1436,7 @@ config HOTPLUG_CPU
 
 config LOCAL_TIMERS
 	bool "Use local timer interrupts"
-	depends on SMP && !ARM_SMP_TWD && !ARCH_MSM
+	depends on SMP && !ARM_SMP_TWD && !ARCH_MSM && !EXYNOS4_MCT
 	default y
 	help
 	  Enable support for local timers on SMP platforms, rather then the
arch/arm/mach-exynos4/mct.c +57 -18

151 lines not on this page · raw message

Signature · 1 line
1.7.0.4
#13 lore raw

RFC PATCH 12/12 ARM: local timers: Remove CONFIG_LOCAL_TIMERS support

In reply to Marc Zyngier

Local timer support in arch/arm is now completely unused, as all in-tree platforms are using standalone timers.

It allows us to simplify the code, only preserving the broadcast timer. The broadcast timer is always installed, and we leave it up to the kernel to pick the more suitable timer (usually the one with the highest priority).

---
 arch/arm/Kconfig                  |   10 ------
 arch/arm/include/asm/localtimer.h |   46 ------------------------------
 arch/arm/kernel/smp.c             |   56 +++++++++---------------------------
 3 files changed, 14 insertions(+), 98 deletions(-)
 delete mode 100644 arch/arm/include/asm/localtimer.h
arch/arm/Kconfig +0 -10
index ef67b64..9aba6c2 100644
@@ -1434,16 +1434,6 @@ config HOTPLUG_CPU
 	  Say Y here to experiment with turning CPUs off and on.  CPUs
 	  can be controlled through /sys/devices/system/cpu.
 
-config LOCAL_TIMERS
-	bool "Use local timer interrupts"
-	depends on SMP && !ARM_SMP_TWD && !ARCH_MSM && !EXYNOS4_MCT
-	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.
-
 source kernel/Kconfig.preempt
 
 config HZ
arch/arm/include/asm/localtimer.h deleted +0 -46

46 lines not on this page · raw message

arch/arm/kernel/smp.c +14 -42

117 lines not on this page · raw message

Signature · 1 line
1.7.0.4