#include <linux/mm.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
+#include <linux/clocksource.h>
#include <asm/setup.h>
#include <asm/system.h>
#include <asm/pgtable.h>
#define TICKS_PER_JIFFY 10
#endif
+static u32 m68328_tick_cnt;
+
+/***************************************************************************/
+
+static irqreturn_t hw_tick(int irq, void *dummy)
+{
+ /* Reset Timer1 */
+ TSTAT &= 0;
+
+ m68328_tick_cnt += TICKS_PER_JIFFY;
+ return arch_timer_interrupt(irq, dummy);
+}
+
/***************************************************************************/
static irqreturn_t hw_tick(int irq, void *dummy)
.handler = hw_tick,
};
+/***************************************************************************/
+
+static cycle_t m68328_read_clk(void)
+{
+ unsigned long flags;
+ u32 cycles;
+
+ local_irq_save(flags);
+ cycles = m68328_tick_cnt + TCN;
+ local_irq_restore(flags);
+
+ return cycles;
+}
+
+/***************************************************************************/
+
+static struct clocksource m68328_clk = {
+ .name = "timer",
+ .rating = 250,
+ .read = m68328_read_clk,
+ .shift = 20,
+ .mask = CLOCKSOURCE_MASK(32),
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+/***************************************************************************/
+
void hw_timer_init(void)
{
/* disable timer 1 */
/* Enable timer 1 */
TCTL |= TCTL_TEN;
-}
-
-/***************************************************************************/
-
-unsigned long hw_timer_offset(void)
-{
- unsigned long ticks = TCN, offset = 0;
-
- /* check for pending interrupt */
- if (ticks < (TICKS_PER_JIFFY >> 1) && (ISR & (1 << TMR_IRQ_NUM)))
- offset = 1000000 / HZ;
- ticks = (ticks * 1000000 / HZ) / TICKS_PER_JIFFY;
- return ticks + offset;
+ m68328_clk.mult = clocksource_hz2mult(TICKS_PER_JIFFY*HZ, m68328_clk.shift);
+ clocksource_register(&m68328_clk);
}
/***************************************************************************/