summaryrefslogtreecommitdiff
path: root/services/std_svc/psci/psci_afflvl_off.c
diff options
context:
space:
mode:
Diffstat (limited to 'services/std_svc/psci/psci_afflvl_off.c')
-rw-r--r--services/std_svc/psci/psci_afflvl_off.c51
1 files changed, 30 insertions, 21 deletions
diff --git a/services/std_svc/psci/psci_afflvl_off.c b/services/std_svc/psci/psci_afflvl_off.c
index 7e05789..f0f4234 100644
--- a/services/std_svc/psci/psci_afflvl_off.c
+++ b/services/std_svc/psci/psci_afflvl_off.c
@@ -62,12 +62,6 @@ static int psci_afflvl0_off(aff_map_node_t *cpu_node)
return rc;
}
- /*
- * Arch. management. Perform the necessary steps to flush all
- * cpu caches.
- */
- psci_do_pwrdown_cache_maintenance(MPIDR_AFFLVL0);
-
if (!psci_plat_pm_ops->affinst_off)
return PSCI_E_SUCCESS;
@@ -75,22 +69,25 @@ static int psci_afflvl0_off(aff_map_node_t *cpu_node)
* Plat. management: Perform platform specific actions to turn this
* cpu off e.g. exit cpu coherency, program the power controller etc.
*/
- return psci_plat_pm_ops->affinst_off(read_mpidr_el1(),
+ rc = psci_plat_pm_ops->affinst_off(read_mpidr_el1(),
cpu_node->level,
psci_get_phys_state(cpu_node));
+ /*
+ * Arch. management. Perform the necessary steps to flush all
+ * cpu caches.
+ */
+ psci_do_pwrdown_cache_maintenance(MPIDR_AFFLVL0);
+
+ return rc;
}
static int psci_afflvl1_off(aff_map_node_t *cluster_node)
{
+ int rc;
+
/* Sanity check the cluster level */
assert(cluster_node->level == MPIDR_AFFLVL1);
- /*
- * Arch. Management. Flush all levels of caches to PoC if
- * the cluster is to be shutdown.
- */
- psci_do_pwrdown_cache_maintenance(MPIDR_AFFLVL1);
-
if (!psci_plat_pm_ops->affinst_off)
return PSCI_E_SUCCESS;
@@ -99,13 +96,23 @@ static int psci_afflvl1_off(aff_map_node_t *cluster_node)
* specific bookeeping e.g. turn off interconnect coherency,
* program the power controller etc.
*/
- return psci_plat_pm_ops->affinst_off(read_mpidr_el1(),
+ rc = psci_plat_pm_ops->affinst_off(read_mpidr_el1(),
cluster_node->level,
psci_get_phys_state(cluster_node));
+
+ /*
+ * Arch. Management. Flush all levels of caches to PoC if
+ * the cluster is to be shutdown.
+ */
+ psci_do_pwrdown_cache_maintenance(MPIDR_AFFLVL1);
+
+ return rc;
}
static int psci_afflvl2_off(aff_map_node_t *system_node)
{
+ int rc;
+
/* Cannot go beyond this level */
assert(system_node->level == MPIDR_AFFLVL2);
@@ -114,12 +121,6 @@ static int psci_afflvl2_off(aff_map_node_t *system_node)
* action needs to be taken
*/
- /*
- * Arch. Management. Flush all levels of caches to PoC if
- * the system is to be shutdown.
- */
- psci_do_pwrdown_cache_maintenance(MPIDR_AFFLVL2);
-
if (!psci_plat_pm_ops->affinst_off)
return PSCI_E_SUCCESS;
@@ -127,9 +128,17 @@ static int psci_afflvl2_off(aff_map_node_t *system_node)
* Plat. Management : Allow the platform to do its bookeeping
* at this affinity level
*/
- return psci_plat_pm_ops->affinst_off(read_mpidr_el1(),
+ rc = psci_plat_pm_ops->affinst_off(read_mpidr_el1(),
system_node->level,
psci_get_phys_state(system_node));
+
+ /*
+ * Arch. Management. Flush all levels of caches to PoC if
+ * the system is to be shutdown.
+ */
+ psci_do_pwrdown_cache_maintenance(MPIDR_AFFLVL2);
+
+ return rc;
}
static const afflvl_off_handler_t psci_afflvl_off_handlers[] = {