clocksource: samsung_pwm_timer: Correct programming of clock events
authorTomasz Figa <t.figa@samsung.com>
Tue, 23 Apr 2013 15:46:29 +0000 (17:46 +0200)
committerOlof Johansson <olof@lixom.net>
Sun, 28 Apr 2013 19:17:01 +0000 (12:17 -0700)
In current code, the tick count value programmed to the hardware is
always decremented by one. This is reasonable for periodic mode, since
there is one extra tick between 0 and COUNT (after reloading), but it
makes oneshot events happen 1 tick earlier than requested, because the
interrupt is triggered on transition from 1 to 0.

This patch removes the decrementation from PWM channel setup code and
moves it instead to periodic timer setup, to make both periodic and
oneshot modes work correctly.

Signed-off-by: Tomasz Figa <t.figa@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Reviewed-by: Arnd Bergmann <arnd@arndb.de>
Acked-by: Kukjin Kim <kgene.kim@samsung.com>
Signed-off-by: Olof Johansson <olof@lixom.net>
drivers/clocksource/samsung_pwm_timer.c

index cb866156b8b0614779ebd93f0fb7b48163c16ed9..92b2f130ae9bb399dc1c6fa63d655f405df9b253 100644 (file)
@@ -138,8 +138,6 @@ static void samsung_time_setup(unsigned int channel, unsigned long tcnt)
 
        tcon = __raw_readl(pwm.base + REG_TCON);
 
-       tcnt--;
-
        tcon &= ~(TCON_START(tcon_chan) | TCON_AUTORELOAD(tcon_chan));
        tcon |= TCON_MANUALUPDATE(tcon_chan);
 
@@ -187,7 +185,7 @@ static int samsung_set_next_event(unsigned long cycles,
 static void samsung_timer_resume(void)
 {
        /* event timer restart */
-       samsung_time_setup(pwm.event_id, pwm.clock_count_per_tick);
+       samsung_time_setup(pwm.event_id, pwm.clock_count_per_tick - 1);
        samsung_time_start(pwm.event_id, true);
 
        /* source timer restart */
@@ -202,7 +200,7 @@ static void samsung_set_mode(enum clock_event_mode mode,
 
        switch (mode) {
        case CLOCK_EVT_MODE_PERIODIC:
-               samsung_time_setup(pwm.event_id, pwm.clock_count_per_tick);
+               samsung_time_setup(pwm.event_id, pwm.clock_count_per_tick - 1);
                samsung_time_start(pwm.event_id, true);
                break;