* [RFC PATCH 10/20] ARM: Platform dependent sched_clock() override
From: Marc Zyngier @ 2011-03-02 16:53 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1299084806-16546-1-git-send-email-marc.zyngier@arm.com>
sched_clock being a (weak) global symbol, there can only be
a single implementation in the kernel, which may cause problems
on the rocky road towards supporting multiple architectures in
a single kernel image.
This patch adds a way of overriding the default sched_clock()
by extending the ARM sched_clock framework. The sched_clock()
call also becomes slightly more expensive (indirect function call).
VExpress support is updated to use that functionnality.
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
arch/arm/Kconfig | 9 +++++++
arch/arm/include/asm/sched_clock.h | 41 +++++++++++++++++++++++++++++---
arch/arm/kernel/sched_clock.c | 23 +++++++++++++++++-
arch/arm/plat-versatile/sched-clock.c | 7 +++--
4 files changed, 72 insertions(+), 8 deletions(-)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 316da4b..26fde47 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -48,6 +48,14 @@ config SYS_SUPPORTS_APM_EMULATION
config HAVE_SCHED_CLOCK
bool
+config ARCH_SCHED_CLOCK
+ bool
+ help
+ Allow the default sched_clock() to be overloaded at runtime.
+ Use this option if you build a kernel for a platform with
+ multiplee sched_clock sources, one of which will be selected
+ at runtime.
+
config GENERIC_GPIO
bool
@@ -271,6 +279,7 @@ config ARCH_VEXPRESS
select ARM_TIMER_SP804
select CLKDEV_LOOKUP
select GENERIC_CLOCKEVENTS
+ select ARCH_SCHED_CLOCK
select HAVE_CLK
select HAVE_PATA_PLATFORM
select ICST
diff --git a/arch/arm/include/asm/sched_clock.h b/arch/arm/include/asm/sched_clock.h
index c8e6ddf..27ef05e 100644
--- a/arch/arm/include/asm/sched_clock.h
+++ b/arch/arm/include/asm/sched_clock.h
@@ -21,6 +21,17 @@ struct clock_data {
#define DEFINE_CLOCK_DATA(name) struct clock_data name
+#ifdef CONFIG_ARCH_SCHED_CLOCK
+#define __DEFINE_SCHED_CLOCK_ALIAS(name)
+#else
+#define __DEFINE_SCHED_CLOCK_ALIAS(name) \
+ unsigned long long sched_clock(void) __attribute__ ((alias (#name)));
+#endif
+
+#define DEFINE_SCHED_CLOCK_FUNC(name) \
+ __DEFINE_SCHED_CLOCK_ALIAS(name) \
+ static unsigned long long notrace name(void)
+
static inline u64 cyc_to_ns(u64 cyc, u32 mult, u32 shift)
{
return (cyc * mult) >> shift;
@@ -94,20 +105,35 @@ static inline unsigned long long cyc_to_sched_clock(struct clock_data *cd,
* and shift. Also setup a timer to ensure that the epoch is refreshed
* at the appropriate time interval, which will call your update
* handler.
+ *
+ * Use the _arch_ version if you want your sched_clock function to be
+ * selected at run time (if CONFIG_ARCH_SCHED_CLOCK is enabled).
*/
-void init_sched_clock(struct clock_data *, void (*)(void),
+void init_arch_sched_clock(struct clock_data *, void (*)(void),
+ unsigned long long (*)(void),
unsigned int, unsigned long);
+static inline void init_sched_clock(struct clock_data *cd,
+ void (*update)(void),
+ unsigned int bits, unsigned long rate)
+{
+ init_arch_sched_clock(cd, update, NULL, bits, rate);
+}
+
/*
* Use this initialization function rather than init_sched_clock() if
* you're using cyc_to_fixed_sched_clock, which will warn if your
* constants are incorrect.
+ *
+ * Use the _arch_ version if you want your sched_clock function to be
+ * selected at run time (if CONFIG_ARCH_SCHED_CLOCK is enabled).
*/
-static inline void init_fixed_sched_clock(struct clock_data *cd,
- void (*update)(void), unsigned int bits, unsigned long rate,
+static inline void init_fixed_arch_sched_clock(struct clock_data *cd,
+ void (*update)(void), unsigned long long (*sched_clock_fn)(void),
+ unsigned int bits, unsigned long rate,
u32 mult, u32 shift)
{
- init_sched_clock(cd, update, bits, rate);
+ init_arch_sched_clock(cd, update, sched_clock_fn, bits, rate);
if (cd->mult != mult || cd->shift != shift) {
pr_crit("sched_clock: wrong multiply/shift: %u>>%u vs calculated %u>>%u\n"
"sched_clock: fix multiply/shift to avoid scheduler hiccups\n",
@@ -115,6 +141,13 @@ static inline void init_fixed_sched_clock(struct clock_data *cd,
}
}
+static inline void init_fixed_sched_clock(struct clock_data *cd,
+ void (*update)(void), unsigned int bits, unsigned long rate,
+ u32 mult, u32 shift)
+{
+ init_fixed_arch_sched_clock(cd, update, NULL, bits, rate, mult, shift);
+}
+
extern void sched_clock_postinit(void);
#endif
diff --git a/arch/arm/kernel/sched_clock.c b/arch/arm/kernel/sched_clock.c
index 9a46370..3c1d08b 100644
--- a/arch/arm/kernel/sched_clock.c
+++ b/arch/arm/kernel/sched_clock.c
@@ -18,13 +18,29 @@ static void sched_clock_poll(unsigned long wrap_ticks);
static DEFINE_TIMER(sched_clock_timer, sched_clock_poll, 0, 0);
static void (*sched_clock_update_fn)(void);
+#ifdef CONFIG_ARCH_SCHED_CLOCK
+static unsigned long long notrace default_sched_clock(void)
+{
+ return (unsigned long long)(jiffies - INITIAL_JIFFIES)
+ * (NSEC_PER_SEC / HZ);
+}
+
+static unsigned long long __read_mostly (*sched_clock_fn)(void) = default_sched_clock;
+
+unsigned long long notrace sched_clock(void)
+{
+ return sched_clock_fn();
+}
+#endif
+
static void sched_clock_poll(unsigned long wrap_ticks)
{
mod_timer(&sched_clock_timer, round_jiffies(jiffies + wrap_ticks));
sched_clock_update_fn();
}
-void __init init_sched_clock(struct clock_data *cd, void (*update)(void),
+void __init init_arch_sched_clock(struct clock_data *cd, void (*update)(void),
+ unsigned long long (*arch_sched_clock_fn)(void),
unsigned int clock_bits, unsigned long rate)
{
unsigned long r, w;
@@ -33,6 +49,11 @@ void __init init_sched_clock(struct clock_data *cd, void (*update)(void),
sched_clock_update_fn = update;
+#ifdef CONFIG_ARCH_SCHED_CLOCK
+ if (arch_sched_clock_fn)
+ sched_clock_fn = arch_sched_clock_fn;
+#endif
+
/* calculate the mult/shift to convert counter ticks to ns. */
clocks_calc_mult_shift(&cd->mult, &cd->shift, rate, NSEC_PER_SEC, 0);
diff --git a/arch/arm/plat-versatile/sched-clock.c b/arch/arm/plat-versatile/sched-clock.c
index 3d6a4c2..d6ebd0f 100644
--- a/arch/arm/plat-versatile/sched-clock.c
+++ b/arch/arm/plat-versatile/sched-clock.c
@@ -34,7 +34,7 @@ static void __iomem *ctr;
#define SC_MULT 2796202667u
#define SC_SHIFT 26
-unsigned long long notrace sched_clock(void)
+DEFINE_SCHED_CLOCK_FUNC(versatile_sched_clock)
{
if (ctr) {
u32 cyc = readl(ctr);
@@ -53,6 +53,7 @@ static void notrace versatile_update_sched_clock(void)
void __init versatile_sched_clock_init(void __iomem *reg, unsigned long rate)
{
ctr = reg;
- init_fixed_sched_clock(&cd, versatile_update_sched_clock,
- 32, rate, SC_MULT, SC_SHIFT);
+ init_fixed_arch_sched_clock(&cd, versatile_update_sched_clock,
+ versatile_sched_clock,
+ 32, rate, SC_MULT, SC_SHIFT);
}
--
1.7.0.4
^ permalink raw reply related
* [RFC PATCH 09/20] ARM: architected timers: add A15 architected timers
From: Marc Zyngier @ 2011-03-02 16:53 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1299084806-16546-1-git-send-email-marc.zyngier@arm.com>
The ARM architecture provides a set of optional system timers that
can be used as clocksources for local timer events.
This patch adds support for these timers, giving them priority over
any private timers if they are detected at runtime.
A global counter is also used to implement a clock source.
Acked-by: Will Deacon <will.deacon@arm.com>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
arch/arm/Kconfig | 7 +-
arch/arm/include/asm/arch_timer.h | 13 ++
arch/arm/include/asm/hardware/entry-macro-gic.S | 18 ++
arch/arm/kernel/Makefile | 1 +
arch/arm/kernel/arch_timer.c | 223 +++++++++++++++++++++++
5 files changed, 261 insertions(+), 1 deletions(-)
create mode 100644 arch/arm/include/asm/arch_timer.h
create mode 100644 arch/arm/kernel/arch_timer.c
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 96d677a..316da4b 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1369,9 +1369,14 @@ config HOTPLUG_CPU
Say Y here to experiment with turning CPUs off and on. CPUs
can be controlled through /sys/devices/system/cpu.
+config HAVE_ARCH_TIMERS
+ bool
+ depends on CPU_V7
+ select TICK_ONESHOT
+
config LOCAL_TIMERS
bool
- depends on SMP || ARCH_MSM_SCORPIONMP
+ depends on SMP || HAVE_ARCH_TIMERS || ARCH_MSM_SCORPIONMP
default y
help
Enable support for local timers on SMP platforms, rather then the
diff --git a/arch/arm/include/asm/arch_timer.h b/arch/arm/include/asm/arch_timer.h
new file mode 100644
index 0000000..f98263c
--- /dev/null
+++ b/arch/arm/include/asm/arch_timer.h
@@ -0,0 +1,13 @@
+#ifndef __ASMARM_ARCH_TIMER_H
+#define __ASMARM_ARCH_TIMER_H
+
+#ifdef CONFIG_HAVE_ARCH_TIMERS
+int arch_timer_register_setup(void (*setup)(struct clock_event_device *));
+#else
+static inline int arch_timer_register_setup(void (*setup)(struct clock_event_device *))
+{
+ return -ENODEV;
+}
+#endif
+
+#endif
diff --git a/arch/arm/include/asm/hardware/entry-macro-gic.S b/arch/arm/include/asm/hardware/entry-macro-gic.S
index c115b82..b362a1e 100644
--- a/arch/arm/include/asm/hardware/entry-macro-gic.S
+++ b/arch/arm/include/asm/hardware/entry-macro-gic.S
@@ -67,8 +67,26 @@
.macro test_for_ltirq, irqnr, irqstat, base, tmp
bic \irqnr, \irqstat, #0x1c00
+#ifdef CONFIG_HAVE_ARCH_TIMERS
+ /*
+ * We need to check for both PPI 29 and 30, as we have no way
+ * to know whether we're running in normal or secure mode.
+ * We cannot check for the architected timers being available,
+ * as the feature register may be virtualised (slow access).
+ * Check for an A15 instead.
+ * If this matches, check for PPI 30. Otherwise, fallback
+ * to the the usual 29.
+ */
+ mrc p15, 0, \tmp, c0, c0, 0
+ and \tmp, \tmp, #0xff0
+ teq \tmp, #0x0f0
+ cmpeq \irqnr, #30
+ movne \tmp, #0
+ cmpne \irqnr, #29
+#else
mov \tmp, #0
cmp \irqnr, #29
+#endif
moveq \tmp, #1
streq \irqstat, [\base, #GIC_CPU_EOI]
cmp \tmp, #0
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index 277f6ff..add5e77 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -33,6 +33,7 @@ obj-$(CONFIG_PM) += sleep.o
obj-$(CONFIG_HAVE_SCHED_CLOCK) += sched_clock.o
obj-$(CONFIG_SMP) += smp.o smp_tlb.o
obj-$(CONFIG_HAVE_ARM_SCU) += smp_scu.o
+obj-$(CONFIG_HAVE_ARCH_TIMERS) += arch_timer.o
obj-$(CONFIG_HAVE_ARM_TWD) += smp_twd.o
obj-$(CONFIG_LOCAL_TIMERS) += percpu_timer.o
obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o
diff --git a/arch/arm/kernel/arch_timer.c b/arch/arm/kernel/arch_timer.c
new file mode 100644
index 0000000..bc05604
--- /dev/null
+++ b/arch/arm/kernel/arch_timer.c
@@ -0,0 +1,223 @@
+/*
+ * linux/arch/arm/kernel/arch_timer.c
+ *
+ * Copyright (C) 2011 ARM Ltd.
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/smp.h>
+#include <linux/jiffies.h>
+#include <linux/clockchips.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+
+#include <asm/cputype.h>
+#include <asm/localtimer.h>
+#include <asm/hardware/gic.h>
+
+static unsigned long arch_timer_rate;
+
+/*
+ * Architected system timer support.
+ */
+
+#define ARCH_TIMER_CTRL_ENABLE (1 << 0)
+#define ARCH_TIMER_CTRL_IT_MASK (1 << 1)
+
+#define ARCH_TIMER_REG_CTRL 0
+#define ARCH_TIMER_REG_FREQ 1
+#define ARCH_TIMER_REG_TVAL 2
+
+static void arch_timer_reg_write(int reg, u32 val)
+{
+ switch (reg) {
+ case ARCH_TIMER_REG_CTRL:
+ asm volatile("mcr p15, 0, %0, c14, c2, 1" : : "r" (val));
+ break;
+ case ARCH_TIMER_REG_TVAL:
+ asm volatile("mcr p15, 0, %0, c14, c2, 0" : : "r" (val));
+ break;
+ }
+
+ isb();
+}
+
+static u32 arch_timer_reg_read(int reg)
+{
+ u32 val;
+
+ switch (reg) {
+ case ARCH_TIMER_REG_CTRL:
+ asm volatile("mrc p15, 0, %0, c14, c2, 1" : "=r" (val));
+ break;
+ case ARCH_TIMER_REG_FREQ:
+ asm volatile("mrc p15, 0, %0, c14, c0, 0" : "=r" (val));
+ break;
+ case ARCH_TIMER_REG_TVAL:
+ asm volatile("mrc p15, 0, %0, c14, c2, 0" : "=r" (val));
+ break;
+ default:
+ BUG();
+ }
+
+ return val;
+}
+
+static int arch_timer_ack(void)
+{
+ unsigned long ctrl;
+
+ ctrl = arch_timer_reg_read(ARCH_TIMER_REG_CTRL);
+ if (ctrl & 0x4) {
+ ctrl |= ARCH_TIMER_CTRL_IT_MASK;
+ arch_timer_reg_write(ARCH_TIMER_REG_CTRL, ctrl);
+ return 1;
+ }
+
+ return 0;
+}
+
+static void arch_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *clk)
+{
+}
+
+static int arch_set_next_event(unsigned long evt,
+ struct clock_event_device *unused)
+{
+ unsigned long ctrl;
+
+ ctrl = arch_timer_reg_read(ARCH_TIMER_REG_CTRL);
+ ctrl |= ARCH_TIMER_CTRL_ENABLE;
+ ctrl &= ~ARCH_TIMER_CTRL_IT_MASK;
+
+ arch_timer_reg_write(ARCH_TIMER_REG_TVAL, evt);
+ arch_timer_reg_write(ARCH_TIMER_REG_CTRL, ctrl);
+
+ return 0;
+}
+
+static void __cpuinit arch_timer_pre_setup(struct clock_event_device *clk)
+{
+ unsigned long ctrl;
+
+ /* Let's make sure the timer is off before doing anything else */
+ ctrl = arch_timer_reg_read(ARCH_TIMER_REG_CTRL);
+ ctrl &= ~ARCH_TIMER_CTRL_ENABLE;
+ arch_timer_reg_write(ARCH_TIMER_REG_CTRL, ctrl);
+}
+
+static void __cpuinit arch_timer_setup(struct clock_event_device *clk)
+{
+ clk->features = CLOCK_EVT_FEAT_ONESHOT;
+ clk->name = "arch_sys_timer";
+ clk->rating = 350;
+ clockevents_calc_mult_shift(clk, arch_timer_rate, 4);
+
+ clk->max_delta_ns = clockevent_delta2ns(0xffffffff, clk);
+ clk->min_delta_ns = clockevent_delta2ns(0xf, clk);
+ clk->set_mode = arch_set_mode;
+ clk->set_next_event = arch_set_next_event;
+
+ /* Make sure our local interrupt controller has this enabled */
+ gic_enable_ppi(clk->irq);
+
+ clockevents_register_device(clk);
+}
+
+static struct local_timer_ops arch_timer_ops = {
+ .pre_setup = arch_timer_pre_setup,
+ .setup = arch_timer_setup,
+ .ack = arch_timer_ack,
+};
+
+/* Is the optional system timer available? */
+static int local_timer_is_architected(void)
+{
+ return (cpu_architecture() >= CPU_ARCH_ARMv7) &&
+ ((read_cpuid_ext(CPUID_EXT_PFR1) >> 16) & 0xf) == 1;
+}
+
+static int arch_timer_available(void)
+{
+ unsigned long freq;
+
+ if (!local_timer_is_architected())
+ return 0;
+
+ if (arch_timer_rate == 0) {
+ arch_timer_reg_write(ARCH_TIMER_REG_CTRL, 0);
+ freq = arch_timer_reg_read(ARCH_TIMER_REG_FREQ);
+
+ /* Check the timer frequency. */
+ if (freq == 0) {
+ pr_warn("Architected timer frequency not available\n");
+ return 0;
+ }
+
+ arch_timer_rate = freq;
+ pr_info("Architected local timer running at %lu.%02luMHz.\n",
+ arch_timer_rate / 1000000, (arch_timer_rate / 100000) % 100);
+ }
+
+ return 1;
+}
+
+static inline cycle_t arch_counter_get_cntpct(void)
+{
+ u32 cvall, cvalh;
+
+ asm volatile("mrrc p15, 0, %0, %1, c14" : "=r" (cvall), "=r" (cvalh));
+
+ return ((u64) cvalh << 32) | cvall;
+}
+
+static inline cycle_t arch_counter_get_cntvct(void)
+{
+ u32 cvall, cvalh;
+
+ asm volatile("mrrc p15, 1, %0, %1, c14" : "=r" (cvall), "=r" (cvalh));
+
+ return ((u64) cvalh << 32) | cvall;
+}
+
+static cycle_t arch_counter_read(struct clocksource *cs)
+{
+ return arch_counter_get_cntpct();
+}
+
+static struct clocksource clocksource_counter = {
+ .name = "arch_sys_counter",
+ .rating = 400,
+ .read = arch_counter_read,
+ .mask = CLOCKSOURCE_MASK(56),
+ .flags = (CLOCK_SOURCE_IS_CONTINUOUS | CLOCK_SOURCE_VALID_FOR_HRES),
+};
+
+static int __init arch_timer_clocksource_init(void)
+{
+ struct clocksource *cs = &clocksource_counter;
+
+ percpu_timer_setup();
+
+ clocksource_register_hz(cs, arch_timer_rate);
+
+ return 0;
+}
+
+int __init arch_timer_register_setup(void (*setup)(struct clock_event_device *))
+{
+ if (!arch_timer_available())
+ return -ENODEV;
+
+ percpu_timer_register_setup(&arch_timer_ops, setup);
+ arch_timer_clocksource_init();
+ return 0;
+}
--
1.7.0.4
^ permalink raw reply related
* [RFC PATCH 08/20] ARM: remove unused twd_timer_setup stub
From: Marc Zyngier @ 2011-03-02 16:53 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1299084806-16546-1-git-send-email-marc.zyngier@arm.com>
Now that there is no in-tree users of twd_timer_setup() anymore,
remove it completely.
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
arch/arm/include/asm/smp_twd.h | 7 -------
1 files changed, 0 insertions(+), 7 deletions(-)
diff --git a/arch/arm/include/asm/smp_twd.h b/arch/arm/include/asm/smp_twd.h
index 4096736..d2abe52 100644
--- a/arch/arm/include/asm/smp_twd.h
+++ b/arch/arm/include/asm/smp_twd.h
@@ -37,11 +37,4 @@ static inline int twd_timer_register_setup(int (*setup)(struct clock_event_devic
}
#endif
-/*
- * Dummy function, to be removed once there is no in-tree user anymore.
- */
-static inline void twd_timer_setup(void *dummy)
-{
-}
-
#endif
--
1.7.0.4
^ permalink raw reply related
* [RFC PATCH 07/20] ARM: versatile: remove stubbed twd_timer_setup call
From: Marc Zyngier @ 2011-03-02 16:53 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1299084806-16546-1-git-send-email-marc.zyngier@arm.com>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
arch/arm/plat-versatile/localtimer.c | 3 ---
1 files changed, 0 insertions(+), 3 deletions(-)
diff --git a/arch/arm/plat-versatile/localtimer.c b/arch/arm/plat-versatile/localtimer.c
index 0fb3961..93ea3e3 100644
--- a/arch/arm/plat-versatile/localtimer.c
+++ b/arch/arm/plat-versatile/localtimer.c
@@ -9,10 +9,8 @@
* published by the Free Software Foundation.
*/
#include <linux/init.h>
-#include <linux/smp.h>
#include <linux/clockchips.h>
-#include <asm/smp_twd.h>
#include <asm/localtimer.h>
#include <mach/irqs.h>
@@ -22,6 +20,5 @@
int __cpuinit local_timer_setup(struct clock_event_device *evt)
{
evt->irq = IRQ_LOCALTIMER;
- twd_timer_setup(evt);
return 0;
}
--
1.7.0.4
^ permalink raw reply related
* [RFC PATCH 06/20] ARM: ux500: remove stubbed twd_timer_setup call
From: Marc Zyngier @ 2011-03-02 16:53 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1299084806-16546-1-git-send-email-marc.zyngier@arm.com>
Cc: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com>
Cc: Linus Walleij <linus.walleij@stericsson.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
arch/arm/mach-ux500/localtimer.c | 3 ---
1 files changed, 0 insertions(+), 3 deletions(-)
diff --git a/arch/arm/mach-ux500/localtimer.c b/arch/arm/mach-ux500/localtimer.c
index 5ba1133..c648725 100644
--- a/arch/arm/mach-ux500/localtimer.c
+++ b/arch/arm/mach-ux500/localtimer.c
@@ -11,11 +11,9 @@
* published by the Free Software Foundation.
*/
#include <linux/init.h>
-#include <linux/smp.h>
#include <linux/clockchips.h>
#include <asm/irq.h>
-#include <asm/smp_twd.h>
#include <asm/localtimer.h>
/*
@@ -24,6 +22,5 @@
int __cpuinit local_timer_setup(struct clock_event_device *evt)
{
evt->irq = IRQ_LOCALTIMER;
- twd_timer_setup(evt);
return 0;
}
--
1.7.0.4
^ permalink raw reply related
* [RFC PATCH 05/20] ARM: tegra: remove stubbed twd_timer_setup call
From: Marc Zyngier @ 2011-03-02 16:53 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1299084806-16546-1-git-send-email-marc.zyngier@arm.com>
Cc: Colin Cross <ccross@android.com>
Cc: Erik Gilling <konkers@android.com>
Cc: Olof Johansson <olof@lixom.net>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
arch/arm/mach-tegra/localtimer.c | 4 +---
1 files changed, 1 insertions(+), 3 deletions(-)
diff --git a/arch/arm/mach-tegra/localtimer.c b/arch/arm/mach-tegra/localtimer.c
index e91d681..aaabad8 100644
--- a/arch/arm/mach-tegra/localtimer.c
+++ b/arch/arm/mach-tegra/localtimer.c
@@ -9,10 +9,9 @@
* published by the Free Software Foundation.
*/
#include <linux/init.h>
-#include <linux/smp.h>
#include <linux/clockchips.h>
+
#include <asm/irq.h>
-#include <asm/smp_twd.h>
#include <asm/localtimer.h>
/*
@@ -21,6 +20,5 @@
int __cpuinit local_timer_setup(struct clock_event_device *evt)
{
evt->irq = IRQ_LOCALTIMER;
- twd_timer_setup(evt);
return 0;
}
--
1.7.0.4
^ permalink raw reply related
* [RFC PATCH 04/20] ARM: shmobile: remove stubbed twd_timer_setup call
From: Marc Zyngier @ 2011-03-02 16:53 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1299084806-16546-1-git-send-email-marc.zyngier@arm.com>
Cc: Paul Mundt <lethal@linux-sh.org>
Cc: Magnus Damm <magnus.damm@gmail.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
arch/arm/mach-shmobile/localtimer.c | 1 -
1 files changed, 0 insertions(+), 1 deletions(-)
diff --git a/arch/arm/mach-shmobile/localtimer.c b/arch/arm/mach-shmobile/localtimer.c
index ad9ccc9..a4c4e8b 100644
--- a/arch/arm/mach-shmobile/localtimer.c
+++ b/arch/arm/mach-shmobile/localtimer.c
@@ -21,6 +21,5 @@
int __cpuinit local_timer_setup(struct clock_event_device *evt)
{
evt->irq = 29;
- twd_timer_setup(evt);
return 0;
}
--
1.7.0.4
^ permalink raw reply related
* [RFC PATCH 03/20] ARM: exynos4: remove stubbed twd_timer_setup call
From: Marc Zyngier @ 2011-03-02 16:53 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1299084806-16546-1-git-send-email-marc.zyngier@arm.com>
Cc: Kukjin Kim <kgene.kim@samsung.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
arch/arm/mach-exynos4/localtimer.c | 1 -
1 files changed, 0 insertions(+), 1 deletions(-)
diff --git a/arch/arm/mach-exynos4/localtimer.c b/arch/arm/mach-exynos4/localtimer.c
index 6bf3d0a..9d9be20 100644
--- a/arch/arm/mach-exynos4/localtimer.c
+++ b/arch/arm/mach-exynos4/localtimer.c
@@ -21,6 +21,5 @@
int __cpuinit local_timer_setup(struct clock_event_device *evt)
{
evt->irq = IRQ_LOCALTIMER;
- twd_timer_setup(evt);
return 0;
}
--
1.7.0.4
^ permalink raw reply related
* [RFC PATCH 02/20] ARM: omap2: remove stubbed twd_timer_setup call
From: Marc Zyngier @ 2011-03-02 16:53 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1299084806-16546-1-git-send-email-marc.zyngier@arm.com>
Cc: Tony Lindgren <tony@atomide.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
arch/arm/mach-omap2/timer-mpu.c | 3 ---
1 files changed, 0 insertions(+), 3 deletions(-)
diff --git a/arch/arm/mach-omap2/timer-mpu.c b/arch/arm/mach-omap2/timer-mpu.c
index 31c0ac4..02feaff 100644
--- a/arch/arm/mach-omap2/timer-mpu.c
+++ b/arch/arm/mach-omap2/timer-mpu.c
@@ -17,10 +17,8 @@
* published by the Free Software Foundation.
*/
#include <linux/init.h>
-#include <linux/smp.h>
#include <linux/clockchips.h>
#include <asm/irq.h>
-#include <asm/smp_twd.h>
#include <asm/localtimer.h>
/*
@@ -33,7 +31,6 @@ int __cpuinit local_timer_setup(struct clock_event_device *evt)
return -ENXIO;
evt->irq = OMAP44XX_IRQ_LOCALTIMER;
- twd_timer_setup(evt);
return 0;
}
--
1.7.0.4
^ permalink raw reply related
* [RFC PATCH 01/20] ARM: architected timers: move local timer support to percpu_timer.c
From: Marc Zyngier @ 2011-03-02 16:53 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1299084806-16546-1-git-send-email-marc.zyngier@arm.com>
To introduce the A15 architected timers without causing too
much disruption on the rest of the kernel, introduce percpu_timer.c
to act as a registration interface that the platform can call at
runtime.
Timer functions are moved out of smp.c (as the A15 can use the
local timer in UP configuration) and smp_twd.c now returns
a set of operations that percpu_timer.c can call.
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
arch/arm/Kconfig | 6 +-
arch/arm/include/asm/entry-macro-multi.S | 2 +-
arch/arm/include/asm/localtimer.h | 60 +++++++----
arch/arm/include/asm/smp.h | 7 +-
arch/arm/include/asm/smp_twd.h | 27 ++++-
arch/arm/kernel/Makefile | 1 +
arch/arm/kernel/irq.c | 1 +
arch/arm/kernel/percpu_timer.c | 164 ++++++++++++++++++++++++++++++
arch/arm/kernel/smp.c | 92 +----------------
arch/arm/kernel/smp_twd.c | 29 +++++-
10 files changed, 266 insertions(+), 123 deletions(-)
create mode 100644 arch/arm/kernel/percpu_timer.c
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index bcc9727..96d677a 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1288,6 +1288,7 @@ config SMP
ARCH_MSM_SCORPIONMP || ARCH_SHMOBILE
select USE_GENERIC_SMP_HELPERS
select HAVE_ARM_SCU if !ARCH_MSM_SCORPIONMP
+ select HAVE_ARM_TWD if !ARCH_MSM_SCORPIONMP
help
This enables support for systems with more than one CPU. If you have
a system with only one CPU, like most personal computers, say N. If
@@ -1369,10 +1370,9 @@ config HOTPLUG_CPU
can be controlled through /sys/devices/system/cpu.
config LOCAL_TIMERS
- bool "Use local timer interrupts"
- depends on SMP
+ bool
+ depends on SMP || ARCH_MSM_SCORPIONMP
default y
- select HAVE_ARM_TWD if !ARCH_MSM_SCORPIONMP
help
Enable support for local timers on SMP platforms, rather then the
legacy IPI broadcast method. Local timers allows the system
diff --git a/arch/arm/include/asm/entry-macro-multi.S b/arch/arm/include/asm/entry-macro-multi.S
index ec0bbf7..589d4ef 100644
--- a/arch/arm/include/asm/entry-macro-multi.S
+++ b/arch/arm/include/asm/entry-macro-multi.S
@@ -23,6 +23,7 @@
movne r1, sp
adrne lr, BSYM(1b)
bne do_IPI
+#endif
#ifdef CONFIG_LOCAL_TIMERS
test_for_ltirq r0, r6, r5, lr
@@ -30,7 +31,6 @@
adrne lr, BSYM(1b)
bne do_local_timer
#endif
-#endif
9997:
.endm
diff --git a/arch/arm/include/asm/localtimer.h b/arch/arm/include/asm/localtimer.h
index 080d74f..8988c50 100644
--- a/arch/arm/include/asm/localtimer.h
+++ b/arch/arm/include/asm/localtimer.h
@@ -10,7 +10,9 @@
#ifndef __ASM_ARM_LOCALTIMER_H
#define __ASM_ARM_LOCALTIMER_H
-struct clock_event_device;
+#include <linux/clockchips.h>
+
+struct seq_file;
/*
* Setup a per-cpu timer, whether it be a local timer or dummy broadcast
@@ -18,40 +20,58 @@ struct clock_event_device;
void percpu_timer_setup(void);
/*
- * Called from assembly, this is the local timer IRQ handler
+ * Call a per-cpu timer handler
*/
-asmlinkage void do_local_timer(struct pt_regs *);
-
-
-#ifdef CONFIG_LOCAL_TIMERS
-
-#ifdef CONFIG_HAVE_ARM_TWD
+void percpu_timer_run(void);
-#include "smp_twd.h"
-
-#define local_timer_ack() twd_timer_ack()
-
-#else
+/*
+ * Stop a per-cpu timer
+ */
+void percpu_timer_stop(void);
/*
- * Platform provides this to acknowledge a local timer IRQ.
- * Returns true if the local timer IRQ is to be processed.
+ * Called from assembly, this is the local timer IRQ handler
*/
-int local_timer_ack(void);
+asmlinkage void do_local_timer(struct pt_regs *);
-#endif
+struct local_timer_ops {
+ void (*const pre_setup)(struct clock_event_device *clk);
+ int (*plat_setup)(struct clock_event_device *clk);
+ void (*const setup)(struct clock_event_device *clk);
+ int (*const ack)(void);
+};
+#ifdef CONFIG_LOCAL_TIMERS
/*
* Setup a local timer interrupt for a CPU.
*/
int local_timer_setup(struct clock_event_device *);
+/*
+ * Register a local timer.
+ */
+void percpu_timer_register(struct local_timer_ops *);
#else
-
-static inline int local_timer_setup(struct clock_event_device *evt)
+static inline void percpu_timer_register(void *dummy)
{
- return -ENXIO;
}
#endif
+static inline int percpu_timer_register_setup(struct local_timer_ops *ops,
+ int (*plat_setup)(struct clock_event_device *))
+{
+ if (ops) {
+ ops->plat_setup = plat_setup;
+ percpu_timer_register(ops);
+ return 0;
+ }
+
+ return -ENODEV;
+}
+
+/*
+ * show local interrupt info
+ */
+extern void show_local_irqs(struct seq_file *, int);
+
#endif
diff --git a/arch/arm/include/asm/smp.h b/arch/arm/include/asm/smp.h
index 96ed521..2e31e8d 100644
--- a/arch/arm/include/asm/smp.h
+++ b/arch/arm/include/asm/smp.h
@@ -95,9 +95,8 @@ extern void platform_cpu_enable(unsigned int cpu);
extern void arch_send_call_function_single_ipi(int cpu);
extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
-/*
- * show local interrupt info
- */
-extern void show_local_irqs(struct seq_file *, int);
+#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
+void smp_timer_broadcast(const struct cpumask *mask);
+#endif
#endif /* ifndef __ASM_ARM_SMP_H */
diff --git a/arch/arm/include/asm/smp_twd.h b/arch/arm/include/asm/smp_twd.h
index fed9981..4096736 100644
--- a/arch/arm/include/asm/smp_twd.h
+++ b/arch/arm/include/asm/smp_twd.h
@@ -1,6 +1,8 @@
#ifndef __ASMARM_SMP_TWD_H
#define __ASMARM_SMP_TWD_H
+#include <linux/clockchips.h>
+
#define TWD_TIMER_LOAD 0x00
#define TWD_TIMER_COUNTER 0x04
#define TWD_TIMER_CONTROL 0x08
@@ -18,11 +20,28 @@
#define TWD_TIMER_CONTROL_PERIODIC (1 << 1)
#define TWD_TIMER_CONTROL_IT_ENABLE (1 << 2)
-struct clock_event_device;
-
extern void __iomem *twd_base;
-int twd_timer_ack(void);
-void twd_timer_setup(struct clock_event_device *);
+#ifdef CONFIG_HAVE_ARM_TWD
+struct local_timer_ops *local_timer_get_twd_ops(void);
+int twd_timer_register_setup(int (*setup)(struct clock_event_device *));
+#else
+static inline struct local_timer_ops *local_timer_get_twd_ops(void)
+{
+ return NULL;
+}
+
+static inline int twd_timer_register_setup(int (*setup)(struct clock_event_device *))
+{
+ return -ENODEV;
+}
+#endif
+
+/*
+ * Dummy function, to be removed once there is no in-tree user anymore.
+ */
+static inline void twd_timer_setup(void *dummy)
+{
+}
#endif
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index 74554f1..277f6ff 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -34,6 +34,7 @@ obj-$(CONFIG_HAVE_SCHED_CLOCK) += sched_clock.o
obj-$(CONFIG_SMP) += smp.o smp_tlb.o
obj-$(CONFIG_HAVE_ARM_SCU) += smp_scu.o
obj-$(CONFIG_HAVE_ARM_TWD) += smp_twd.o
+obj-$(CONFIG_LOCAL_TIMERS) += percpu_timer.o
obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o
obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o
obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
index 3535d37..97154bc 100644
--- a/arch/arm/kernel/irq.c
+++ b/arch/arm/kernel/irq.c
@@ -38,6 +38,7 @@
#include <linux/ftrace.h>
#include <asm/system.h>
+#include <asm/localtimer.h>
#include <asm/mach/arch.h>
#include <asm/mach/irq.h>
#include <asm/mach/time.h>
diff --git a/arch/arm/kernel/percpu_timer.c b/arch/arm/kernel/percpu_timer.c
new file mode 100644
index 0000000..5992fae
--- /dev/null
+++ b/arch/arm/kernel/percpu_timer.c
@@ -0,0 +1,164 @@
+/*
+ * linux/arch/arm/kernel/percpu_timer.c
+ *
+ * Copyright (C) 2011 ARM Ltd.
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/irq.h>
+#include <linux/seq_file.h>
+#include <linux/interrupt.h>
+
+#include <asm/localtimer.h>
+#include <asm/hardware/gic.h>
+
+#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
+static void broadcast_timer_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+}
+#else
+#define broadcast_timer_set_mode NULL
+#define smp_timer_broadcast NULL
+#endif
+
+static void broadcast_timer_setup(struct clock_event_device *evt)
+{
+ /* check that no-one has registered the timer in plat_setup */
+ if (evt->name)
+ return;
+
+ evt->name = "dummy_timer";
+ evt->features = CLOCK_EVT_FEAT_ONESHOT |
+ CLOCK_EVT_FEAT_PERIODIC |
+ CLOCK_EVT_FEAT_DUMMY;
+ evt->rating = 400;
+ evt->mult = 1;
+ evt->set_mode = broadcast_timer_set_mode;
+ evt->broadcast = smp_timer_broadcast;
+
+ clockevents_register_device(evt);
+}
+
+static struct local_timer_ops broadcast_timer_ops = {
+ .setup = broadcast_timer_setup,
+};
+
+static struct local_timer_ops *timer_ops;
+
+int __attribute__ ((weak)) local_timer_setup(struct clock_event_device *evt)
+{
+ return -ENXIO;
+}
+
+void percpu_timer_register(struct local_timer_ops *ops)
+{
+ timer_ops = ops;
+}
+
+/*
+ * local_timer_ack: checks for a local timer interrupt.
+ *
+ * If a local timer interrupt has occurred, acknowledge and return 1.
+ * Otherwise, return 0.
+ *
+ * This can be overloaded by platform code that doesn't provide its
+ * timer in timer_fns way (msm at the moment). Once all platforms have
+ * migrated, the weak alias can be removed.
+ */
+static int percpu_timer_ack(void)
+{
+ return timer_ops->ack();
+}
+
+int local_timer_ack(void) __attribute__ ((weak, alias("percpu_timer_ack")));
+
+asmlinkage void __exception_irq_entry do_local_timer(struct pt_regs *regs)
+{
+ struct pt_regs *old_regs = set_irq_regs(regs);
+ int cpu = smp_processor_id();
+
+ if (local_timer_ack()) {
+ __inc_irq_stat(cpu, local_timer_irqs);
+ percpu_timer_run();
+ }
+
+ set_irq_regs(old_regs);
+}
+
+void show_local_irqs(struct seq_file *p, int prec)
+{
+ unsigned int cpu;
+
+ seq_printf(p, "%*s: ", prec, "LOC");
+
+ for_each_present_cpu(cpu)
+ seq_printf(p, "%10u ", __get_irq_stat(cpu, local_timer_irqs));
+
+ seq_printf(p, " Local timer interrupts\n");
+}
+
+/*
+ * Timer (local or broadcast) support
+ */
+static DEFINE_PER_CPU(struct clock_event_device, percpu_clockevent);
+
+void percpu_timer_run(void)
+{
+ struct clock_event_device *evt = &__get_cpu_var(percpu_clockevent);
+ irq_enter();
+ evt->event_handler(evt);
+ irq_exit();
+}
+
+void __cpuinit percpu_timer_setup(void)
+{
+ int ret = 0;
+ unsigned int cpu = smp_processor_id();
+ struct clock_event_device *evt = &per_cpu(percpu_clockevent, cpu);
+
+ if (evt->name)
+ return;
+
+ /*
+ * All this can go away once we've migrated all users to
+ * properly register the timer they use, and broadcast can
+ * become the fallback.
+ */
+ if (!timer_ops)
+ timer_ops = local_timer_get_twd_ops();
+ if (!timer_ops)
+ timer_ops = &broadcast_timer_ops;
+ if (!timer_ops->plat_setup)
+ timer_ops->plat_setup = local_timer_setup;
+
+ evt->cpumask = cpumask_of(cpu);
+
+ if (timer_ops->pre_setup)
+ timer_ops->pre_setup(evt);
+ if (timer_ops->plat_setup)
+ ret = timer_ops->plat_setup(evt);
+ if (ret) /* Fallback to broadcast */
+ timer_ops = &broadcast_timer_ops;
+ if (timer_ops->setup)
+ timer_ops->setup(evt);
+}
+
+#ifdef CONFIG_HOTPLUG_CPU
+/*
+ * The generic clock events code purposely does not stop the local timer
+ * on CPU_DEAD/CPU_DEAD_FROZEN hotplug events, so we have to do it
+ * manually here.
+ */
+void percpu_timer_stop(void)
+{
+ unsigned int cpu = smp_processor_id();
+ struct clock_event_device *evt = &per_cpu(percpu_clockevent, cpu);
+
+ evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt);
+}
+#endif
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 8fe05ad..b94b19c 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -153,8 +153,6 @@ int __cpuinit __cpu_up(unsigned int cpu)
}
#ifdef CONFIG_HOTPLUG_CPU
-static void percpu_timer_stop(void);
-
/*
* __cpu_disable runs on the processor to be shutdown.
*/
@@ -426,97 +424,13 @@ u64 smp_irq_stat_cpu(unsigned int cpu)
}
/*
- * Timer (local or broadcast) support
+ * Broadcast timer support
*/
-static DEFINE_PER_CPU(struct clock_event_device, percpu_clockevent);
-
-static void ipi_timer(void)
-{
- struct clock_event_device *evt = &__get_cpu_var(percpu_clockevent);
- irq_enter();
- evt->event_handler(evt);
- irq_exit();
-}
-
-#ifdef CONFIG_LOCAL_TIMERS
-asmlinkage void __exception_irq_entry do_local_timer(struct pt_regs *regs)
-{
- struct pt_regs *old_regs = set_irq_regs(regs);
- int cpu = smp_processor_id();
-
- if (local_timer_ack()) {
- __inc_irq_stat(cpu, local_timer_irqs);
- ipi_timer();
- }
-
- set_irq_regs(old_regs);
-}
-
-void show_local_irqs(struct seq_file *p, int prec)
-{
- unsigned int cpu;
-
- seq_printf(p, "%*s: ", prec, "LOC");
-
- for_each_present_cpu(cpu)
- seq_printf(p, "%10u ", __get_irq_stat(cpu, local_timer_irqs));
-
- seq_printf(p, " Local timer interrupts\n");
-}
-#endif
-
#ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST
-static void smp_timer_broadcast(const struct cpumask *mask)
+void smp_timer_broadcast(const struct cpumask *mask)
{
smp_cross_call(mask, IPI_TIMER);
}
-#else
-#define smp_timer_broadcast NULL
-#endif
-
-static void broadcast_timer_set_mode(enum clock_event_mode mode,
- struct clock_event_device *evt)
-{
-}
-
-static void broadcast_timer_setup(struct clock_event_device *evt)
-{
- evt->name = "dummy_timer";
- evt->features = CLOCK_EVT_FEAT_ONESHOT |
- CLOCK_EVT_FEAT_PERIODIC |
- CLOCK_EVT_FEAT_DUMMY;
- evt->rating = 400;
- evt->mult = 1;
- evt->set_mode = broadcast_timer_set_mode;
-
- clockevents_register_device(evt);
-}
-
-void __cpuinit percpu_timer_setup(void)
-{
- unsigned int cpu = smp_processor_id();
- struct clock_event_device *evt = &per_cpu(percpu_clockevent, cpu);
-
- evt->cpumask = cpumask_of(cpu);
- evt->broadcast = smp_timer_broadcast;
-
- if (local_timer_setup(evt))
- broadcast_timer_setup(evt);
-}
-
-#ifdef CONFIG_HOTPLUG_CPU
-/*
- * The generic clock events code purposely does not stop the local timer
- * on CPU_DEAD/CPU_DEAD_FROZEN hotplug events, so we have to do it
- * manually here.
- */
-static void percpu_timer_stop(void)
-{
- unsigned int cpu = smp_processor_id();
- struct clock_event_device *evt = &per_cpu(percpu_clockevent, cpu);
-
- evt->set_mode(CLOCK_EVT_MODE_UNUSED, evt);
-}
#endif
static DEFINE_SPINLOCK(stop_lock);
@@ -556,7 +470,7 @@ asmlinkage void __exception_irq_entry do_IPI(int ipinr, struct pt_regs *regs)
switch (ipinr) {
case IPI_TIMER:
- ipi_timer();
+ percpu_timer_run();
break;
case IPI_RESCHEDULE:
diff --git a/arch/arm/kernel/smp_twd.c b/arch/arm/kernel/smp_twd.c
index 60636f4..4fdfb85 100644
--- a/arch/arm/kernel/smp_twd.c
+++ b/arch/arm/kernel/smp_twd.c
@@ -18,6 +18,7 @@
#include <linux/irq.h>
#include <linux/io.h>
+#include <asm/localtimer.h>
#include <asm/smp_twd.h>
#include <asm/hardware/gic.h>
@@ -70,7 +71,7 @@ static int twd_set_next_event(unsigned long evt,
* If a local timer interrupt has occurred, acknowledge and return 1.
* Otherwise, return 0.
*/
-int twd_timer_ack(void)
+static int twd_timer_ack(void)
{
if (__raw_readl(twd_base + TWD_TIMER_INTSTAT)) {
__raw_writel(1, twd_base + TWD_TIMER_INTSTAT);
@@ -122,7 +123,7 @@ static void __cpuinit twd_calibrate_rate(void)
/*
* Setup the local clock events for a CPU.
*/
-void __cpuinit twd_timer_setup(struct clock_event_device *clk)
+static void __cpuinit twd_setup(struct clock_event_device *clk)
{
twd_calibrate_rate();
@@ -142,3 +143,27 @@ void __cpuinit twd_timer_setup(struct clock_event_device *clk)
clockevents_register_device(clk);
}
+
+static struct local_timer_ops twd_timer_ops = {
+ .setup = twd_setup,
+ .ack = twd_timer_ack,
+};
+
+struct local_timer_ops *local_timer_get_twd_ops(void)
+{
+ if (!twd_base) {
+ pr_warn("TWD base address not set\n");
+ return NULL;
+ }
+
+ return &twd_timer_ops;
+}
+
+int __init twd_timer_register_setup(int (*setup)(struct clock_event_device *))
+{
+ if (!twd_base)
+ return -ENODEV;
+
+ percpu_timer_register_setup(&twd_timer_ops, setup);
+ return 0;
+}
--
1.7.0.4
^ permalink raw reply related
* [RFC PATCH 00/20] A15 architected timer support
From: Marc Zyngier @ 2011-03-02 16:53 UTC (permalink / raw)
To: linux-arm-kernel
This patch set adds support for the architected (or generic) timers
that appear in the Cortex A15. The specification is part of the
ARMv7-AR LPA Virtualization Extensions, available from (free
registration required):
http://infocenter.arm.com/help/topic/com.arm.doc.ddi0406b_virtualization_extns/index.html
They provide physical and virtual timers/counters (the later being
under control of the hypervisor). The code provides a clock source
(using the physical counter) and a sched_clock implementation (using
the virtual counter, so the local scheduling is not affected by having
multiple VMs scheduled in and out of the CPU by the hypervisor).
Modifications are relatively invasive:
- The timer interrupt is on IRQ 29 or 30, depending on whether the
kernel is running in secure or normal mode. As it is not possible to
distinguish between the two modes in a reliable way, we have to
check if we're running on an A15 or not (the feature register may be
virtualized, and thus potentially expensive to access).
- Local timer is also used in an UP configuration, so the local timer
code is isolated from SMP support.
- A registration interface is introduced to allow a platform to pick
its preferred implementation (architected timers, twd, msm local
timers...). This causes some code churn in the platform specific
code as the registration mechanism takes place at runtime instead of
having a link time selection (local_timer_setup).
- Broadcast timers become the fallback in case no local timers are
available.
- Allow the kernel to have multiple sched_clock() implementations
compiled in, and extend the existing API to register one at
runtime.
On the (emulated) Versatile Express platform, the A15 is running
without the SP804 that is usually used across the whole Versatile
range. The same binary kernel also runs on the Cortex A5 tile using
TWD and SP804 (both patch sets to be posted shortly).
Patches #1, 9, 10 and 11 carry the core modifications. All the others
are platform support changes and various cleanups. This patch set
depends on Will Deacon's multi-tile patch. Tested on next-20110302.
Any comments are welcome.
Marc Zyngier (20):
ARM: architected timers: move local timer support to percpu_timer.c
ARM: omap2: remove stubbed twd_timer_setup call
ARM: exynos4: remove stubbed twd_timer_setup call
ARM: shmobile: remove stubbed twd_timer_setup call
ARM: tegra: remove stubbed twd_timer_setup call
ARM: ux500: remove stubbed twd_timer_setup call
ARM: versatile: remove stubbed twd_timer_setup call
ARM: remove unused twd_timer_setup stub
ARM: architected timers: add A15 architected timers
ARM: Platform dependent sched_clock() override
ARM: architected timers: Add A15 specific sched_clock implementation
ARM: versatile/vexpress: rework timer support
ARM: msm: dynamically register local timer setup function
ARM: omap4: dynamically register local timer setup function
ARM: exynos4: dynamically register local timer setup function
ARM: shmobile: dynamically register local timer setup function
ARM: tegra: dynamically register local timer setup function
ARM: ux500: dynamically register local timer setup function
ARM: simplify percpu_timer_setup
ARM: simplify percpu_timer_ack
arch/arm/Kconfig | 20 ++-
arch/arm/include/asm/arch_timer.h | 13 +
arch/arm/include/asm/entry-macro-multi.S | 2 +-
arch/arm/include/asm/hardware/entry-macro-gic.S | 18 ++
arch/arm/include/asm/localtimer.h | 61 +++--
arch/arm/include/asm/sched_clock.h | 41 +++-
arch/arm/include/asm/smp.h | 7 +-
arch/arm/include/asm/smp_twd.h | 14 +-
arch/arm/kernel/Makefile | 2 +
arch/arm/kernel/arch_timer.c | 253 +++++++++++++++++++++
arch/arm/kernel/irq.c | 1 +
arch/arm/kernel/percpu_timer.c | 141 ++++++++++++
arch/arm/kernel/sched_clock.c | 23 ++-
arch/arm/kernel/smp.c | 92 +-------
arch/arm/kernel/smp_twd.c | 21 ++-
arch/arm/mach-exynos4/Makefile | 1 -
arch/arm/mach-exynos4/localtimer.c | 26 --
arch/arm/mach-exynos4/time.c | 10 +
arch/arm/mach-msm/timer.c | 22 ++-
arch/arm/mach-omap2/Makefile | 1 -
arch/arm/mach-omap2/timer-gp.c | 12 +-
arch/arm/mach-omap2/timer-mpu.c | 39 ----
arch/arm/mach-realview/realview_eb.c | 4 +-
arch/arm/mach-realview/realview_pb11mp.c | 4 +-
arch/arm/mach-realview/realview_pbx.c | 5 +-
arch/arm/mach-shmobile/Makefile | 1 -
arch/arm/mach-shmobile/localtimer.c | 26 --
arch/arm/mach-shmobile/timer.c | 12 +
arch/arm/mach-tegra/Makefile | 2 +-
arch/arm/mach-tegra/localtimer.c | 26 --
arch/arm/mach-tegra/timer.c | 10 +
arch/arm/mach-ux500/Makefile | 1 -
arch/arm/mach-ux500/cpu.c | 12 +
arch/arm/mach-ux500/localtimer.c | 29 ---
arch/arm/mach-vexpress/v2m.c | 29 +++-
arch/arm/plat-versatile/include/plat/localtimer.h | 9 +
arch/arm/plat-versatile/localtimer.c | 11 +-
arch/arm/plat-versatile/sched-clock.c | 7 +-
38 files changed, 711 insertions(+), 297 deletions(-)
create mode 100644 arch/arm/include/asm/arch_timer.h
create mode 100644 arch/arm/kernel/arch_timer.c
create mode 100644 arch/arm/kernel/percpu_timer.c
delete mode 100644 arch/arm/mach-exynos4/localtimer.c
delete mode 100644 arch/arm/mach-omap2/timer-mpu.c
delete mode 100644 arch/arm/mach-shmobile/localtimer.c
delete mode 100644 arch/arm/mach-tegra/localtimer.c
delete mode 100644 arch/arm/mach-ux500/localtimer.c
create mode 100644 arch/arm/plat-versatile/include/plat/localtimer.h
^ permalink raw reply
* [PATCH 1/8 resend] dw_dmac: Remove compilation dependency from AVR32
From: Koul, Vinod @ 2011-03-02 16:46 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <d41145ce4d5e3d870f720709f68d5b1dbf34d6a0.1298889267.git.viresh.kumar@st.com>
On Mon, 2011-02-28 at 16:11 +0530, Viresh Kumar wrote:
> This will be used in SPEAr, ARM family.
Does this mean it can be used on AVR32 now? Did you implay it will
*also* be....
>
> Signed-off-by: Viresh Kumar <viresh.kumar@st.com>
> ---
> drivers/dma/Kconfig | 1 -
> 1 files changed, 0 insertions(+), 1 deletions(-)
>
> diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
> index 1c28816..95c7db7 100644
> --- a/drivers/dma/Kconfig
> +++ b/drivers/dma/Kconfig
> @@ -82,7 +82,6 @@ config INTEL_IOP_ADMA
>
> config DW_DMAC
> tristate "Synopsys DesignWare AHB DMA support"
> - depends on AVR32
Shouldn't you be adding a corresponding depends on new arch? And since
this supports old arch as well, it should say depends on both...
> select DMA_ENGINE
> default y if CPU_AT32AP7000
> help
--
~Vinod
^ permalink raw reply
* [PATCH 0/8 resend] dw_dmac: Extending support & minor fixes
From: Koul, Vinod @ 2011-03-02 16:39 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <cover.1298889267.git.viresh.kumar@st.com>
On Mon, 2011-02-28 at 16:11 +0530, Viresh Kumar wrote:
> Following set of patches extends dw_dmac support and fixes minor bugs.
>
> This patch series has earlier been posted to linux-kernel at vger.kernel.org.
> Didn't get any review there, so including linux-arm-kernel at lists.infradead.org.
>
Please remember to copy the MAINTAINERS, (in this case Dan and me) thats
why didn't get review last time.
Will look into this series now...
--
~Vinod
^ permalink raw reply
* [RFC PATCH 1/1] ARM: imx5x: clean up ARCH_MX5X
From: Uwe Kleine-König @ 2011-03-02 16:33 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20110302160605.GA2994@richard-laptop>
On Thu, Mar 03, 2011 at 12:06:05AM +0800, Richard Zhao wrote:
> Hi Uwe,
>
> Thanks for your detailed explanation!
> On Wed, Mar 02, 2011 at 12:25:59PM +0100, Uwe Kleine-K?nig wrote:
> > Hello Richard,
> >
> > On Wed, Mar 02, 2011 at 11:28:46AM +0800, Richard Zhao wrote:
> > > Remove legacy support of ARCH_MX5X. Move to SOC_SOC_IMX5X.
> > >
> > > My understanding is ARCH_MX5 selects Kconfig in arch/arm/mach-mx5,
> > > and every board can be selected/unselected, and SOC_XXX be selected
> > > by the board config. MACH_XXXX/SOC_XXXX then select those HAVE_XXXX.
> > My intended goal with these ARCH_MX.., MACH_MX.. and SOC_IMX.. symbols is:
> >
> > - ARCH_MX.. should be only a helper to group all machines together that
> > can be built in a single image. In the far future it hopefully dies
> > because we can compile everything together. These IMHO should not be
> > used in Makefiles or source files at all as the grouping can change
> > over time. I'm not sure the name ARCH_MX.. is that good. Didn't think
> > about a better naming scheme, so if you have suggestions don't
> > hesitate to tell them.
> Would it make sense to go straight forward?
> ARCH_MX.. for SoC series. eg. ARCH_MX1/2/3/5. It groups SoCs.
This doesn't work. Where do you want to put i.MX25? Conceptually the
easy groups are { i.MX21, i.MX27 } and { i.MX25, i.MX31, i.MX35 }
because these share PHYS_OFFSETs. And note that i.MX31 has a different
iomuxer than i.MX25 and i.MX35. As soon as we have support for runtime
PHYS_OFFSET the remaining groups are:
ARMv4 + ARMv5 vs. ARMv6 + ARMv7
(I think) which doesn't match the ARCH_MX1/2/3/5 approach anymore.
> SOC_IMX.. for single SoC. eg. SOC_IMX31/35/50/51/53. It groups Machines.
> MACH_.. for single machine. eg. MACH_MX51_BABBAGE.
>
> They can be used in Makefiles to help include source files, but idealy not be
> used in source files. For multi-soc in single image, it's more easy to select
> build targets. It can also help transit to single image step by step.
Here I'd prefer things like:
config SOC_IMX21
bool
select IMX_HAVE_IOMUX_V1
obj-$(IMX_HAVE_IOMUX_V1) += tralala.o
> > - MACH_MX.. actually are misnomers becauce they clash with the name
> > space of the machine db. So they should be substituted by SOC_IMX...
> > (maybe a few by ARCH_MX..) (affected: MACH_MX21 and MACH_MX27)
> > - SOC_IMX.. are used to differentiate between SoCs.
> >
> > So a goal is to review all ARCH_MX.. and MACH_MX.. used in .c and .h
> > files and try to use the SOC_IMX variables instead.
> > Here I consider important that SOC_IMX... is really only used with
> > having multi-SoC-kernels in mind. So you can consider ARCH_MX and
> > MACH_MX as todo-markers for that (and this is the main difference IMHO).
> > E.g. the Makefile.boots are such a place that are not multi-soc capable
> > yet as is the selection of PHYS_OFFSET. I'd like to keep them marked
> > somehow.
> The ToDO markers might label itself as markers, Or it cause many people
> confused.
I don't know what you mean here.
> And are you sure we won't need ARCH_MX.. in the final single image solution?
> IMHO, single image needs to select what targetis it builds for too. The ARCH_MX..
> works as categories and help reduce image size.
Again, I don't understand you here.
> > I don't know if it's sensible to coordinate this effort, it mainly
> > depends on how many people are willing to help. I'll start with ARCH_MX2
> > and MACH_MX2[17] next.
> >
> > A bit orthogonal to this issue is to clean up mach-mx3 and mach-mx5 to
> > allow them to be merged into mach-imx. I didn't look at all on mxc91231,
> > yet.
> >
> > Comments and patches are welcome. If you want to help and don't know
> > where to start, here are a few hints:
> >
> > - git grep -E 'M?AR?CH_MX' drivers
> > - convert arch/arm/mach-mx[35]/devices.c to dynamically allocation
> >
> > Richard, having said that, some of your changes look OK, while I'm not
> > completely happy with the others.
> It seems only PHYS_OFFSET are not ok?
and Makefile.boot
> Maybe the p2v patch can help?
Indeed.
Best regards
Uwe
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply
* [PATCH 2/2] ARM: mx5/mx53_evk: Fix IOMUX for UART3
From: Fabio Estevam @ 2011-03-02 16:30 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1299083453-29431-1-git-send-email-fabio.estevam@freescale.com>
On mx53_evk board only RX/TX pins are used on UART3.
Signed-off-by: Fabio Estevam <fabio.estevam@freescale.com>
---
arch/arm/mach-mx5/board-mx53_evk.c | 4 +---
1 files changed, 1 insertions(+), 3 deletions(-)
diff --git a/arch/arm/mach-mx5/board-mx53_evk.c b/arch/arm/mach-mx5/board-mx53_evk.c
index 652e1e0..7b5735c 100644
--- a/arch/arm/mach-mx5/board-mx53_evk.c
+++ b/arch/arm/mach-mx5/board-mx53_evk.c
@@ -52,8 +52,6 @@ static iomux_v3_cfg_t mx53_evk_pads[] = {
MX53_PAD_PATA_CS_0__UART3_TXD_MUX,
MX53_PAD_PATA_CS_1__UART3_RXD_MUX,
- MX53_PAD_PATA_DA_1__UART3_CTS,
- MX53_PAD_PATA_DA_2__UART3_RTS,
MX53_PAD_EIM_D16__ECSPI1_SCLK,
MX53_PAD_EIM_D17__ECSPI1_MISO,
@@ -72,7 +70,7 @@ static inline void mx53_evk_init_uart(void)
{
imx53_add_imx_uart(0, NULL);
imx53_add_imx_uart(1, &mx53_evk_uart_pdata);
- imx53_add_imx_uart(2, &mx53_evk_uart_pdata);
+ imx53_add_imx_uart(2, NULL);
}
static const struct imxi2c_platform_data mx53_evk_i2c_data __initconst = {
--
1.6.0.4
^ permalink raw reply related
* [PATCH 1/2] ARM: mx5/mx53_smd: Fix IOMUX for UART2
From: Fabio Estevam @ 2011-03-02 16:30 UTC (permalink / raw)
To: linux-arm-kernel
On mx53_smd board only RX/TX pins are used on UART2.
Signed-off-by: Fabio Estevam <fabio.estevam@freescale.com>
---
arch/arm/mach-mx5/board-mx53_smd.c | 4 +---
1 files changed, 1 insertions(+), 3 deletions(-)
diff --git a/arch/arm/mach-mx5/board-mx53_smd.c b/arch/arm/mach-mx5/board-mx53_smd.c
index 5eb1638..31e1732 100644
--- a/arch/arm/mach-mx5/board-mx53_smd.c
+++ b/arch/arm/mach-mx5/board-mx53_smd.c
@@ -44,8 +44,6 @@ static iomux_v3_cfg_t mx53_smd_pads[] = {
MX53_PAD_PATA_BUFFER_EN__UART2_RXD_MUX,
MX53_PAD_PATA_DMARQ__UART2_TXD_MUX,
- MX53_PAD_PATA_DIOR__UART2_RTS,
- MX53_PAD_PATA_INTRQ__UART2_CTS,
MX53_PAD_PATA_CS_0__UART3_TXD_MUX,
MX53_PAD_PATA_CS_1__UART3_RXD_MUX,
@@ -63,7 +61,7 @@ static const struct imxuart_platform_data mx53_smd_uart_data __initconst = {
static inline void mx53_smd_init_uart(void)
{
imx53_add_imx_uart(0, NULL);
- imx53_add_imx_uart(1, &mx53_smd_uart_data);
+ imx53_add_imx_uart(1, NULL);
imx53_add_imx_uart(2, &mx53_smd_uart_data);
}
--
1.6.0.4
^ permalink raw reply related
* [GIT PULL] OMAP PM fixes for 2.6.38-rc
From: Kevin Hilman @ 2011-03-02 16:30 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <87pqqae8mc.fsf@ti.com>
Tony,
Kevin Hilman <khilman@ti.com> writes:
> Here's a final batch of PM fixes for the 2.6.38-rc cycle.
I just noticed that a couple of these were already queued in your last
pull request to Linus.
Here's an updated pull request based on .38-rc7.
Kevin
The following changes since commit dd9c1549edef02290edced639f67b54a25abbe0e:
Linux 2.6.38-rc7 (2011-03-01 13:55:12 -0800)
are available in the git repository at:
ssh://master.kernel.org/pub/scm/linux/kernel/git/khilman/linux-omap-pm.git for_2.6.38/pm-fixes
Aaro Koskinen (1):
arm: mach-omap2: smartreflex: fix another memory leak
Shweta Gulati (1):
OMAP2+: PM: SmartReflex: fix memory leaks in Smartreflex driver
arch/arm/mach-omap2/smartreflex.c | 33 +++++++++++++++------------------
1 files changed, 15 insertions(+), 18 deletions(-)
^ permalink raw reply
* [PATCH v5] dmaengine: mxs-dma: add dma support for i.MX23/28
From: Koul, Vinod @ 2011-03-02 16:29 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1298738862-3623-1-git-send-email-shawn.guo@freescale.com>
On Sat, 2011-02-26 at 22:17 +0530, Shawn Guo wrote:
> This patch adds dma support for Freescale MXS-based SoC i.MX23/28,
> including apbh-dma and apbx-dma.
>
> * apbh-dma and apbx-dma are supported in the driver as two mxs-dma
> instances.
>
> * apbh-dma is different between mx23 and mx28, hardware version
> register is used to differentiate.
>
> * mxs-dma supports pio function besides data transfer. The driver
> uses dma_data_direction DMA_NONE to identify the pio mode, and
> steals sgl and sg_len to get pio words and numbers from clients.
>
> * mxs dmaengine has some very specific features, like sense function
> and the special NAND support (nand_lock, nand_wait4ready). These
> are too specific to implemented in generic dmaengine driver.
>
> * The driver refers to imx-sdma and only a single descriptor is
> statically assigned to each channel.
>
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
> Change since v4:
>
> Fix checkpatch errors (sorry for forgetting this basical requirement)
>
> arch/arm/mach-mxs/include/mach/dma.h | 26 ++
> drivers/dma/Kconfig | 8 +
> drivers/dma/Makefile | 1 +
> drivers/dma/mxs-dma.c | 724 ++++++++++++++++++++++++++++++++++
> 4 files changed, 759 insertions(+), 0 deletions(-)
> create mode 100644 arch/arm/mach-mxs/include/mach/dma.h
> create mode 100644 drivers/dma/mxs-dma.c
Thanks, Applied to my tree at
git://git.infradead.org/users/vkoul/slave-dma.git
~Vinod
^ permalink raw reply
* [PATCH] omap:iommu-added cache flushing operation for L2 cache
From: Gupta, Ramesh @ 2011-03-02 16:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <AANLkTi=ULWw2CsZgcYpkXrA+qQe3ufDhW5es0dwe66ph@mail.gmail.com>
David,
On Wed, Mar 2, 2011 at 5:58 AM, David Cohen <dacohen@gmail.com> wrote:
> Hi,
>
> On Tue, Mar 1, 2011 at 9:46 PM, Fernando Guzman Lugo
> <fernando.lugo@ti.com> wrote:
>> From: Ramesh Gupta <grgupta@ti.com>
>
> No patch body description at all?
> Can we get at least something here?
My apologies, I will be sending an updated patch
with description.
regards
Ramesh Gupta G
^ permalink raw reply
* [PATCH] omap:iommu-added cache flushing operation for L2 cache
From: Gupta, Ramesh @ 2011-03-02 16:12 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1dc497a090414bf80ff588791d6db5cc@mail.gmail.com>
Hi Santosh,
On Wed, Mar 2, 2011 at 6:48 AM, Santosh Shilimkar
<santosh.shilimkar@ti.com> wrote:
> Hello,
>> -----Original Message-----
>> From: linux-omap-owner at vger.kernel.org [mailto:linux-omap-
>> owner at vger.kernel.org] On Behalf Of Fernando Guzman Lugo
>> Sent: Wednesday, March 02, 2011 1:17 AM
>> To: hiroshi.doyu at nokia.com
>> Cc: tony at atomide.com; linux at arm.linux.org.uk; linux-
>> omap at vger.kernel.org; linux-arm-kernel at lists.infradead.org; linux-
>> kernel at vger.kernel.org; Ramesh Gupta; Hari Kanigeri
>> Subject: [PATCH] omap:iommu-added cache flushing operation for L2
>> cache
>>
>> From: Ramesh Gupta <grgupta@ti.com>
>>
>> Signed-off-by: Ramesh Gupta <grgupta@ti.com>
>> Signed-off-by: Hari Kanigeri <h-kanigeri2@ti.com>
>> ---
>> ?arch/arm/plat-omap/iommu.c | ? 22 ++++++++--------------
>> ?1 files changed, 8 insertions(+), 14 deletions(-)
>>
>> diff --git a/arch/arm/plat-omap/iommu.c b/arch/arm/plat-omap/iommu.c
>> index e3eb038..aeb2c33 100644
>> --- a/arch/arm/plat-omap/iommu.c
>> +++ b/arch/arm/plat-omap/iommu.c
>> @@ -471,22 +471,15 @@ EXPORT_SYMBOL_GPL(foreach_iommu_device);
>> ? */
>> ?static void flush_iopgd_range(u32 *first, u32 *last)
>> ?{
>> - ? ? /* FIXME: L2 cache should be taken care of if it exists */
>> - ? ? do {
>> - ? ? ? ? ? ? asm("mcr ? ? ? ?p15, 0, %0, c7, c10, 1 @ flush_pgd"
>> - ? ? ? ? ? ? ? ? : : "r" (first));
>> - ? ? ? ? ? ? first += L1_CACHE_BYTES / sizeof(*first);
>> - ? ? } while (first <= last);
>> + ? ? dmac_flush_range(first, last);
>
> There is note just above this API.
Thank you for your inputs. I agree, I will send an updated patch with
proper apis.
regards
Ramesh Gupta G
^ permalink raw reply
* [RFC PATCH 1/1] ARM: imx5x: clean up ARCH_MX5X
From: Richard Zhao @ 2011-03-02 16:06 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20110302112559.GC22310@pengutronix.de>
Hi Uwe,
Thanks for your detailed explanation!
On Wed, Mar 02, 2011 at 12:25:59PM +0100, Uwe Kleine-K?nig wrote:
> Hello Richard,
>
> On Wed, Mar 02, 2011 at 11:28:46AM +0800, Richard Zhao wrote:
> > Remove legacy support of ARCH_MX5X. Move to SOC_SOC_IMX5X.
> >
> > My understanding is ARCH_MX5 selects Kconfig in arch/arm/mach-mx5,
> > and every board can be selected/unselected, and SOC_XXX be selected
> > by the board config. MACH_XXXX/SOC_XXXX then select those HAVE_XXXX.
> My intended goal with these ARCH_MX.., MACH_MX.. and SOC_IMX.. symbols is:
>
> - ARCH_MX.. should be only a helper to group all machines together that
> can be built in a single image. In the far future it hopefully dies
> because we can compile everything together. These IMHO should not be
> used in Makefiles or source files at all as the grouping can change
> over time. I'm not sure the name ARCH_MX.. is that good. Didn't think
> about a better naming scheme, so if you have suggestions don't
> hesitate to tell them.
Would it make sense to go straight forward?
ARCH_MX.. for SoC series. eg. ARCH_MX1/2/3/5. It groups SoCs.
SOC_IMX.. for single SoC. eg. SOC_IMX31/35/50/51/53. It groups Machines.
MACH_.. for single machine. eg. MACH_MX51_BABBAGE.
They can be used in Makefiles to help include source files, but idealy not be
used in source files. For multi-soc in single image, it's more easy to select
build targets. It can also help transit to single image step by step.
> - MACH_MX.. actually are misnomers becauce they clash with the name
> space of the machine db. So they should be substituted by SOC_IMX...
> (maybe a few by ARCH_MX..) (affected: MACH_MX21 and MACH_MX27)
> - SOC_IMX.. are used to differentiate between SoCs.
>
> So a goal is to review all ARCH_MX.. and MACH_MX.. used in .c and .h
> files and try to use the SOC_IMX variables instead.
> Here I consider important that SOC_IMX... is really only used with
> having multi-SoC-kernels in mind. So you can consider ARCH_MX and
> MACH_MX as todo-markers for that (and this is the main difference IMHO).
> E.g. the Makefile.boots are such a place that are not multi-soc capable
> yet as is the selection of PHYS_OFFSET. I'd like to keep them marked
> somehow.
The ToDO markers might label itself as markers, Or it cause many people
confused.
And are you sure we won't need ARCH_MX.. in the final single image solution?
IMHO, single image needs to select what targetis it builds for too. The ARCH_MX..
works as categories and help reduce image size.
>
> I don't know if it's sensible to coordinate this effort, it mainly
> depends on how many people are willing to help. I'll start with ARCH_MX2
> and MACH_MX2[17] next.
>
> A bit orthogonal to this issue is to clean up mach-mx3 and mach-mx5 to
> allow them to be merged into mach-imx. I didn't look at all on mxc91231,
> yet.
>
> Comments and patches are welcome. If you want to help and don't know
> where to start, here are a few hints:
>
> - git grep -E 'M?AR?CH_MX' drivers
> - convert arch/arm/mach-mx[35]/devices.c to dynamically allocation
>
> Richard, having said that, some of your changes look OK, while I'm not
> completely happy with the others.
It seems only PHYS_OFFSET are not ok? Maybe the p2v patch can help?
>
> > diff --git a/arch/arm/mach-mx5/Kconfig b/arch/arm/mach-mx5/Kconfig
> > index f065a0d..518a39e 100644
> > --- a/arch/arm/mach-mx5/Kconfig
> > +++ b/arch/arm/mach-mx5/Kconfig
> > @@ -1,14 +1,4 @@
> > if ARCH_MX5
> > -# ARCH_MX51 and ARCH_MX50 are left for compatibility
> > -
> > -config ARCH_MX50
> > - bool
> > -
> > -config ARCH_MX51
> > - bool
> > -
> > -config ARCH_MX53
> > - bool
> these are still needed, see below (or you should suggest an alternative marking).
>
> > config SOC_IMX50
> > bool
> > @@ -16,7 +6,6 @@ config SOC_IMX50
> > select ARCH_MXC_IOMUX_V3
> > select ARCH_MXC_AUDMUX_V2
> > select ARCH_HAS_CPUFREQ
> > - select ARCH_MX50
> >
> > config SOC_IMX51
> > bool
> > @@ -24,13 +13,11 @@ config SOC_IMX51
> > select ARCH_MXC_IOMUX_V3
> > select ARCH_MXC_AUDMUX_V2
> > select ARCH_HAS_CPUFREQ
> > - select ARCH_MX51
> >
> > config SOC_IMX53
> > bool
> > select MXC_TZIC
> > select ARCH_MXC_IOMUX_V3
> > - select ARCH_MX53
> >
> > comment "MX5 platforms:"
> >
> > diff --git a/arch/arm/mach-mx5/Makefile.boot b/arch/arm/mach-mx5/Makefile.boot
> > index e928be1..cdc70b3 100644
> > --- a/arch/arm/mach-mx5/Makefile.boot
> > +++ b/arch/arm/mach-mx5/Makefile.boot
> > @@ -1,9 +1,9 @@
> > - zreladdr-$(CONFIG_ARCH_MX50) := 0x70008000
> > -params_phys-$(CONFIG_ARCH_MX50) := 0x70000100
> > -initrd_phys-$(CONFIG_ARCH_MX50) := 0x70800000
> > - zreladdr-$(CONFIG_ARCH_MX51) := 0x90008000
> > -params_phys-$(CONFIG_ARCH_MX51) := 0x90000100
> > -initrd_phys-$(CONFIG_ARCH_MX51) := 0x90800000
> > - zreladdr-$(CONFIG_ARCH_MX53) := 0x70008000
> > -params_phys-$(CONFIG_ARCH_MX53) := 0x70000100
> > -initrd_phys-$(CONFIG_ARCH_MX53) := 0x70800000
> > + zreladdr-$(CONFIG_SOC_MX50) := 0x70008000
> > +params_phys-$(CONFIG_SOC_MX50) := 0x70000100
> > +initrd_phys-$(CONFIG_SOC_MX50) := 0x70800000
> > + zreladdr-$(CONFIG_SOC_MX51) := 0x90008000
> > +params_phys-$(CONFIG_SOC_MX51) := 0x90000100
> > +initrd_phys-$(CONFIG_SOC_MX51) := 0x90800000
> > + zreladdr-$(CONFIG_SOC_MX53) := 0x70008000
> > +params_phys-$(CONFIG_SOC_MX53) := 0x70000100
> > +initrd_phys-$(CONFIG_SOC_MX53) := 0x70800000
> > diff --git a/arch/arm/plat-mxc/devices/platform-imx-dma.c b/arch/arm/plat-mxc/devices/platform-imx-dma.c
> > index 33530d2..be7df13 100644
> > --- a/arch/arm/plat-mxc/devices/platform-imx-dma.c
> > +++ b/arch/arm/plat-mxc/devices/platform-imx-dma.c
> > @@ -194,7 +194,7 @@ static int __init imxXX_add_imx_dma(void)
> > } else
> > #endif
> >
> > -#if defined(CONFIG_ARCH_MX51)
> > +#if defined(CONFIG_SOC_IMX51)
> > if (cpu_is_mx51()) {
> > imx51_imx_sdma_data.pdata.script_addrs = &addr_imx51_to1;
> > ret = imx_add_imx_sdma(&imx51_imx_sdma_data);
> looks OK.
>
> > diff --git a/arch/arm/plat-mxc/include/mach/irqs.h b/arch/arm/plat-mxc/include/mach/irqs.h
> > index ba65c92..a3d930d 100644
> > --- a/arch/arm/plat-mxc/include/mach/irqs.h
> > +++ b/arch/arm/plat-mxc/include/mach/irqs.h
> > @@ -23,17 +23,17 @@
> > #define MXC_GPIO_IRQ_START MXC_INTERNAL_IRQS
> >
> > /* these are ordered by size to support multi-SoC kernels */
> > -#if defined CONFIG_ARCH_MX53
> > +#if defined CONFIG_SOC_IMX53
> > #define MXC_GPIO_IRQS (32 * 7)
> > #elif defined CONFIG_ARCH_MX2
> > #define MXC_GPIO_IRQS (32 * 6)
> > -#elif defined CONFIG_ARCH_MX50
> > +#elif defined CONFIG_SOC_IMX50
> > #define MXC_GPIO_IRQS (32 * 6)
> > #elif defined CONFIG_ARCH_MX1
> > #define MXC_GPIO_IRQS (32 * 4)
> > #elif defined CONFIG_ARCH_MX25
> > #define MXC_GPIO_IRQS (32 * 4)
> > -#elif defined CONFIG_ARCH_MX51
> > +#elif defined CONFIG_SOC_IMX51
> > #define MXC_GPIO_IRQS (32 * 4)
> > #elif defined CONFIG_ARCH_MXC91231
> > #define MXC_GPIO_IRQS (32 * 4)
> OK
>
> > diff --git a/arch/arm/plat-mxc/include/mach/memory.h b/arch/arm/plat-mxc/include/mach/memory.h
> > index 8386140..f1e9c0a 100644
> > --- a/arch/arm/plat-mxc/include/mach/memory.h
> > +++ b/arch/arm/plat-mxc/include/mach/memory.h
> > @@ -34,11 +34,11 @@
> > # define PHYS_OFFSET MX3x_PHYS_OFFSET
> > # elif defined CONFIG_ARCH_MXC91231
> > # define PHYS_OFFSET MXC91231_PHYS_OFFSET
> > -# elif defined CONFIG_ARCH_MX50
> > +# elif defined CONFIG_SOC_IMX50
> > # define PHYS_OFFSET MX50_PHYS_OFFSET
> > -# elif defined CONFIG_ARCH_MX51
> > +# elif defined CONFIG_SOC_IMX51
> > # define PHYS_OFFSET MX51_PHYS_OFFSET
> > -# elif defined CONFIG_ARCH_MX53
> > +# elif defined CONFIG_SOC_IMX53
> > # define PHYS_OFFSET MX53_PHYS_OFFSET
> > # endif
> > #endif
> not ok
>
> > diff --git a/arch/arm/plat-mxc/include/mach/mxc.h b/arch/arm/plat-mxc/include/mach/mxc.h
> > index 04c7a26..3781f2f 100644
> > --- a/arch/arm/plat-mxc/include/mach/mxc.h
> > +++ b/arch/arm/plat-mxc/include/mach/mxc.h
> > @@ -127,7 +127,7 @@ extern unsigned int __mxc_cpu_type;
> > # define cpu_is_mx35() (0)
> > #endif
> >
> > -#ifdef CONFIG_ARCH_MX50
> > +#ifdef CONFIG_SOC_IMX50
> > # ifdef mxc_cpu_type
> > # undef mxc_cpu_type
> > # define mxc_cpu_type __mxc_cpu_type
> > @@ -139,7 +139,7 @@ extern unsigned int __mxc_cpu_type;
> > # define cpu_is_mx50() (0)
> > #endif
> >
> > -#ifdef CONFIG_ARCH_MX51
> > +#ifdef CONFIG_SOC_IMX51
> > # ifdef mxc_cpu_type
> > # undef mxc_cpu_type
> > # define mxc_cpu_type __mxc_cpu_type
> > @@ -151,7 +151,7 @@ extern unsigned int __mxc_cpu_type;
> > # define cpu_is_mx51() (0)
> > #endif
> >
> > -#ifdef CONFIG_ARCH_MX53
> > +#ifdef CONFIG_SOC_IMX53
> > # ifdef mxc_cpu_type
> > # undef mxc_cpu_type
> > # define mxc_cpu_type __mxc_cpu_type
> These are OK, too, I think
>
> > diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
> > index c895922..daeafc2 100644
> > --- a/drivers/mtd/nand/Kconfig
> > +++ b/drivers/mtd/nand/Kconfig
> > @@ -476,7 +476,7 @@ config MTD_NAND_MPC5121_NFC
> >
> > config MTD_NAND_MXC
> > tristate "MXC NAND support"
> > - depends on ARCH_MX2 || ARCH_MX25 || ARCH_MX3 || ARCH_MX51
> > + depends on ARCH_MX2 || ARCH_MX25 || ARCH_MX3 || SOC_IMX51
> OK, though I'd prefer having
>
> depends on HAVE_MTD_NAND_MXC
>
> and let the SOC_IMXYZ symbols select this one.
Yes. Thanks.
>
> > help
> > This enables the driver for the NAND flash controller on the
> > MXC processors.
> > diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
> > index bb233a9..9f9d3f7 100644
> > --- a/drivers/spi/Kconfig
> > +++ b/drivers/spi/Kconfig
> > @@ -164,10 +164,10 @@ config SPI_IMX_VER_0_4
> > def_bool y if ARCH_MX31
> >
> > config SPI_IMX_VER_0_7
> > - def_bool y if ARCH_MX25 || ARCH_MX35 || ARCH_MX51 || ARCH_MX53
> > + def_bool y if ARCH_MX25 || ARCH_MX35 || SOC_IMX51 || SOC_IMX53
> >
> > config SPI_IMX_VER_2_3
> > - def_bool y if ARCH_MX51 || ARCH_MX53
> > + def_bool y if SOC_IMX51 || SOC_IMX53
> >
> > config SPI_IMX
> > tristate "Freescale i.MX SPI controllers"
> ok
>
Thanks
Richard
> Best regards
> Uwe
>
> --
> Pengutronix e.K. | Uwe Kleine-K?nig |
> Industrial Linux Solutions | http://www.pengutronix.de/ |
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Question about free_pgd_slow ?
From: Rabin Vincent @ 2011-03-02 15:52 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <79b2dce2.4b84.12e5ae30c01.Coremail.bill_carson@126.com>
On Fri, Feb 25, 2011 at 09:05, rocky <bill_carson@126.com> wrote:
> free_pgd_slow in arch/arm/mm/pgd.c ?free the 4 pages at pgd level,l
> while could I ask a question about why free the page by pointed by pgd
> index 0 ?
Besides the 16k for the pgd, it frees the second level* page table
referenced at index 0 of the pgd.
(* - of course it frees pud+pmd+pte, but on current ARM this folds down
to just the second level page table.)
On ARM, FIRST_USER_ADDRESS is set to PAGE_SIZE because the vectors may
need to be placed at 0x0. Since the tables for that translation have to
always be active, functions like exit_mmap() will not free the 0th
secondary level page table (see the calls to free_pgtables() there). So
we free it here when we're freeing the pgd.
^ permalink raw reply
* [PATCH] omap:iommu-added cache flushing operation for L2 cache
From: Gupta, Ramesh @ 2011-03-02 15:46 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1dc497a090414bf80ff588791d6db5cc@mail.gmail.com>
Hi Santosh,
On Wed, Mar 2, 2011 at 6:48 AM, Santosh Shilimkar
<santosh.shilimkar@ti.com>wrote:
> Hello,
> > -----Original Message-----
> > From: linux-omap-owner at vger.kernel.org [mailto:linux-omap-
> > owner at vger.kernel.org] On Behalf Of Fernando Guzman Lugo
> > Sent: Wednesday, March 02, 2011 1:17 AM
> > To: hiroshi.doyu at nokia.com
> > Cc: tony at atomide.com; linux at arm.linux.org.uk; linux-
> > omap at vger.kernel.org; linux-arm-kernel at lists.infradead.org; linux-
> > kernel at vger.kernel.org; Ramesh Gupta; Hari Kanigeri
> > Subject: [PATCH] omap:iommu-added cache flushing operation for L2
> > cache
> >
> > From: Ramesh Gupta <grgupta@ti.com>
> >
> > Signed-off-by: Ramesh Gupta <grgupta@ti.com>
> > Signed-off-by: Hari Kanigeri <h-kanigeri2@ti.com>
> > ---
> > arch/arm/plat-omap/iommu.c | 22 ++++++++--------------
> > 1 files changed, 8 insertions(+), 14 deletions(-)
> >
> > diff --git a/arch/arm/plat-omap/iommu.c b/arch/arm/plat-omap/iommu.c
> > index e3eb038..aeb2c33 100644
> > --- a/arch/arm/plat-omap/iommu.c
> > +++ b/arch/arm/plat-omap/iommu.c
> > @@ -471,22 +471,15 @@ EXPORT_SYMBOL_GPL(foreach_iommu_device);
> > */
> > static void flush_iopgd_range(u32 *first, u32 *last)
> > {
> > - /* FIXME: L2 cache should be taken care of if it exists */
> > - do {
> > - asm("mcr p15, 0, %0, c7, c10, 1 @ flush_pgd"
> > - : : "r" (first));
> > - first += L1_CACHE_BYTES / sizeof(*first);
> > - } while (first <= last);
> > + dmac_flush_range(first, last);
>
> There is note just above this API.
>
Thank you for your comment. I agree, I will send an updated patch with
proper apis.
regards
Ramesh Gupta G
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20110302/32e35286/attachment-0001.html>
^ permalink raw reply
* [patch v2 2/3] arm: pmu: allow platform specifc irq enable/disable handling
From: Will Deacon @ 2011-03-02 15:46 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <AANLkTinbZjNHGiY5Ge-CjHpx9MOxpiELhzmricPEsU=o@mail.gmail.com>
> Hi Will,
Hello,
> 2011/3/2 Will Deacon <will.deacon@arm.com>:
> > Looks good to me. Unfortunately, I don't have an OMAP4 to test this
> > on (contributions welcome :) so I've just eyeballed the code:
> >
> > Reviewed-by: Will Deacon <will.deacon@arm.com>
> >
> > You'll need to wait for the ux500 stuff to be merged before you can
> > get this upstream (Linus W is handling the pull request afaik).
>
> Thanks for your review, the ux500 stuff has been merged into -next
> tree already, so this one may be into -next too.
Ok, that's great. I've just noticed that you've typoed the subject
line for the patch (s/specifc/specific/) so you might want to fix
that before Sergei spots it!
Will
^ permalink raw reply
* [PATCH 6/6] ARM: nmk: update GPIO chained IRQ handler to use EOI in parent chip
From: Will Deacon @ 2011-03-02 15:33 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <alpine.LFD.2.00.1103012133530.2701@localhost6.localdomain6>
Hi Thomas,
> Can you please take the time and explain me the difference of the
> following:
>
> irqchip1.c
>
> struct irq_chip1;
>
> handle_primary_irq(int irq, struct irq_desc *desc)
> {
> chip->irq_ack();
> desc->demux();
> }
>
> init()
> {
> irq_set_chip(PRIMARY_IRQ, &irq_chip1);
> irq_set_primary_handler(PRIMARY_IRQ, handle_primary_irq);
> }
I think with this approach you get the exact opposite problem; that
is the primary irq_chip doesn't know which IRQs are going to be
demuxed so it cannot know at init time which IRQs need their primary
handler set. Is the idea that you set_primary_handler for all IRQs,
stash that in the descriptor somewhere and then replace handle_irq
with the primary handler when a demux handler is registered?
I guess I'm missing something here,
Cheers,
Will
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox