summaryrefslogtreecommitdiff
path: root/drivers/clocksource/db5500-mtimer.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/clocksource/db5500-mtimer.c')
-rw-r--r--drivers/clocksource/db5500-mtimer.c67
1 files changed, 67 insertions, 0 deletions
diff --git a/drivers/clocksource/db5500-mtimer.c b/drivers/clocksource/db5500-mtimer.c
new file mode 100644
index 00000000000..5e64da19e66
--- /dev/null
+++ b/drivers/clocksource/db5500-mtimer.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2011
+ *
+ * License Terms: GNU General Public License v2
+ */
+
+#include <linux/io.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/clockchips.h>
+#include <linux/clksrc-db5500-mtimer.h>
+#include <linux/boottime.h>
+
+#include <asm/sched_clock.h>
+
+#define MTIMER_PRIMARY_COUNTER 0x18
+
+static void __iomem *db5500_mtimer_base;
+
+#ifdef CONFIG_CLKSRC_DB5500_MTIMER_SCHED_CLOCK
+static DEFINE_CLOCK_DATA(cd);
+
+unsigned long long notrace sched_clock(void)
+{
+ u32 cyc;
+
+ if (unlikely(!db5500_mtimer_base))
+ return 0;
+
+ cyc = readl_relaxed(db5500_mtimer_base + MTIMER_PRIMARY_COUNTER);
+
+ return cyc_to_sched_clock(&cd, cyc, (u32)~0);
+}
+
+static void notrace db5500_mtimer_update_sched_clock(void)
+{
+ u32 cyc = readl_relaxed(db5500_mtimer_base + MTIMER_PRIMARY_COUNTER);
+ update_sched_clock(&cd, cyc, (u32)~0);
+}
+#endif
+
+#ifdef CONFIG_BOOTTIME
+static unsigned long __init boottime_get_time(void)
+{
+ return sched_clock();
+}
+
+static struct boottime_timer __initdata boottime_timer = {
+ .init = NULL,
+ .get_time = boottime_get_time,
+ .finalize = NULL,
+};
+#endif
+
+void __init db5500_mtimer_init(void __iomem *base)
+{
+ db5500_mtimer_base = base;
+
+ clocksource_mmio_init(base + MTIMER_PRIMARY_COUNTER, "mtimer", 32768,
+ 400, 32, clocksource_mmio_readl_up);
+
+#ifdef CONFIG_CLKSRC_DB5500_MTIMER_SCHED_CLOCK
+ init_sched_clock(&cd, db5500_mtimer_update_sched_clock,
+ 32, 32768);
+#endif
+ boottime_activate(&boottime_timer);
+}