*/
#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
#include <linux/clockchips.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
+#include <asm/sched_clock.h>
#include <asm/mach/time.h>
#include <mach/bridge-regs.h>
+#include <mach/hardware.h>
/*
* Number of timer ticks per jiffy.
#define TIMER1_VAL (TIMER_VIRT_BASE + 0x001c)
+/*
+ * Orion's sched_clock implementation. It has a resolution of
+ * at least 7.5ns (133MHz TCLK).
+ */
+static DEFINE_CLOCK_DATA(cd);
+
+unsigned long long notrace sched_clock(void)
+{
+ u32 cyc = 0xffffffff - readl(TIMER0_VAL);
+ return cyc_to_sched_clock(&cd, cyc, (u32)~0);
+}
+
+
+static void notrace orion_update_sched_clock(void)
+{
+ u32 cyc = 0xffffffff - readl(TIMER0_VAL);
+ update_sched_clock(&cd, cyc, (u32)~0);
+}
+
+static void __init setup_sched_clock(unsigned long tclk)
+{
+ init_sched_clock(&cd, orion_update_sched_clock, 32, tclk);
+}
+
/*
* Clocksource handling.
*/
static struct clocksource orion_clksrc = {
.name = "orion_clocksource",
- .shift = 20,
.rating = 300,
.read = orion_clksrc_read,
.mask = CLOCKSOURCE_MASK(32),
ticks_per_jiffy = (tclk + HZ/2) / HZ;
+ /*
+ * Set scale and timer for sched_clock
+ */
+ setup_sched_clock(tclk);
/*
* Setup free-running clocksource timer (interrupts
writel(u & ~BRIDGE_INT_TIMER0, BRIDGE_MASK);
u = readl(TIMER_CTRL);
writel(u | TIMER0_EN | TIMER0_RELOAD_EN, TIMER_CTRL);
- orion_clksrc.mult = clocksource_hz2mult(tclk, orion_clksrc.shift);
- clocksource_register(&orion_clksrc);
-
+ clocksource_register_hz(&orion_clksrc, tclk);
/*
* Setup clockevent timer (interrupt-driven.)