Commit f710bdee authored by Viresh Kumar's avatar Viresh Kumar Committed by Daniel Lezcano

clockevents/drivers/integrator: Migrate to new 'set-state' interface

Migrate integrator driver to the new 'set-state' interface provided by
clockevents core, the earlier 'set-mode' interface is marked obsolete
now.

This also enables us to implement callbacks for new states of clockevent
devices, for example: ONESHOT_STOPPED.

For oneshot mode the clkevt device was first getting disabled by
clearing TIMER_CTRL_ENABLE bits in TIMER_CTRL register, followed by
clearing TIMER_CTRL_PERIODIC bit. Both these are done with a single
write operation now.

Cc: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: default avatarViresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: default avatarDaniel Lezcano <daniel.lezcano@linaro.org>
Acked-by: default avatarLinus Walleij <linus.walleij@linaro.org>
parent e0d1ca33
...@@ -75,33 +75,37 @@ static irqreturn_t integrator_timer_interrupt(int irq, void *dev_id) ...@@ -75,33 +75,37 @@ static irqreturn_t integrator_timer_interrupt(int irq, void *dev_id)
return IRQ_HANDLED; return IRQ_HANDLED;
} }
static void clkevt_set_mode(enum clock_event_mode mode, struct clock_event_device *evt) static int clkevt_shutdown(struct clock_event_device *evt)
{ {
u32 ctrl = readl(clkevt_base + TIMER_CTRL) & ~TIMER_CTRL_ENABLE; u32 ctrl = readl(clkevt_base + TIMER_CTRL) & ~TIMER_CTRL_ENABLE;
/* Disable timer */ /* Disable timer */
writel(ctrl, clkevt_base + TIMER_CTRL); writel(ctrl, clkevt_base + TIMER_CTRL);
return 0;
}
switch (mode) { static int clkevt_set_oneshot(struct clock_event_device *evt)
case CLOCK_EVT_MODE_PERIODIC: {
/* Enable the timer and start the periodic tick */ u32 ctrl = readl(clkevt_base + TIMER_CTRL) &
writel(timer_reload, clkevt_base + TIMER_LOAD); ~(TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC);
ctrl |= TIMER_CTRL_PERIODIC | TIMER_CTRL_ENABLE;
writel(ctrl, clkevt_base + TIMER_CTRL); /* Leave the timer disabled, .set_next_event will enable it */
break; writel(ctrl, clkevt_base + TIMER_CTRL);
case CLOCK_EVT_MODE_ONESHOT: return 0;
/* Leave the timer disabled, .set_next_event will enable it */ }
ctrl &= ~TIMER_CTRL_PERIODIC;
writel(ctrl, clkevt_base + TIMER_CTRL);
break;
case CLOCK_EVT_MODE_UNUSED:
case CLOCK_EVT_MODE_SHUTDOWN:
case CLOCK_EVT_MODE_RESUME:
default:
/* Just leave in disabled state */
break;
}
static int clkevt_set_periodic(struct clock_event_device *evt)
{
u32 ctrl = readl(clkevt_base + TIMER_CTRL) & ~TIMER_CTRL_ENABLE;
/* Disable timer */
writel(ctrl, clkevt_base + TIMER_CTRL);
/* Enable the timer and start the periodic tick */
writel(timer_reload, clkevt_base + TIMER_LOAD);
ctrl |= TIMER_CTRL_PERIODIC | TIMER_CTRL_ENABLE;
writel(ctrl, clkevt_base + TIMER_CTRL);
return 0;
} }
static int clkevt_set_next_event(unsigned long next, struct clock_event_device *evt) static int clkevt_set_next_event(unsigned long next, struct clock_event_device *evt)
...@@ -116,11 +120,15 @@ static int clkevt_set_next_event(unsigned long next, struct clock_event_device * ...@@ -116,11 +120,15 @@ static int clkevt_set_next_event(unsigned long next, struct clock_event_device *
} }
static struct clock_event_device integrator_clockevent = { static struct clock_event_device integrator_clockevent = {
.name = "timer1", .name = "timer1",
.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, .features = CLOCK_EVT_FEAT_PERIODIC |
.set_mode = clkevt_set_mode, CLOCK_EVT_FEAT_ONESHOT,
.set_next_event = clkevt_set_next_event, .set_state_shutdown = clkevt_shutdown,
.rating = 300, .set_state_periodic = clkevt_set_periodic,
.set_state_oneshot = clkevt_set_oneshot,
.tick_resume = clkevt_shutdown,
.set_next_event = clkevt_set_next_event,
.rating = 300,
}; };
static struct irqaction integrator_timer_irq = { static struct irqaction integrator_timer_irq = {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment