ARM: smp_twd: add device tree support

Add bindings to support DT discovery of the ARM Timer Watchdog
(aka TWD). Only the timer side is converted by this patch.

Acked-by: Rob Herring <rob.herring@calxeda.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
This commit is contained in:
Marc Zyngier
2012-01-10 22:15:45 +00:00
orang tua 81e46f7b6d
melakukan d8e0364364
3 mengubah file dengan 120 tambahan dan 13 penghapusan

Melihat File

@@ -20,6 +20,8 @@
#include <linux/clockchips.h>
#include <linux/irq.h>
#include <linux/io.h>
#include <linux/of_irq.h>
#include <linux/of_address.h>
#include <asm/smp_twd.h>
#include <asm/localtimer.h>
@@ -284,37 +286,86 @@ static struct local_timer_ops twd_lt_ops __cpuinitdata = {
.stop = twd_timer_stop,
};
int __init twd_local_timer_register(struct twd_local_timer *tlt)
static int __init twd_local_timer_common_register(void)
{
int err;
if (twd_base || twd_evt)
return -EBUSY;
twd_ppi = tlt->res[1].start;
twd_evt = alloc_percpu(struct clock_event_device *);
twd_base = ioremap(tlt->res[0].start, resource_size(&tlt->res[0]));
if (!twd_base || !twd_evt) {
if (!twd_evt) {
err = -ENOMEM;
goto out;
goto out_free;
}
err = request_percpu_irq(twd_ppi, twd_handler, "twd", twd_evt);
if (err) {
pr_err("twd: can't register interrupt %d (%d)\n", twd_ppi, err);
goto out;
goto out_free;
}
err = local_timer_register(&twd_lt_ops);
if (err)
goto out;
goto out_irq;
return 0;
out:
out_irq:
free_percpu_irq(twd_ppi, twd_evt);
out_free:
iounmap(twd_base);
twd_base = NULL;
free_percpu(twd_evt);
twd_base = twd_evt = NULL;
return err;
}
int __init twd_local_timer_register(struct twd_local_timer *tlt)
{
if (twd_base || twd_evt)
return -EBUSY;
twd_ppi = tlt->res[1].start;
twd_base = ioremap(tlt->res[0].start, resource_size(&tlt->res[0]));
if (!twd_base)
return -ENOMEM;
return twd_local_timer_common_register();
}
#ifdef CONFIG_OF
const static struct of_device_id twd_of_match[] __initconst = {
{ .compatible = "arm,cortex-a9-twd-timer", },
{ .compatible = "arm,cortex-a5-twd-timer", },
{ .compatible = "arm,arm11mp-twd-timer", },
{ },
};
void __init twd_local_timer_of_register(void)
{
struct device_node *np;
int err;
np = of_find_matching_node(NULL, twd_of_match);
if (!np) {
err = -ENODEV;
goto out;
}
twd_ppi = irq_of_parse_and_map(np, 0);
if (!twd_ppi) {
err = -EINVAL;
goto out;
}
twd_base = of_iomap(np, 0);
if (!twd_base) {
err = -ENOMEM;
goto out;
}
err = twd_local_timer_common_register();
out:
WARN(err, "twd_local_timer_of_register failed (%d)\n", err);
}
#endif