Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a894fcc2 authored by Stephen Boyd's avatar Stephen Boyd
Browse files

ARM: smp_twd: Divorce smp_twd from local timer API



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

Tested-by: default avatarMark Rutland <mark.rutland@arm.com>
Acked-by: default avatarMarc Zyngier <marc.zyngier@arm.com>
Cc: Russell King <linux@arm.linux.org.uk>
Cc: Tony Lindgren <tony@atomide.com>
Signed-off-by: default avatarStephen Boyd <sboyd@codeaurora.org>
parent 3d53ceec
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -638,7 +638,7 @@ config ARCH_SHMOBILE
	select CLKDEV_LOOKUP
	select GENERIC_CLOCKEVENTS
	select HAVE_ARM_SCU if SMP
	select HAVE_ARM_TWD if LOCAL_TIMERS
	select HAVE_ARM_TWD if SMP
	select HAVE_CLK
	select HAVE_MACH_CLKDEV
	select HAVE_SMP
+43 −21
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/clk.h>
#include <linux/cpu.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/err.h>
@@ -24,7 +25,6 @@

#include <asm/smp_plat.h>
#include <asm/smp_twd.h>
#include <asm/localtimer.h>

/* set up by the platform code */
static void __iomem *twd_base;
@@ -33,7 +33,7 @@ static struct clk *twd_clk;
static unsigned long twd_timer_rate;
static DEFINE_PER_CPU(bool, percpu_setup_called);

static struct clock_event_device __percpu **twd_evt;
static struct clock_event_device __percpu *twd_evt;
static int twd_ppi;

static void twd_set_mode(enum clock_event_mode mode,
@@ -90,8 +90,10 @@ static int twd_timer_ack(void)
	return 0;
}

static void twd_timer_stop(struct clock_event_device *clk)
static void twd_timer_stop(void)
{
	struct clock_event_device *clk = __this_cpu_ptr(twd_evt);

	twd_set_mode(CLOCK_EVT_MODE_UNUSED, clk);
	disable_percpu_irq(clk->irq);
}
@@ -106,7 +108,7 @@ static void twd_update_frequency(void *new_rate)
{
	twd_timer_rate = *((unsigned long *) new_rate);

	clockevents_update_freq(*__this_cpu_ptr(twd_evt), twd_timer_rate);
	clockevents_update_freq(__this_cpu_ptr(twd_evt), twd_timer_rate);
}

