Skip to content

Commit

Permalink
ARM: 7211/1: smp_twd: get the rate from a clock
Browse files Browse the repository at this point in the history
This break-out from Colin Cross' cpufreq-aware TWD patch will
optionally retrieve the clock rate of the TWD from an external
clock. A variant of this patch has been proposed by Rob Herring
as well.

The basic idea is to avoid recalibrating the rate of the clock
at boot if the platform already know what rate the clock to the
TWD block has.

ChangeLog v1->v2: added clk_[prepare|unprepare] calls.

[Broke out of larger SMP TWD patch]

Signed-off-by: Colin Cross <ccross@android.com>
Acked-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Rob Herring <rob.herring@calxeda.com>
Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
  • Loading branch information
Linus Walleij authored and Russell King committed Dec 23, 2011
1 parent 54d15b1 commit 5def51b
Showing 1 changed file with 39 additions and 1 deletion.
40 changes: 39 additions & 1 deletion arch/arm/kernel/smp_twd.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/smp.h>
#include <linux/jiffies.h>
#include <linux/clockchips.h>
Expand All @@ -25,6 +27,7 @@
/* set up by the platform code */
void __iomem *twd_base;

static struct clk *twd_clk;
static unsigned long twd_timer_rate;

static struct clock_event_device __percpu **twd_evt;
Expand Down Expand Up @@ -140,6 +143,35 @@ static irqreturn_t twd_handler(int irq, void *dev_id)
return IRQ_NONE;
}

static struct clk *twd_get_clock(void)
{
struct clk *clk;
int err;

clk = clk_get_sys("smp_twd", NULL);
if (IS_ERR(clk)) {
pr_err("smp_twd: clock not found: %d\n", (int)PTR_ERR(clk));
return clk;
}

err = clk_prepare(clk);
if (err) {
pr_err("smp_twd: clock failed to prepare: %d\n", err);
clk_put(clk);
return ERR_PTR(err);
}

err = clk_enable(clk);
if (err) {
pr_err("smp_twd: clock failed to enable: %d\n", err);
clk_unprepare(clk);
clk_put(clk);
return ERR_PTR(err);
}

return clk;
}

/*
* Setup the local clock events for a CPU.
*/
Expand All @@ -165,7 +197,13 @@ void __cpuinit twd_timer_setup(struct clock_event_device *clk)
}
}

twd_calibrate_rate();
if (!twd_clk)
twd_clk = twd_get_clock();

if (!IS_ERR_OR_NULL(twd_clk))
twd_timer_rate = clk_get_rate(twd_clk);
else
twd_calibrate_rate();

clk->name = "local_timer";
clk->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT |
Expand Down

0 comments on commit 5def51b

Please sign in to comment.