summaryrefslogtreecommitdiff
path: root/services/std_svc/psci/psci_afflvl_suspend.c
diff options
context:
space:
mode:
Diffstat (limited to 'services/std_svc/psci/psci_afflvl_suspend.c')
-rw-r--r--services/std_svc/psci/psci_afflvl_suspend.c76
1 files changed, 30 insertions, 46 deletions
diff --git a/services/std_svc/psci/psci_afflvl_suspend.c b/services/std_svc/psci/psci_afflvl_suspend.c
index 70f90a1..a123dc3 100644
--- a/services/std_svc/psci/psci_afflvl_suspend.c
+++ b/services/std_svc/psci/psci_afflvl_suspend.c
@@ -34,6 +34,7 @@
#include <arch_helpers.h>
#include <context.h>
#include <context_mgmt.h>
+#include <cpu_data.h>
#include <platform.h>
#include <runtime_svc.h>
#include <stddef.h>
@@ -45,76 +46,59 @@ typedef int (*afflvl_suspend_handler_t)(aff_map_node_t *,
unsigned int);
/*******************************************************************************
- * This function sets the power state of the current cpu while
- * powering down during a cpu_suspend call
+ * This function saves the power state parameter passed in the current PSCI
+ * cpu_suspend call in the per-cpu data array.
******************************************************************************/
-void psci_set_suspend_power_state(aff_map_node_t *node, unsigned int power_state)
+void psci_set_suspend_power_state(unsigned int power_state)
{
- /*
- * 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);
-
- /*
- * Save PSCI power state parameter for the core in suspend context.
- * The node is in always-coherent RAM so it does not need to be flushed
- */
- node->power_state = power_state;
+ set_cpu_data(psci_svc_cpu_data.power_state, power_state);
+ flush_cpu_data(psci_svc_cpu_data.power_state);
}
/*******************************************************************************
- * This function gets the affinity level till which a cpu is powered down
- * during a cpu_suspend call. Returns PSCI_INVALID_DATA if the
- * power state saved for the node is invalid
+ * This function gets the affinity level till which the current cpu could be
+ * powered down during a cpu_suspend call. Returns PSCI_INVALID_DATA if the
+ * power state is invalid.
******************************************************************************/
-int psci_get_suspend_afflvl(unsigned long mpidr)
+int psci_get_suspend_afflvl()
{
- aff_map_node_t *node;
+ unsigned int power_state;
- node = psci_get_aff_map_node(mpidr & MPIDR_AFFINITY_MASK,
- MPIDR_AFFLVL0);
- assert(node);
+ power_state = get_cpu_data(psci_svc_cpu_data.power_state);
- return psci_get_aff_map_node_suspend_afflvl(node);
+ return ((power_state == PSCI_INVALID_DATA) ?
+ power_state : psci_get_pstate_afflvl(power_state));
}
-
/*******************************************************************************
- * This function gets the affinity level till which the current cpu was powered
- * down during a cpu_suspend call. Returns PSCI_INVALID_DATA if the
- * power state saved for the node is invalid
+ * This function gets the state id of the current cpu from the power state
+ * parameter saved in the per-cpu data array. Returns PSCI_INVALID_DATA if the
+ * power state saved is invalid.
******************************************************************************/
-int psci_get_aff_map_node_suspend_afflvl(aff_map_node_t *node)
+int psci_get_suspend_stateid()
{
unsigned int power_state;
- assert(node->level == MPIDR_AFFLVL0);
+ power_state = get_cpu_data(psci_svc_cpu_data.power_state);
- power_state = node->power_state;
return ((power_state == PSCI_INVALID_DATA) ?
- power_state : psci_get_pstate_afflvl(power_state));
+ power_state : psci_get_pstate_id(power_state));
}
/*******************************************************************************
- * This function gets the state id of a cpu stored in suspend context
- * while powering down during a cpu_suspend call. Returns 0xFFFFFFFF
- * if the power state saved for the node is invalid
+ * This function gets the state id of the cpu specified by the 'mpidr' parameter
+ * from the power state parameter saved in the per-cpu data array. Returns
+ * PSCI_INVALID_DATA if the power state saved is invalid.
******************************************************************************/
-int psci_get_suspend_stateid(unsigned long mpidr)
+int psci_get_suspend_stateid_by_mpidr(unsigned long mpidr)
{
- aff_map_node_t *node;
unsigned int power_state;
- node = psci_get_aff_map_node(mpidr & MPIDR_AFFINITY_MASK,
- MPIDR_AFFLVL0);
- assert(node);
- assert(node->level == MPIDR_AFFLVL0);
+ power_state = get_cpu_data_by_mpidr(mpidr,
+ psci_svc_cpu_data.power_state);
- power_state = node->power_state;
return ((power_state == PSCI_INVALID_DATA) ?
- power_state : psci_get_pstate_id(power_state));
+ power_state : psci_get_pstate_id(power_state));
}
/*******************************************************************************
@@ -136,7 +120,7 @@ static int psci_afflvl0_suspend(aff_map_node_t *cpu_node,
assert(cpu_node->level == MPIDR_AFFLVL0);
/* Save PSCI power state parameter for the core in suspend context */
- psci_set_suspend_power_state(cpu_node, power_state);
+ psci_set_suspend_power_state(power_state);
/*
* Generic management: Store the re-entry information for the non-secure
@@ -451,13 +435,13 @@ static unsigned int psci_afflvl0_suspend_finish(aff_map_node_t *cpu_node)
* error, it's expected to assert within
*/
if (psci_spd_pm && psci_spd_pm->svc_suspend) {
- suspend_level = psci_get_aff_map_node_suspend_afflvl(cpu_node);
+ suspend_level = psci_get_suspend_afflvl();
assert (suspend_level != PSCI_INVALID_DATA);
psci_spd_pm->svc_suspend_finish(suspend_level);
}
/* Invalidate the suspend context for the node */
- psci_set_suspend_power_state(cpu_node, PSCI_INVALID_DATA);
+ psci_set_suspend_power_state(PSCI_INVALID_DATA);
/*
* Generic management: Now we just need to retrieve the