From 43809473b9d5fa9f82bf64ddeb3c21fe1140ef0e Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Wed, 4 Aug 2010 04:31:38 +0000 Subject: 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 Signed-off-by: Paul Mundt --- drivers/clocksource/sh_cmt.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers/clocksource/sh_cmt.c') 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) * isr before we end up here. */ if (p->flags & FLAG_CLOCKSOURCE) - p->total_cycles += p->match_value; + p->total_cycles += p->match_value + 1; if (!(p->flags & FLAG_REPROGRAM)) p->next_match_value = p->max_match_value; @@ -403,7 +403,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 + 1; spin_unlock_irqrestore(&p->lock, flags); return value + raw; @@ -478,7 +478,7 @@ static void sh_cmt_clock_event_start(struct sh_cmt_priv *p, int periodic) ced->min_delta_ns = clockevent_delta2ns(0x1f, ced); if (periodic) - sh_cmt_set_next(p, (p->rate + HZ/2) / HZ); + sh_cmt_set_next(p, ((p->rate + HZ/2) / HZ) - 1); else sh_cmt_set_next(p, p->max_match_value); } @@ -523,9 +523,9 @@ static int sh_cmt_clock_event_next(unsigned long delta, BUG_ON(ced->mode != CLOCK_EVT_MODE_ONESHOT); if (likely(p->flags & FLAG_IRQCONTEXT)) - p->next_match_value = delta; + p->next_match_value = delta - 1; else - sh_cmt_set_next(p, delta); + sh_cmt_set_next(p, delta - 1); return 0; } -- cgit v1.2.3 From 38409d726bc6413d39f082f60bc803f52d8b5849 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Mon, 2 Aug 2010 09:24:05 +0000 Subject: clocksource: sh_cmt: Rate calculation fix Fix the rate calculation in the CMT driver. Without this fix the clocksource runs way too fast and we get a divide-by-zero error. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- drivers/clocksource/sh_cmt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/clocksource/sh_cmt.c') diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c index ed8e07b97e27..a44611652282 100644 --- a/drivers/clocksource/sh_cmt.c +++ b/drivers/clocksource/sh_cmt.c @@ -445,7 +445,7 @@ static int sh_cmt_register_clocksource(struct sh_cmt_priv *p, /* clk_get_rate() needs an enabled clock */ clk_enable(p->clk); - p->rate = clk_get_rate(p->clk) / (p->width == 16) ? 512 : 8; + p->rate = clk_get_rate(p->clk) / ((p->width == 16) ? 512 : 8); clk_disable(p->clk); /* TODO: calculate good shift from rate and counter bit width */ -- cgit v1.2.3