* is free-running, and can't generate interrupts.
*
* The 508 kHz timers are ideal for use for the timer interrupt, as the
- * most common values of HZ divide 508 kHz nicely. We pick one of the 16
- * bit timers (timer 1) since we don't need more than 16 bits of reload
- * value as long as HZ >= 8.
+ * most common values of HZ divide 508 kHz nicely. We pick the 32 bit
+ * timer (timer 3) to get as long sleep intervals as possible when using
+ * CONFIG_NO_HZ.
*
* The higher clock rate of timer 4 makes it a better choice than the
- * other timers for use in gettimeoffset(), while the fact that it can't
- * generate interrupts means we don't have to worry about not being able
- * to use this timer for something else. We also use timer 4 for keeping
- * track of lost jiffies.
+ * other timers for use as clock source and for sched_clock(), providing
+ * a stable 40 bit time base.
+ *************************************************************************
*/
#define EP93XX_TIMER_REG(x) (EP93XX_TIMER_BASE + (x))
#define EP93XX_TIMER1_LOAD EP93XX_TIMER_REG(0x00)
{
u64 ret;
- ret = __raw_readl(EP93XX_TIMER4_VALUE_LOW);
- ret |= ((u64) (__raw_readl(EP93XX_TIMER4_VALUE_HIGH) & 0xff) << 32);
+ ret = readl(EP93XX_TIMER4_VALUE_LOW);
+ ret |= ((u64) (readl(EP93XX_TIMER4_VALUE_HIGH) & 0xff) << 32);
return ret;
}
{
u64 ret;
- ret = __raw_readl(EP93XX_TIMER4_VALUE_LOW);
- ret |= ((u64) (__raw_readl(EP93XX_TIMER4_VALUE_HIGH) & 0xff) << 32);
+ ret = readl(EP93XX_TIMER4_VALUE_LOW);
+ ret |= ((u64) (readl(EP93XX_TIMER4_VALUE_HIGH) & 0xff) << 32);
return (cycle_t) ret;
}
EP93XX_TIMER123_CONTROL_CLKSEL;
/* Clear timer */
- __raw_writel(tmode, EP93XX_TIMER1_CONTROL);
+ writel(tmode, EP93XX_TIMER3_CONTROL);
/* Set next event */
- __raw_writel(next, EP93XX_TIMER1_LOAD);
- __raw_writel(tmode | EP93XX_TIMER123_CONTROL_ENABLE,
- EP93XX_TIMER1_CONTROL);
+ writel(next, EP93XX_TIMER3_LOAD);
+ writel(tmode | EP93XX_TIMER123_CONTROL_ENABLE,
+ EP93XX_TIMER3_CONTROL);
return 0;
}
-static void ep93xx_clkevt_set_mode(enum clock_event_mode mode,
- struct clock_event_device *evt)
+static int ep93xx_clkevt_shutdown(struct clock_event_device *evt)
{
/* Disable timer */
- __raw_writel(0, EP93XX_TIMER1_CONTROL);
+ writel(0, EP93XX_TIMER3_CONTROL);
+
+ return 0;
}
static struct clock_event_device ep93xx_clockevent = {
- .name = "timer1",
- .features = CLOCK_EVT_FEAT_ONESHOT,
- .set_mode = ep93xx_clkevt_set_mode,
- .set_next_event = ep93xx_clkevt_set_next_event,
- .rating = 300,
+ .name = "timer1",
+ .features = CLOCK_EVT_FEAT_ONESHOT,
+ .set_state_shutdown = ep93xx_clkevt_shutdown,
+ .set_state_oneshot = ep93xx_clkevt_shutdown,
+ .tick_resume = ep93xx_clkevt_shutdown,
+ .set_next_event = ep93xx_clkevt_set_next_event,
+ .rating = 300,
};
static irqreturn_t ep93xx_timer_interrupt(int irq, void *dev_id)
struct clock_event_device *evt = dev_id;
/* Writing any value clears the timer interrupt */
- __raw_writel(1, EP93XX_TIMER1_CLEAR);
+ writel(1, EP93XX_TIMER3_CLEAR);
evt->event_handler(evt);
void __init ep93xx_timer_init(void)
{
/* Enable and register clocksource and sched_clock on timer 4 */
- __raw_writel(EP93XX_TIMER4_VALUE_HIGH_ENABLE,
- EP93XX_TIMER4_VALUE_HIGH);
+ writel(EP93XX_TIMER4_VALUE_HIGH_ENABLE,
+ EP93XX_TIMER4_VALUE_HIGH);
clocksource_mmio_init(NULL, "timer4",
EP93XX_TIMER4_RATE, 200, 40,
ep93xx_clocksource_read);
sched_clock_register(ep93xx_read_sched_clock, 40,
EP93XX_TIMER4_RATE);
- /* Set up clockevent on timer 1 */
- setup_irq(IRQ_EP93XX_TIMER1, &ep93xx_timer_irq);
- // FIXME: timer one is 16 bits 1-ffff use timer 3 1-ffffffff */
+ /* Set up clockevent on timer 3 */
+ setup_irq(IRQ_EP93XX_TIMER3, &ep93xx_timer_irq);
clockevents_config_and_register(&ep93xx_clockevent,
EP93XX_TIMER123_RATE,
1,
- 0xffffU);
+ 0xffffffffU);
}