diff options
Diffstat (limited to 'services/std_svc/psci/psci_afflvl_suspend.c')
-rw-r--r-- | services/std_svc/psci/psci_afflvl_suspend.c | 76 |
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 |