summaryrefslogtreecommitdiff
path: root/lib/power_management/hotplug
diff options
context:
space:
mode:
authorSandrine Bailleux <sandrine.bailleux@arm.com>2015-03-05 14:06:35 +0000
committerSandrine Bailleux <sandrine.bailleux@arm.com>2015-03-12 12:52:19 +0000
commitc6997d97a64b892ef881305ebb30c7634f27d8a2 (patch)
treea109fee9bbf817ff9061d2ff42c344e264306ff8 /lib/power_management/hotplug
parent5afb9079c79cb79f9b8bd4c098c823fc3df20694 (diff)
Reset 'cpu_is_online' event when a CPU powers itself off
The 'cpu_is_online' event might be pending when a CPU powers itself off. This can happen when the CPU has been previously powered up but no other CPU has taken the event advertising it. We can't leave the event pending because this might trick other CPUs into thinking the CPU is still on. This patch resets the event to avoid this situation. Change-Id: I77acb28f6c57934230de71f04e0be4ff55a3c78d
Diffstat (limited to 'lib/power_management/hotplug')
-rw-r--r--lib/power_management/hotplug/hotplug.c17
1 files changed, 16 insertions, 1 deletions
diff --git a/lib/power_management/hotplug/hotplug.c b/lib/power_management/hotplug/hotplug.c
index 445489c..fa31afb 100644
--- a/lib/power_management/hotplug/hotplug.c
+++ b/lib/power_management/hotplug/hotplug.c
@@ -123,8 +123,16 @@ void tftf_set_cpu_offline(void)
unsigned int core_pos = platform_get_core_pos(mpid);
spin_lock(&cpus_status_map[core_pos].lock);
+
assert(tftf_is_cpu_online(mpid));
cpus_status_map[core_pos].state = TFTF_AFFINITY_STATE_OFF;
+ /*
+ * Reset the event in case it would be pending.
+ * This can happen when the CPU has been previously powered up
+ * but no other CPU has taken the event advertising it.
+ */
+ tftf_init_event(&cpu_is_online[core_pos]);
+
spin_unlock(&cpus_status_map[core_pos].lock);
}
@@ -144,6 +152,7 @@ int32_t tftf_cpu_on(uint64_t target_cpu,
spin_lock(&cpus_status_map[core_pos].lock);
cpu_state = cpus_status_map[core_pos].state;
+
if (cpu_state == TFTF_AFFINITY_STATE_ON) {
spin_unlock(&cpus_status_map[core_pos].lock);
return PSCI_E_ALREADY_ON;
@@ -156,6 +165,13 @@ int32_t tftf_cpu_on(uint64_t target_cpu,
return PSCI_E_SUCCESS;
}
+ assert(cpu_state == TFTF_AFFINITY_STATE_OFF);
+ /*
+ * Ensure no event is pending. That would trick other CPUs into thinking
+ * the CPU is already powered on.
+ */
+ assert(cpu_is_online[core_pos].cnt == 0);
+
/*
* Populate the test entry point for this core.
* This is the address where the core will jump to once the framework
@@ -163,7 +179,6 @@ int32_t tftf_cpu_on(uint64_t target_cpu,
*/
test_entrypoint[core_pos] = entrypoint;
- assert(cpu_state == TFTF_AFFINITY_STATE_OFF);
do {
ret = tftf_psci_cpu_on(target_cpu,
(uint64_t) tftf_hotplug_entry,