aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTomasz Figa <t.figa@samsung.com>2013-04-23 11:46:29 -0400
committerOlof Johansson <olof@lixom.net>2013-04-28 15:17:01 -0400
commit6fe4dfd041dadbc1cc2460ed8680f2734dc3dc95 (patch)
tree05c695f8677efcdfbaa6a3e8e84b7c57d940f172
parente9b852b8a7bc0217a03afff07fad34093e087542 (diff)
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 <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>
-rw-r--r--drivers/clocksource/samsung_pwm_timer.c6
1 files changed, 2 insertions, 4 deletions
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)
138 138
139 tcon = __raw_readl(pwm.base + REG_TCON); 139 tcon = __raw_readl(pwm.base + REG_TCON);
140 140
141 tcnt--;
142
143 tcon &= ~(TCON_START(tcon_chan) | TCON_AUTORELOAD(tcon_chan)); 141 tcon &= ~(TCON_START(tcon_chan) | TCON_AUTORELOAD(tcon_chan));
144 tcon |= TCON_MANUALUPDATE(tcon_chan); 142 tcon |= TCON_MANUALUPDATE(tcon_chan);
145 143
@@ -187,7 +185,7 @@ static int samsung_set_next_event(unsigned long cycles,
187static void samsung_timer_resume(void) 185static void samsung_timer_resume(void)
188{ 186{
189 /* event timer restart */ 187 /* event timer restart */
190 samsung_time_setup(pwm.event_id, pwm.clock_count_per_tick); 188 samsung_time_setup(pwm.event_id, pwm.clock_count_per_tick - 1);
191 samsung_time_start(pwm.event_id, true); 189 samsung_time_start(pwm.event_id, true);
192 190
193 /* source timer restart */ 191 /* source timer restart */
@@ -202,7 +200,7 @@ static void samsung_set_mode(enum clock_event_mode mode,
202 200
203 switch (mode) { 201 switch (mode) {
204 case CLOCK_EVT_MODE_PERIODIC: 202 case CLOCK_EVT_MODE_PERIODIC:
205 samsung_time_setup(pwm.event_id, pwm.clock_count_per_tick); 203 samsung_time_setup(pwm.event_id, pwm.clock_count_per_tick - 1);
206 samsung_time_start(pwm.event_id, true); 204 samsung_time_start(pwm.event_id, true);
207 break; 205 break;
208 206