From: Tomasz Figa Date: Tue, 23 Apr 2013 15:46:29 +0000 (+0200) Subject: clocksource: samsung_pwm_timer: Correct programming of clock events X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=6fe4dfd041dadbc1cc2460ed8680f2734dc3dc95;p=linux-beck.git clocksource: samsung_pwm_timer: Correct programming of clock events 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 Signed-off-by: Kyungmin Park Reviewed-by: Arnd Bergmann Acked-by: Kukjin Kim Signed-off-by: Olof Johansson --- diff --git a/drivers/clocksource/samsung_pwm_timer.c b/drivers/clocksource/samsung_pwm_timer.c index cb866156b8b0..92b2f130ae9b 100644 --- a/drivers/clocksource/samsung_pwm_timer.c +++ b/drivers/clocksource/samsung_pwm_timer.c @@ -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;