static int twd_rate_change(struct notifier_block *nb,
@@ -132,7 +134,7 @@ static struct notifier_block twd_clk_nb = {

static int twd_clk_init(void)
{
	if (twd_evt && *__this_cpu_ptr(twd_evt) && !IS_ERR(twd_clk))
	if (twd_evt && __this_cpu_ptr(twd_evt) && !IS_ERR(twd_clk))
		return clk_notifier_register(twd_clk, &twd_clk_nb);

	return 0;
@@ -151,7 +153,7 @@ static void twd_update_frequency(void *data)
{
	twd_timer_rate = clk_get_rate(twd_clk);

	clockevents_update_freq(*__this_cpu_ptr(twd_evt), twd_timer_rate);
	clockevents_update_freq(__this_cpu_ptr(twd_evt), twd_timer_rate);
}

static int twd_cpufreq_transition(struct notifier_block *nb,
@@ -177,7 +179,7 @@ static struct notifier_block twd_cpufreq_nb = {

static int twd_cpufreq_init(void)
{
	if (twd_evt && *__this_cpu_ptr(twd_evt) && !IS_ERR(twd_clk))
	if (twd_evt && __this_cpu_ptr(twd_evt) && !IS_ERR(twd_clk))
		return cpufreq_register_notifier(&twd_cpufreq_nb,
			CPUFREQ_TRANSITION_NOTIFIER);

@@ -228,7 +230,7 @@ static void __cpuinit twd_calibrate_rate(void)

static irqreturn_t twd_handler(int irq, void *dev_id)
{
	struct clock_event_device *evt = *(struct clock_event_device **)dev_id;
	struct clock_event_device *evt = dev_id;

	if (twd_timer_ack()) {
		evt->event_handler(evt);
@@ -265,9 +267,9 @@ static void twd_get_clock(struct device_node *np)
/*
 * Setup the local clock events for a CPU.
 */
static int __cpuinit twd_timer_setup(struct clock_event_device *clk)
static void __cpuinit twd_timer_setup(void)
{
	struct clock_event_device **this_cpu_clk;
	struct clock_event_device *clk = __this_cpu_ptr(twd_evt);
	int cpu = smp_processor_id();

	/*
@@ -276,9 +278,9 @@ static int __cpuinit twd_timer_setup(struct clock_event_device *clk)
	 */
	if (per_cpu(percpu_setup_called, cpu)) {
		__raw_writel(0, twd_base + TWD_TIMER_CONTROL);
		clockevents_register_device(*__this_cpu_ptr(twd_evt));
		clockevents_register_device(clk);
		enable_percpu_irq(clk->irq, 0);
		return 0;
		return;
	}
	per_cpu(percpu_setup_called, cpu) = true;

@@ -297,27 +299,37 @@ static int __cpuinit twd_timer_setup(struct clock_event_device *clk)
	clk->set_mode = twd_set_mode;
	clk->set_next_event = twd_set_next_event;
	clk->irq = twd_ppi;

	this_cpu_clk = __this_cpu_ptr(twd_evt);
	*this_cpu_clk = clk;
	clk->cpumask = cpumask_of(cpu);

	clockevents_config_and_register(clk, twd_timer_rate,
					0xf, 0xffffffff);
	enable_percpu_irq(clk->irq, 0);
}

	return 0;
static int __cpuinit twd_timer_cpu_notify(struct notifier_block *self,
					   unsigned long action, void *hcpu)
{
	switch (action & ~CPU_TASKS_FROZEN) {
	case CPU_STARTING:
		twd_timer_setup();
		break;
	case CPU_DYING:
		twd_timer_stop();
		break;
	}

	return NOTIFY_OK;
}

static struct local_timer_ops twd_lt_ops __cpuinitdata = {
	.setup	= twd_timer_setup,
	.stop	= twd_timer_stop,
static struct notifier_block twd_timer_cpu_nb __cpuinitdata = {
	.notifier_call = twd_timer_cpu_notify,
};

static int __init twd_local_timer_common_register(struct device_node *np)
{
	int err;

	twd_evt = alloc_percpu(struct clock_event_device *);
	twd_evt = alloc_percpu(struct clock_event_device);
	if (!twd_evt) {
		err = -ENOMEM;
		goto out_free;
@@ -329,12 +341,22 @@ static int __init twd_local_timer_common_register(struct device_node *np)
		goto out_free;
	}

	err = local_timer_register(&twd_lt_ops);
	err = register_cpu_notifier(&twd_timer_cpu_nb);
	if (err)
		goto out_irq;

	twd_get_clock(np);

	/*
	 * Immediately configure the timer on the boot CPU, unless we need
	 * jiffies to be incrementing to calibrate the rate in which case
	 * setup the timer in late_time_init.
	 */
	if (twd_timer_rate)
		twd_timer_setup();
	else
		late_time_init = twd_timer_setup;

	return 0;

out_irq:
+1 −1
Original line number Diff line number Diff line
@@ -12,7 +12,7 @@ config ARCH_HIGHBANK
	select CPU_V7
	select GENERIC_CLOCKEVENTS
	select HAVE_ARM_SCU
	select HAVE_ARM_TWD if LOCAL_TIMERS
	select HAVE_ARM_TWD if SMP
	select HAVE_SMP
	select MAILBOX
	select PL320_MBOX
+1 −1
Original line number Diff line number Diff line
@@ -798,7 +798,7 @@ config SOC_IMX6Q
	select COMMON_CLK
	select CPU_V7
	select HAVE_ARM_SCU if SMP
	select HAVE_ARM_TWD if LOCAL_TIMERS
	select HAVE_ARM_TWD if SMP
	select HAVE_CAN_FLEXCAN if CAN
	select HAVE_IMX_ANATOP
	select HAVE_IMX_GPC
+1 −1
Original line number Diff line number Diff line
@@ -90,7 +90,7 @@ config ARCH_OMAP4
	select CACHE_L2X0
	select CPU_V7
	select HAVE_ARM_SCU if SMP
	select HAVE_ARM_TWD if LOCAL_TIMERS
	select HAVE_ARM_TWD if SMP
	select HAVE_SMP
	select LOCAL_TIMERS if SMP
	select OMAP_INTERCONNECT
Loading