ARM: mmp/mmp2: dt: enable the clock
The device-tree booted MMP2 needs to enable the timer clock, otherwise it would stop ticking when the boot finishes. It can also use the clock rate from the clk, the non-DT boards need to keep using the hardcoded rates. Signed-off-by: Lubomir Rintel <lkundrak@v3.sk> Acked-by: Pavel Machek <pavel@ucw.cz> Signed-off-by: Olof Johansson <olof@lixom.net>
This commit is contained in:
parent
e78ebdcb6e
commit
f36797ee43
|
@ -2,7 +2,7 @@
|
||||||
#include <linux/reboot.h>
|
#include <linux/reboot.h>
|
||||||
#define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x)
|
#define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x)
|
||||||
|
|
||||||
extern void timer_init(int irq);
|
extern void timer_init(int irq, unsigned long rate);
|
||||||
|
|
||||||
extern void __init mmp_map_io(void);
|
extern void __init mmp_map_io(void);
|
||||||
extern void mmp_restart(enum reboot_mode, const char *);
|
extern void mmp_restart(enum reboot_mode, const char *);
|
||||||
|
|
|
@ -134,7 +134,7 @@ void __init mmp2_timer_init(void)
|
||||||
clk_rst = APBC_APBCLK | APBC_FNCLK | APBC_FNCLKSEL(1);
|
clk_rst = APBC_APBCLK | APBC_FNCLK | APBC_FNCLKSEL(1);
|
||||||
__raw_writel(clk_rst, APBC_TIMERS);
|
__raw_writel(clk_rst, APBC_TIMERS);
|
||||||
|
|
||||||
timer_init(IRQ_MMP2_TIMER1);
|
timer_init(IRQ_MMP2_TIMER1, 6500000);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* on-chip devices */
|
/* on-chip devices */
|
||||||
|
|
|
@ -79,7 +79,7 @@ void __init pxa168_timer_init(void)
|
||||||
/* 3.25MHz, bus/functional clock enabled, release reset */
|
/* 3.25MHz, bus/functional clock enabled, release reset */
|
||||||
__raw_writel(TIMER_CLK_RST, APBC_TIMERS);
|
__raw_writel(TIMER_CLK_RST, APBC_TIMERS);
|
||||||
|
|
||||||
timer_init(IRQ_PXA168_TIMER1);
|
timer_init(IRQ_PXA168_TIMER1, 6500000);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pxa168_clear_keypad_wakeup(void)
|
void pxa168_clear_keypad_wakeup(void)
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
#include <linux/clockchips.h>
|
#include <linux/clockchips.h>
|
||||||
|
#include <linux/clk.h>
|
||||||
|
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
#include <linux/irq.h>
|
#include <linux/irq.h>
|
||||||
|
@ -38,12 +39,6 @@
|
||||||
#include "cputype.h"
|
#include "cputype.h"
|
||||||
#include "clock.h"
|
#include "clock.h"
|
||||||
|
|
||||||
#ifdef CONFIG_CPU_MMP2
|
|
||||||
#define MMP_CLOCK_FREQ 6500000
|
|
||||||
#else
|
|
||||||
#define MMP_CLOCK_FREQ 3250000
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define TIMERS_VIRT_BASE TIMERS1_VIRT_BASE
|
#define TIMERS_VIRT_BASE TIMERS1_VIRT_BASE
|
||||||
|
|
||||||
#define MAX_DELTA (0xfffffffe)
|
#define MAX_DELTA (0xfffffffe)
|
||||||
|
@ -189,19 +184,18 @@ static struct irqaction timer_irq = {
|
||||||
.dev_id = &ckevt,
|
.dev_id = &ckevt,
|
||||||
};
|
};
|
||||||
|
|
||||||
void __init timer_init(int irq)
|
void __init timer_init(int irq, unsigned long rate)
|
||||||
{
|
{
|
||||||
timer_config();
|
timer_config();
|
||||||
|
|
||||||
sched_clock_register(mmp_read_sched_clock, 32, MMP_CLOCK_FREQ);
|
sched_clock_register(mmp_read_sched_clock, 32, rate);
|
||||||
|
|
||||||
ckevt.cpumask = cpumask_of(0);
|
ckevt.cpumask = cpumask_of(0);
|
||||||
|
|
||||||
setup_irq(irq, &timer_irq);
|
setup_irq(irq, &timer_irq);
|
||||||
|
|
||||||
clocksource_register_hz(&cksrc, MMP_CLOCK_FREQ);
|
clocksource_register_hz(&cksrc, rate);
|
||||||
clockevents_config_and_register(&ckevt, MMP_CLOCK_FREQ,
|
clockevents_config_and_register(&ckevt, rate, MIN_DELTA, MAX_DELTA);
|
||||||
MIN_DELTA, MAX_DELTA);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_OF
|
#ifdef CONFIG_OF
|
||||||
|
@ -213,7 +207,9 @@ static const struct of_device_id mmp_timer_dt_ids[] = {
|
||||||
void __init mmp_dt_init_timer(void)
|
void __init mmp_dt_init_timer(void)
|
||||||
{
|
{
|
||||||
struct device_node *np;
|
struct device_node *np;
|
||||||
|
struct clk *clk;
|
||||||
int irq, ret;
|
int irq, ret;
|
||||||
|
unsigned long rate;
|
||||||
|
|
||||||
np = of_find_matching_node(NULL, mmp_timer_dt_ids);
|
np = of_find_matching_node(NULL, mmp_timer_dt_ids);
|
||||||
if (!np) {
|
if (!np) {
|
||||||
|
@ -221,6 +217,18 @@ void __init mmp_dt_init_timer(void)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
clk = of_clk_get(np, 0);
|
||||||
|
if (!IS_ERR(clk)) {
|
||||||
|
ret = clk_prepare_enable(clk);
|
||||||
|
if (ret)
|
||||||
|
goto out;
|
||||||
|
rate = clk_get_rate(clk) / 2;
|
||||||
|
} else if (cpu_is_pj4()) {
|
||||||
|
rate = 6500000;
|
||||||
|
} else {
|
||||||
|
rate = 3250000;
|
||||||
|
}
|
||||||
|
|
||||||
irq = irq_of_parse_and_map(np, 0);
|
irq = irq_of_parse_and_map(np, 0);
|
||||||
if (!irq) {
|
if (!irq) {
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
|
@ -231,7 +239,7 @@ void __init mmp_dt_init_timer(void)
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
timer_init(irq);
|
timer_init(irq, rate);
|
||||||
return;
|
return;
|
||||||
out:
|
out:
|
||||||
pr_err("Failed to get timer from device tree with error:%d\n", ret);
|
pr_err("Failed to get timer from device tree with error:%d\n", ret);
|
||||||
|
|
Loading…
Reference in New Issue