Skip to content

Commit

Permalink
clocksource: improve sh_cmt clocksource overflow handling
Browse files Browse the repository at this point in the history
This patch improves the sh_cmt clocksource handling.

Currently the counter value is ignored in the case of
overflow. With this patch the overflow flag is read
before and after reading the counter, removing any
counter value and overflow flag mismatch issues.

Signed-off-by: Magnus Damm <damm@igel.co.jp>
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
  • Loading branch information
Magnus Damm authored and Paul Mundt committed Apr 28, 2009
1 parent c2e0090 commit 5b644c7
Showing 1 changed file with 9 additions and 4 deletions.
13 changes: 9 additions & 4 deletions drivers/clocksource/sh_cmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,16 +111,21 @@ static unsigned long sh_cmt_get_counter(struct sh_cmt_priv *p,
int *has_wrapped)
{
unsigned long v1, v2, v3;
int o1, o2;

o1 = sh_cmt_read(p, CMCSR) & p->overflow_bit;

/* Make sure the timer value is stable. Stolen from acpi_pm.c */
do {
o2 = o1;
v1 = sh_cmt_read(p, CMCNT);
v2 = sh_cmt_read(p, CMCNT);
v3 = sh_cmt_read(p, CMCNT);
} while (unlikely((v1 > v2 && v1 < v3) || (v2 > v3 && v2 < v1)
|| (v3 > v1 && v3 < v2)));
o1 = sh_cmt_read(p, CMCSR) & p->overflow_bit;
} while (unlikely((o1 != o2) || (v1 > v2 && v1 < v3)
|| (v2 > v3 && v2 < v1) || (v3 > v1 && v3 < v2)));

*has_wrapped = sh_cmt_read(p, CMCSR) & p->overflow_bit;
*has_wrapped = o1;
return v2;
}

Expand Down Expand Up @@ -394,7 +399,7 @@ static cycle_t sh_cmt_clocksource_read(struct clocksource *cs)
raw = sh_cmt_get_counter(p, &has_wrapped);

if (unlikely(has_wrapped))
raw = p->match_value;
raw += p->match_value;
spin_unlock_irqrestore(&p->lock, flags);

return value + raw;
Expand Down

0 comments on commit 5b644c7

Please sign in to comment.