summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDietmar Eggemann <dietmar.eggemann@arm.com>2012-03-15 12:09:41 +0000
committerDave Martin <dave.martin@linaro.org>2012-04-19 11:18:43 +0100
commit2b011732345db02b80958848fc0f81b4300e4bb4 (patch)
tree6639364d97612e302a251e4d2bdc4f5c97e63091
parentc8f957411e0f92dd509c750801181b53c2191131 (diff)
Hotplug: Add a cpu mask argument to event functions.
To be able to cluster switch with cpus in hotplug, the event mechanism must be able to inform only cpus which are online when the cluster switch occurs. Thus the event functions need the online cpu mask as an argument. Signed-off-by: Dietmar Eggemann <dietmar.eggemann@arm.com>
-rw-r--r--big-little/include/events.h5
-rw-r--r--big-little/lib/virt_events.c54
2 files changed, 34 insertions, 25 deletions
diff --git a/big-little/include/events.h b/big-little/include/events.h
index 629404f..abebaa9 100644
--- a/big-little/include/events.h
+++ b/big-little/include/events.h
@@ -68,11 +68,12 @@
#define FLUSH_L2 2
#define SETUP_RST 3
+
extern void set_event(unsigned, unsigned);
-extern void set_events(unsigned);
+extern void set_events(unsigned, unsigned);
extern unsigned get_event(unsigned, unsigned);
extern void reset_event(unsigned, unsigned);
extern void wait_for_event(unsigned, unsigned);
-extern void wait_for_events(unsigned);
+extern void wait_for_events(unsigned, unsigned);
#endif /* __EVENTS_H__ */
diff --git a/big-little/lib/virt_events.c b/big-little/lib/virt_events.c
index 33e9d3b..ec5c468 100644
--- a/big-little/lib/virt_events.c
+++ b/big-little/lib/virt_events.c
@@ -66,6 +66,15 @@ void wait_for_event(unsigned event_id, unsigned cpu_id)
return;
}
+static unsigned count_set_bits(unsigned mask)
+{
+ unsigned i;
+ for (i = 0; mask; i++)
+ mask &= mask - 1;
+
+ return i;
+}
+
/*
* Wait for events from each core. Its a little trickier than
* waiting for a single event. The event register as per the
@@ -74,26 +83,29 @@ void wait_for_event(unsigned event_id, unsigned cpu_id)
* the time we enter wfe() then each flag variable should be
* checked.
*/
-void wait_for_events(unsigned event_id)
+void wait_for_events(unsigned event_id, unsigned cpu_mask)
{
- unsigned ctr, event_count = 0, num_cpus = 0;
+ unsigned mask = 0, event_count = 0, cpu_count = 0;
+ int cpu_id = 0;
- if (switcher) {
- num_cpus = num_secondaries() + 1;
- } else {
- num_cpus = CLUSTER_CPU_COUNT(host_cluster)
- + CLUSTER_CPU_COUNT(!host_cluster);
- }
+ cpu_count = count_set_bits(cpu_mask);
do {
- for (ctr = 0; ctr < num_cpus; ctr++) {
- if (TRUE == get_event(event_id, ctr)) {
+ for (mask = cpu_mask; mask;) {
+
+ /* Find the first set msb */
+ cpu_id = bitindex(mask);
+
+ /* Unset the recorded bit */
+ mask &= ~(1 << cpu_id);
+
+ if (TRUE == get_event(event_id, cpu_id)) {
event_count++;
- reset_event(event_id, ctr);
+ reset_event(event_id, cpu_id);
}
}
- if (event_count != num_cpus)
+ if (event_count != cpu_count)
wfe();
else
break;
@@ -102,19 +114,15 @@ void wait_for_events(unsigned event_id)
return;
}
-void set_events(unsigned event_id)
+void set_events(unsigned event_id, unsigned cpu_mask)
{
- unsigned ctr, num_cpus = 0;
+ unsigned cpu_id = 0;
- if (switcher) {
- num_cpus = num_secondaries() + 1;
- } else {
- num_cpus = CLUSTER_CPU_COUNT(host_cluster)
- + CLUSTER_CPU_COUNT(!host_cluster);
- }
+ while (cpu_mask) {
+ cpu_id = bitindex(cpu_mask);
+ set_event(event_id, cpu_id);
+ cpu_mask &= ~(1 << cpu_id);
+ };
- for (ctr = 0; ctr < num_cpus; ctr++) {
- set_event(event_id, ctr);
- }
return;
}