diff options
Diffstat (limited to 'arch/arm/mach-spear/time.c')
-rw-r--r-- | arch/arm/mach-spear/time.c | 91 |
1 files changed, 51 insertions, 40 deletions
diff --git a/arch/arm/mach-spear/time.c b/arch/arm/mach-spear/time.c index 26fda4ed4..9ccffc1d0 100644 --- a/arch/arm/mach-spear/time.c +++ b/arch/arm/mach-spear/time.c @@ -66,8 +66,6 @@ static __iomem void *gpt_base; static struct clk *gpt_clk; -static void clockevent_set_mode(enum clock_event_mode mode, - struct clock_event_device *clk_event_dev); static int clockevent_next_event(unsigned long evt, struct clock_event_device *clk_event_dev); @@ -95,54 +93,67 @@ static void __init spear_clocksource_init(void) 200, 16, clocksource_mmio_readw_up); } -static struct clock_event_device clkevt = { - .name = "tmr0", - .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, - .set_mode = clockevent_set_mode, - .set_next_event = clockevent_next_event, - .shift = 0, /* to be computed */ -}; +static inline void timer_shutdown(struct clock_event_device *evt) +{ + u16 val = readw(gpt_base + CR(CLKEVT)); + + /* stop the timer */ + val &= ~CTRL_ENABLE; + writew(val, gpt_base + CR(CLKEVT)); +} + +static int spear_shutdown(struct clock_event_device *evt) +{ + timer_shutdown(evt); + + return 0; +} + +static int spear_set_oneshot(struct clock_event_device *evt) +{ + u16 val; -static void clockevent_set_mode(enum clock_event_mode mode, - struct clock_event_device *clk_event_dev) + /* stop the timer */ + timer_shutdown(evt); + + val = readw(gpt_base + CR(CLKEVT)); + val |= CTRL_ONE_SHOT; + writew(val, gpt_base + CR(CLKEVT)); + + return 0; +} + +static int spear_set_periodic(struct clock_event_device *evt) { u32 period; u16 val; /* stop the timer */ + timer_shutdown(evt); + + period = clk_get_rate(gpt_clk) / HZ; + period >>= CTRL_PRESCALER16; + writew(period, gpt_base + LOAD(CLKEVT)); + val = readw(gpt_base + CR(CLKEVT)); - val &= ~CTRL_ENABLE; + val &= ~CTRL_ONE_SHOT; + val |= CTRL_ENABLE | CTRL_INT_ENABLE; writew(val, gpt_base + CR(CLKEVT)); - switch (mode) { - case CLOCK_EVT_MODE_PERIODIC: - period = clk_get_rate(gpt_clk) / HZ; - period >>= CTRL_PRESCALER16; - writew(period, gpt_base + LOAD(CLKEVT)); - - val = readw(gpt_base + CR(CLKEVT)); - val &= ~CTRL_ONE_SHOT; - val |= CTRL_ENABLE | CTRL_INT_ENABLE; - writew(val, gpt_base + CR(CLKEVT)); - - break; - case CLOCK_EVT_MODE_ONESHOT: - val = readw(gpt_base + CR(CLKEVT)); - val |= CTRL_ONE_SHOT; - writew(val, gpt_base + CR(CLKEVT)); - - break; - case CLOCK_EVT_MODE_UNUSED: - case CLOCK_EVT_MODE_SHUTDOWN: - case CLOCK_EVT_MODE_RESUME: - - break; - default: - pr_err("Invalid mode requested\n"); - break; - } + return 0; } +static struct clock_event_device clkevt = { + .name = "tmr0", + .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, + .set_state_shutdown = spear_shutdown, + .set_state_periodic = spear_set_periodic, + .set_state_oneshot = spear_set_oneshot, + .tick_resume = spear_shutdown, + .set_next_event = clockevent_next_event, + .shift = 0, /* to be computed */ +}; + static int clockevent_next_event(unsigned long cycles, struct clock_event_device *clk_event_dev) { @@ -193,7 +204,7 @@ static void __init spear_clockevent_init(int irq) setup_irq(irq, &spear_timer_irq); } -const static struct of_device_id timer_of_match[] __initconst = { +static const struct of_device_id const timer_of_match[] __initconst = { { .compatible = "st,spear-timer", }, { }, }; |