blob: aa1ee33c3d50ce49e2acb10914f82dd522262c7b [file] [log] [blame]
From e8cb9e16b76cfe3cb8062b0451d39c940f2f2150 Mon Sep 17 00:00:00 2001
From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
Date: Wed, 19 Feb 2014 16:19:44 +0100
Subject: clocksource: sh_cmt: Set cpumask to cpu_possible_mask
The CMT is a global timer not restricted to a single CPU. It has a lower
rating than the TMU or ARM architected timer, but is still useful on
systems where the other timers are stopped during CPU sleep.
When multiple timers are available the timers core selects which timer
to use based on timer ratings.
On SMP systems where timer broadcasting is required, one dummy timer is
instantiated per CPU with a rating of 100. On those systems the CMT
timer has a rating of 80, which makes the dummy timer selected by
default on all CPUs. The CMT is then available, and will be used as a
broadcast timer.
On UP systems no dummy timer is instantiated. The CMT timer has a rating
of 125 on those systems and is used directly as a clock event device for
CPU0 without broadcasting.
The CMT rating shouldn't depend on whether we boot a UP or SMP system.
We can't raise the CMT rating to 125 on SMP systems. This would select
CMT as the clock event device for CPU0 as its rating is higher than the
dummy timer rating, and would leave the system without a broadcast
timer. We could instead lower the rating to 80 on all systems, but that
wouldn't reflect reality as ratings between 1 and 99 are documented as
"unfit for real use".
We should raise the rating above 99 and still have the CMT selected as a
broadcast timer. This can be done by changing the cpumask from
cpumask_of(0) to cpu_possible_mask. In that case the timer selection
logic will prefer the previously probed and already selected dummy timer
for all CPUs based on the fact that already selected per-cpu timers are
preferred over new global timers, regardless of their respective
ratings. This also better reflects reality, as the CMT is not tied to
the boot CPU.
Ideally the timer selection logic should realize that the CMT needs to
be used as a broadcast timer on SMP systems as no other broadcast timer
is available, regardless of the cpumask and rating.
Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
(cherry picked from commit f1ebe1e47e1979393a8492bfe751176908a830ae)
Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
---
drivers/clocksource/sh_cmt.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
index ce00baaf8bd2..926abe288126 100644
--- a/drivers/clocksource/sh_cmt.c
+++ b/drivers/clocksource/sh_cmt.c
@@ -776,7 +776,7 @@ static void sh_cmt_register_clockevent(struct sh_cmt_channel *ch,
ced->features = CLOCK_EVT_FEAT_PERIODIC;
ced->features |= CLOCK_EVT_FEAT_ONESHOT;
ced->rating = rating;
- ced->cpumask = cpumask_of(0);
+ ced->cpumask = cpu_possible_mask;
ced->set_next_event = sh_cmt_clock_event_next;
ced->set_mode = sh_cmt_clock_event_mode;
ced->suspend = sh_cmt_clock_event_suspend;
--
2.1.2