diff options
author | Achin Gupta <achin.gupta@arm.com> | 2013-12-05 15:10:48 +0000 |
---|---|---|
committer | Dan Handley <dan.handley@arm.com> | 2014-01-20 18:45:04 +0000 |
commit | a45e39738bcfb8ad49f581c92c747e159aa23892 (patch) | |
tree | 9b52dcc3be7d54ab7ed72ec4c194d6fd7fc2f0c4 /common/psci/psci_afflvl_suspend.c | |
parent | a59caa4cbd03c394e7a5bf098ddd9db457b35aae (diff) |
psci: preserve target affinity level during suspend
This patch adds support to save and restore the target affinity level
specified during a cpu_suspend psci call. This ensures that we
traverse only through the affinity levels that we originally intended
to after resuming from suspend.
Change-Id: I0900ae49a50b496da137cfec8f158da0397ec56c
Diffstat (limited to 'common/psci/psci_afflvl_suspend.c')
-rw-r--r-- | common/psci/psci_afflvl_suspend.c | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/common/psci/psci_afflvl_suspend.c b/common/psci/psci_afflvl_suspend.c index 6fb60f4a..b2dc732f 100644 --- a/common/psci/psci_afflvl_suspend.c +++ b/common/psci/psci_afflvl_suspend.c @@ -44,6 +44,37 @@ typedef int (*afflvl_suspend_handler)(unsigned long, unsigned int); /******************************************************************************* + * This function sets the affinity level till which the current cpu is being + * powered down to during a cpu_suspend call + ******************************************************************************/ +void psci_set_suspend_afflvl(aff_map_node *node, int afflvl) +{ + /* + * Check that nobody else is calling this function on our behalf & + * this information is being set only in the cpu node + */ + assert(node->mpidr == (read_mpidr() & MPIDR_AFFINITY_MASK)); + assert(node->level == MPIDR_AFFLVL0); + + /* + * Store the affinity level we are powering down to in our context. + * The cache flush in the suspend code will ensure that this info + * is available immediately upon resuming. + */ + psci_suspend_context[node->data].suspend_level = afflvl; +} + +/******************************************************************************* + * This function gets the affinity level till which the current cpu was powered + * down during a cpu_suspend call. + ******************************************************************************/ +int psci_get_suspend_afflvl(aff_map_node *node) +{ + /* Return the target affinity level */ + return psci_suspend_context[node->data].suspend_level; +} + +/******************************************************************************* * The next three functions implement a handler for each supported affinity * level which is called when that affinity level is about to be suspended. ******************************************************************************/ @@ -336,6 +367,9 @@ int psci_afflvl_suspend(unsigned long mpidr, end_afflvl, PSCI_STATE_SUSPEND); + /* Save the affinity level till which this cpu can be powered down */ + psci_set_suspend_afflvl(mpidr_nodes[MPIDR_AFFLVL0], end_afflvl); + /* Perform generic, architecture and platform specific handling */ rc = psci_call_suspend_handlers(mpidr_nodes, start_afflvl, |