[PATCH v2 2/7] ARM: mmp: parse timer configuration from DT
Haojian Zhuang
haojian.zhuang at marvell.com
Thu Jul 28 02:41:28 EDT 2011
Parse timer configuration from DT. Now we can merge pxa910_timer and
mmp2_timer into mmp_timer. Since most configuration between these two
timers are same. The difference is recorded in DT.
Signed-off-by: Haojian Zhuang <haojian.zhuang at marvell.com>
---
.../devicetree/bindings/arm/marvell/timer.txt | 24 +++++++++
arch/arm/mach-mmp/common.h | 2 +
arch/arm/mach-mmp/time.c | 50 +++++++++++++++++++-
3 files changed, 75 insertions(+), 1 deletions(-)
create mode 100644 Documentation/devicetree/bindings/arm/marvell/timer.txt
diff --git a/Documentation/devicetree/bindings/arm/marvell/timer.txt b/Documentation/devicetree/bindings/arm/marvell/timer.txt
new file mode 100644
index 0000000..24a6f97
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/marvell/timer.txt
@@ -0,0 +1,24 @@
+* Timer Controller Binding for ARCH-MMP
+
+This binding specifies what properties must be available in device tree
+representation of an ARCH-MMP compliant timer controller.
+
+Required properties:
+
+ - compatible: Specifies the compatibility list of the timer controller.
+ The type shall be <string> and the value shall be
+ "mrvl,pxa168-timer".
+
+ - mrvl,clk-conf: Specifies the address and value of timer
+ configuration register.
+ The type shall be <prop-encoded-array>. The first value indicates
+ the physical address of timer configuration register. The second
+ value indicates data should be written to timer configuration
+ register.
+
+* Example
+
+ mmp_timer: {
+ compatible = "mrvl,pxa168-timer";
+ mrvl,clk-conf = <0xd4000034 0x33>;
+ };
diff --git a/arch/arm/mach-mmp/common.h b/arch/arm/mach-mmp/common.h
index 1c563c2..890c664 100644
--- a/arch/arm/mach-mmp/common.h
+++ b/arch/arm/mach-mmp/common.h
@@ -2,6 +2,8 @@
struct sys_timer;
+extern struct sys_timer mmp_timer;
+
extern void timer_init(int irq);
extern void __init icu_init_irq(void);
diff --git a/arch/arm/mach-mmp/time.c b/arch/arm/mach-mmp/time.c
index 99833b9..5a90b27 100644
--- a/arch/arm/mach-mmp/time.c
+++ b/arch/arm/mach-mmp/time.c
@@ -25,6 +25,8 @@
#include <linux/io.h>
#include <linux/irq.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
#include <linux/sched.h>
#include <asm/sched_clock.h>
@@ -150,7 +152,7 @@ static void __init timer_config(void)
__raw_writel(cer & ~0x1, TIMERS_VIRT_BASE + TMR_CER); /* disable */
- ccr &= (cpu_is_mmp2()) ? TMR_CCR_CS_0(0) : TMR_CCR_CS_0(3);
+ ccr &= TMR_CCR_CS_0(0);
__raw_writel(ccr, TIMERS_VIRT_BASE + TMR_CCR);
/* free-running mode */
@@ -187,3 +189,49 @@ void __init timer_init(int irq)
clocksource_register_hz(&cksrc, CLOCK_TICK_RATE);
clockevents_register_device(&ckevt);
}
+
+#ifdef CONFIG_OF
+static void __init mmp_timer_init(void)
+{
+ struct device_node *np;
+ const __be32 *clk_offs;
+ void __iomem *conf;
+ unsigned int addr = 0, offs = 0;
+ int size, irq;
+
+ np = of_find_compatible_node(NULL, NULL, "mrvl,pxa168-timer");
+
+ BUG_ON(!np);
+
+ of_node_get(np);
+ irq = irq_of_parse_and_map(np, 0);
+
+ clk_offs = of_get_property(np, "mrvl,clk-conf", &size);
+ if ((clk_offs == NULL) || (size != sizeof(int) * 2)) {
+ pr_warn("mmp-timer: mrvl,clk-conf property is wrong\n");
+ goto out;
+ }
+ addr = be32_to_cpu(*clk_offs) & PAGE_MASK;
+ offs = be32_to_cpu(*clk_offs) - addr;
+ conf = ioremap(addr, PAGE_SIZE);
+ if (conf == NULL) {
+ pr_warn("mmp-timer: failed on mapping 0x%x\n", (uint32_t)conf);
+ goto out;
+ }
+ /* reset and configure */
+ __raw_writel(APBC_APBCLK | APBC_RST, conf + offs);
+ __raw_writel(be32_to_cpu(*++clk_offs), conf + offs);
+ __raw_readl(conf + offs);
+ iounmap(conf);
+
+ timer_init(irq);
+ return;
+out:
+ of_node_put(np);
+ return;
+}
+
+struct sys_timer mmp_timer = {
+ .init = mmp_timer_init,
+};
+#endif
--
1.5.6.5
More information about the linux-arm-kernel
mailing list