diff options
| author | Magnus Damm <damm@opensource.se> | 2010-08-04 00:31:38 -0400 |
|---|---|---|
| committer | Paul Mundt <lethal@linux-sh.org> | 2010-08-04 03:01:24 -0400 |
| commit | 43809473b9d5fa9f82bf64ddeb3c21fe1140ef0e (patch) | |
| tree | 9869cb6b077a8e2096964b26984301a62d9756cb /drivers/clocksource | |
| parent | 7b42176a2969bc913cd2949e7edd935466745b11 (diff) | |
clocksource: sh_cmt: One-off clockevent fix V2
Fix a one-off error in the CMT driver V2. The match register
should be programmed with the period minus one.
Many thanks to Eiraku-san for tracking down this issue.
Signed-off-by: Magnus Damm <damm@opensource.se>
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'drivers/clocksource')
| -rw-r--r-- | drivers/clocksource/sh_cmt.c | 10 |
1 files changed, 5 insertions, 5 deletions
diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c index 717305d30444..ed8e07b97e27 100644 --- a/drivers/clocksource/sh_cmt.c +++ b/drivers/clocksource/sh_cmt.c | |||
| @@ -308,7 +308,7 @@ static irqreturn_t sh_cmt_interrupt(int irq, void *dev_id) | |||
| 308 | * isr before we end up here. | 308 | * isr before we end up here. |
| 309 | */ | 309 | */ |
| 310 | if (p->flags & FLAG_CLOCKSOURCE) | 310 | if (p->flags & FLAG_CLOCKSOURCE) |
| 311 | p->total_cycles += p->match_value; | 311 | p->total_cycles += p->match_value + 1; |
| 312 | 312 | ||
| 313 | if (!(p->flags & FLAG_REPROGRAM)) | 313 | if (!(p->flags & FLAG_REPROGRAM)) |
| 314 | p->next_match_value = p->max_match_value; | 314 | p->next_match_value = p->max_match_value; |
| @@ -403,7 +403,7 @@ static cycle_t sh_cmt_clocksource_read(struct clocksource *cs) | |||
| 403 | raw = sh_cmt_get_counter(p, &has_wrapped); | 403 | raw = sh_cmt_get_counter(p, &has_wrapped); |
| 404 | 404 | ||
| 405 | if (unlikely(has_wrapped)) | 405 | if (unlikely(has_wrapped)) |
| 406 | raw += p->match_value; | 406 | raw += p->match_value + 1; |
| 407 | spin_unlock_irqrestore(&p->lock, flags); | 407 | spin_unlock_irqrestore(&p->lock, flags); |
| 408 | 408 | ||
| 409 | return value + raw; | 409 | return value + raw; |
| @@ -478,7 +478,7 @@ static void sh_cmt_clock_event_start(struct sh_cmt_priv *p, int periodic) | |||
| 478 | ced->min_delta_ns = clockevent_delta2ns(0x1f, ced); | 478 | ced->min_delta_ns = clockevent_delta2ns(0x1f, ced); |
| 479 | 479 | ||
| 480 | if (periodic) | 480 | if (periodic) |
| 481 | sh_cmt_set_next(p, (p->rate + HZ/2) / HZ); | 481 | sh_cmt_set_next(p, ((p->rate + HZ/2) / HZ) - 1); |
| 482 | else | 482 | else |
| 483 | sh_cmt_set_next(p, p->max_match_value); | 483 | sh_cmt_set_next(p, p->max_match_value); |
| 484 | } | 484 | } |
| @@ -523,9 +523,9 @@ static int sh_cmt_clock_event_next(unsigned long delta, | |||
| 523 | 523 | ||
| 524 | BUG_ON(ced->mode != CLOCK_EVT_MODE_ONESHOT); | 524 | BUG_ON(ced->mode != CLOCK_EVT_MODE_ONESHOT); |
| 525 | if (likely(p->flags & FLAG_IRQCONTEXT)) | 525 | if (likely(p->flags & FLAG_IRQCONTEXT)) |
| 526 | p->next_match_value = delta; | 526 | p->next_match_value = delta - 1; |
| 527 | else | 527 | else |
| 528 | sh_cmt_set_next(p, delta); | 528 | sh_cmt_set_next(p, delta - 1); |
| 529 | 529 | ||
| 530 | return 0; | 530 | return 0; |
| 531 | } | 531 | } |
