summaryrefslogtreecommitdiff
path: root/services/std_svc
diff options
context:
space:
mode:
authorSoby Mathew <soby.mathew@arm.com>2014-09-30 11:19:51 +0100
committerSoby Mathew <soby.mathew@arm.com>2015-01-23 15:14:36 +0000
commit31244d74b350d49cfba6ad46d90dad2d5f2f364c (patch)
treed7f1fd7609927e15b4e4da50665355d04fc7a99a /services/std_svc
parent78879b9a5e5c31b80830046007c9955a6fcf0dd1 (diff)
Save 'power_state' early in PSCI CPU_SUSPEND call
This patch adds support to save the "power state" parameter before the affinity level specific handlers are called in a CPU_SUSPEND call. This avoids the need to pass the power_state as a parameter to the handlers and Secure Payload Dispatcher (SPD) suspend spd_pm_ops. The power_state arguments in the spd_pm_ops operations are now reserved and must not be used. The SPD can query the relevant power_state fields by using the psci_get_suspend_afflvl() & psci_get_suspend_stateid() APIs. NOTE: THIS PATCH WILL BREAK THE SPD_PM_OPS INTERFACE. HENCE THE SECURE PAYLOAD DISPATCHERS WILL NEED TO BE REWORKED TO USE THE NEW INTERFACE. Change-Id: I1293d7dc8cf29cfa6a086a009eee41bcbf2f238e
Diffstat (limited to 'services/std_svc')
-rw-r--r--services/std_svc/psci/psci_afflvl_suspend.c28
-rw-r--r--services/std_svc/psci/psci_main.c7
-rw-r--r--services/std_svc/psci/psci_private.h1
3 files changed, 14 insertions, 22 deletions
diff --git a/services/std_svc/psci/psci_afflvl_suspend.c b/services/std_svc/psci/psci_afflvl_suspend.c
index 4988e677..942e9a12 100644
--- a/services/std_svc/psci/psci_afflvl_suspend.c
+++ b/services/std_svc/psci/psci_afflvl_suspend.c
@@ -40,8 +40,7 @@
#include <stddef.h>
#include "psci_private.h"
-typedef int (*afflvl_suspend_handler_t)(aff_map_node_t *node,
- unsigned int power_state);
+typedef int (*afflvl_suspend_handler_t)(aff_map_node_t *node);
/*******************************************************************************
* This function saves the power state parameter passed in the current PSCI
@@ -103,17 +102,13 @@ int psci_get_suspend_stateid_by_mpidr(unsigned long mpidr)
* The next three functions implement a handler for each supported affinity
* level which is called when that affinity level is about to be suspended.
******************************************************************************/
-static int psci_afflvl0_suspend(aff_map_node_t *cpu_node,
- unsigned int power_state)
+static int psci_afflvl0_suspend(aff_map_node_t *cpu_node)
{
unsigned long psci_entrypoint;
/* Sanity check to safeguard against data corruption */
assert(cpu_node->level == MPIDR_AFFLVL0);
- /* Save PSCI power state parameter for the core in suspend context */
- psci_set_suspend_power_state(power_state);
-
/*
* Generic management: Allow the Secure world to suspend itself
*/
@@ -124,8 +119,7 @@ static int psci_afflvl0_suspend(aff_map_node_t *cpu_node,
* error, it's expected to assert within
*/
if (psci_spd_pm && psci_spd_pm->svc_suspend)
- psci_spd_pm->svc_suspend(power_state);
-
+ psci_spd_pm->svc_suspend(0);
/* Set the secure world (EL3) re-entry point after BL1 */
psci_entrypoint = (unsigned long) psci_aff_suspend_finish_entry;
@@ -150,8 +144,7 @@ static int psci_afflvl0_suspend(aff_map_node_t *cpu_node,
psci_get_phys_state(cpu_node));
}
-static int psci_afflvl1_suspend(aff_map_node_t *cluster_node,
- unsigned int power_state)
+static int psci_afflvl1_suspend(aff_map_node_t *cluster_node)
{
unsigned int plat_state;
unsigned long psci_entrypoint;
@@ -184,8 +177,7 @@ static int psci_afflvl1_suspend(aff_map_node_t *cluster_node,
}
-static int psci_afflvl2_suspend(aff_map_node_t *system_node,
- unsigned int power_state)
+static int psci_afflvl2_suspend(aff_map_node_t *system_node)
{
unsigned int plat_state;
unsigned long psci_entrypoint;
@@ -238,8 +230,7 @@ static const afflvl_suspend_handler_t psci_afflvl_suspend_handlers[] = {
******************************************************************************/
static int psci_call_suspend_handlers(aff_map_node_t *mpidr_nodes[],
int start_afflvl,
- int end_afflvl,
- unsigned int power_state)
+ int end_afflvl)
{
int rc = PSCI_E_INVALID_PARAMS, level;
aff_map_node_t *node;
@@ -254,8 +245,7 @@ static int psci_call_suspend_handlers(aff_map_node_t *mpidr_nodes[],
* of restoring what we might have torn down at
* lower affinity levels.
*/
- rc = psci_afflvl_suspend_handlers[level](node,
- power_state);
+ rc = psci_afflvl_suspend_handlers[level](node);
if (rc != PSCI_E_SUCCESS)
break;
}
@@ -283,7 +273,6 @@ static int psci_call_suspend_handlers(aff_map_node_t *mpidr_nodes[],
* first.
******************************************************************************/
int psci_afflvl_suspend(entry_point_info_t *ep,
- unsigned int power_state,
int start_afflvl,
int end_afflvl)
{
@@ -339,8 +328,7 @@ int psci_afflvl_suspend(entry_point_info_t *ep,
/* Perform generic, architecture and platform specific handling */
rc = psci_call_suspend_handlers(mpidr_nodes,
start_afflvl,
- end_afflvl,
- power_state);
+ end_afflvl);
/*
* Invalidate the entry for the highest affinity level stashed earlier.
diff --git a/services/std_svc/psci/psci_main.c b/services/std_svc/psci/psci_main.c
index 7fce5faf..506f5920 100644
--- a/services/std_svc/psci/psci_main.c
+++ b/services/std_svc/psci/psci_main.c
@@ -125,18 +125,23 @@ int psci_cpu_suspend(unsigned int power_state,
if (rc != PSCI_E_SUCCESS)
return rc;
+ /* Save PSCI power state parameter for the core in suspend context */
+ psci_set_suspend_power_state(power_state);
+
/*
* Do what is needed to enter the power down state. Upon success,
* enter the final wfi which will power down this cpu else return
* an error.
*/
rc = psci_afflvl_suspend(&ep,
- power_state,
MPIDR_AFFLVL0,
target_afflvl);
if (rc == PSCI_E_SUCCESS)
psci_power_down_wfi();
assert(rc == PSCI_E_INVALID_PARAMS);
+
+ /* Reset PSCI power state parameter for the core. */
+ psci_set_suspend_power_state(PSCI_INVALID_DATA);
return rc;
}
diff --git a/services/std_svc/psci/psci_private.h b/services/std_svc/psci/psci_private.h
index 3a4ee3c8..98d5d92a 100644
--- a/services/std_svc/psci/psci_private.h
+++ b/services/std_svc/psci/psci_private.h
@@ -139,7 +139,6 @@ int psci_afflvl_off(int, int);
/* Private exported functions from psci_affinity_suspend.c */
int psci_afflvl_suspend(entry_point_info_t *ep,
- unsigned int power_state,
int start_afflvl,
int end_afflvl);