Commit bd603455 authored by Rob Herring's avatar Rob Herring Committed by Rafael J. Wysocki

ARM: use device tree to get smp_twd clock

Move clk setup to twd_local_timer_common_register and rely on
twd_timer_rate being 0 to force calibration if there is no clock.
Remove common_setup_called as it is no longer needed.
Signed-off-by: default avatarRob Herring <rob.herring@calxeda.com>
Signed-off-by: default avatarMark Langsdorf <mark.langsdorf@calxeda.com>
Acked-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent ab45bd9b
...@@ -31,7 +31,6 @@ static void __iomem *twd_base; ...@@ -31,7 +31,6 @@ static void __iomem *twd_base;
static struct clk *twd_clk; static struct clk *twd_clk;
static unsigned long twd_timer_rate; static unsigned long twd_timer_rate;
static bool common_setup_called;
static DEFINE_PER_CPU(bool, percpu_setup_called); static DEFINE_PER_CPU(bool, percpu_setup_called);
static struct clock_event_device __percpu **twd_evt; static struct clock_event_device __percpu **twd_evt;
...@@ -239,25 +238,28 @@ static irqreturn_t twd_handler(int irq, void *dev_id) ...@@ -239,25 +238,28 @@ static irqreturn_t twd_handler(int irq, void *dev_id)
return IRQ_NONE; return IRQ_NONE;
} }
static struct clk *twd_get_clock(void) static void twd_get_clock(struct device_node *np)
{ {
struct clk *clk;
int err; int err;
clk = clk_get_sys("smp_twd", NULL); if (np)
if (IS_ERR(clk)) { twd_clk = of_clk_get(np, 0);
pr_err("smp_twd: clock not found: %d\n", (int)PTR_ERR(clk)); else
return clk; twd_clk = clk_get_sys("smp_twd", NULL);
if (IS_ERR(twd_clk)) {
pr_err("smp_twd: clock not found %d\n", (int) PTR_ERR(twd_clk));
return;
} }
err = clk_prepare_enable(clk); err = clk_prepare_enable(twd_clk);
if (err) { if (err) {
pr_err("smp_twd: clock failed to prepare+enable: %d\n", err); pr_err("smp_twd: clock failed to prepare+enable: %d\n", err);
clk_put(clk); clk_put(twd_clk);
return ERR_PTR(err); return;
} }
return clk; twd_timer_rate = clk_get_rate(twd_clk);
} }
/* /*
...@@ -280,26 +282,7 @@ static int __cpuinit twd_timer_setup(struct clock_event_device *clk) ...@@ -280,26 +282,7 @@ static int __cpuinit twd_timer_setup(struct clock_event_device *clk)
} }
per_cpu(percpu_setup_called, cpu) = true; per_cpu(percpu_setup_called, cpu) = true;
/* twd_calibrate_rate();
* This stuff only need to be done once for the entire TWD cluster
* during the runtime of the system.
*/
if (!common_setup_called) {
twd_clk = twd_get_clock();
/*
* We use IS_ERR_OR_NULL() here, because if the clock stubs
* are active we will get a valid clk reference which is
* however NULL and will return the rate 0. In that case we
* need to calibrate the rate instead.
*/
if (!IS_ERR_OR_NULL(twd_clk))
twd_timer_rate = clk_get_rate(twd_clk);
else
twd_calibrate_rate();
common_setup_called = true;
}
/* /*
* The following is done once per CPU the first time .setup() is * The following is done once per CPU the first time .setup() is
...@@ -330,7 +313,7 @@ static struct local_timer_ops twd_lt_ops __cpuinitdata = { ...@@ -330,7 +313,7 @@ static struct local_timer_ops twd_lt_ops __cpuinitdata = {
.stop = twd_timer_stop, .stop = twd_timer_stop,
}; };
static int __init twd_local_timer_common_register(void) static int __init twd_local_timer_common_register(struct device_node *np)
{ {
int err; int err;
...@@ -350,6 +333,8 @@ static int __init twd_local_timer_common_register(void) ...@@ -350,6 +333,8 @@ static int __init twd_local_timer_common_register(void)
if (err) if (err)
goto out_irq; goto out_irq;
twd_get_clock(np);
return 0; return 0;
out_irq: out_irq:
...@@ -373,7 +358,7 @@ int __init twd_local_timer_register(struct twd_local_timer *tlt) ...@@ -373,7 +358,7 @@ int __init twd_local_timer_register(struct twd_local_timer *tlt)
if (!twd_base) if (!twd_base)
return -ENOMEM; return -ENOMEM;
return twd_local_timer_common_register(); return twd_local_timer_common_register(NULL);
} }
#ifdef CONFIG_OF #ifdef CONFIG_OF
...@@ -405,7 +390,7 @@ void __init twd_local_timer_of_register(void) ...@@ -405,7 +390,7 @@ void __init twd_local_timer_of_register(void)
goto out; goto out;
} }
err = twd_local_timer_common_register(); err = twd_local_timer_common_register(np);
out: out:
WARN(err, "twd_local_timer_of_register failed (%d)\n", err); WARN(err, "twd_local_timer_of_register failed (%d)\n", err);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment