diff --git a/include/bl31/services/psci.h b/include/bl31/services/psci.h index 88b2107..6c23f1b 100644 --- a/include/bl31/services/psci.h +++ b/include/bl31/services/psci.h @@ -189,8 +189,6 @@ * Function & Data prototypes ******************************************************************************/ unsigned int psci_version(void); -int __psci_cpu_suspend(unsigned int, unsigned long, unsigned long); -int __psci_cpu_off(void); int psci_affinity_info(unsigned long, unsigned int); int psci_migrate(unsigned int); unsigned int psci_migrate_info_type(void); diff --git a/services/std_svc/psci/psci_afflvl_off.c b/services/std_svc/psci/psci_afflvl_off.c index 231721e..7e05789 100644 --- a/services/std_svc/psci/psci_afflvl_off.c +++ b/services/std_svc/psci/psci_afflvl_off.c @@ -42,7 +42,6 @@ ******************************************************************************/ static int psci_afflvl0_off(aff_map_node_t *cpu_node) { - unsigned int plat_state; int rc; assert(cpu_node->level == MPIDR_AFFLVL0); @@ -69,61 +68,44 @@ */ psci_do_pwrdown_cache_maintenance(MPIDR_AFFLVL0); + if (!psci_plat_pm_ops->affinst_off) + return PSCI_E_SUCCESS; + /* * Plat. management: Perform platform specific actions to turn this * cpu off e.g. exit cpu coherency, program the power controller etc. */ - rc = PSCI_E_SUCCESS; - if (psci_plat_pm_ops->affinst_off) { - - /* Get the current physical state of this cpu */ - plat_state = psci_get_phys_state(cpu_node); - rc = psci_plat_pm_ops->affinst_off(read_mpidr_el1(), - cpu_node->level, - plat_state); - } - - return rc; + return psci_plat_pm_ops->affinst_off(read_mpidr_el1(), + cpu_node->level, + psci_get_phys_state(cpu_node)); } static int psci_afflvl1_off(aff_map_node_t *cluster_node) { - int rc = PSCI_E_SUCCESS; - unsigned int plat_state; - /* Sanity check the cluster level */ assert(cluster_node->level == MPIDR_AFFLVL1); /* - * Keep the physical state of this cluster handy to decide - * what action needs to be taken - */ - plat_state = 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); + if (!psci_plat_pm_ops->affinst_off) + return PSCI_E_SUCCESS; + /* * Plat. Management. Allow the platform to do its cluster * specific bookeeping e.g. turn off interconnect coherency, * program the power controller etc. */ - if (psci_plat_pm_ops->affinst_off) - rc = psci_plat_pm_ops->affinst_off(read_mpidr_el1(), - cluster_node->level, - plat_state); - - return rc; + return psci_plat_pm_ops->affinst_off(read_mpidr_el1(), + cluster_node->level, + psci_get_phys_state(cluster_node)); } static int psci_afflvl2_off(aff_map_node_t *system_node) { - int rc = PSCI_E_SUCCESS; - unsigned int plat_state; - /* Cannot go beyond this level */ assert(system_node->level == MPIDR_AFFLVL2); @@ -131,7 +113,6 @@ * Keep the physical state of the system handy to decide what * action needs to be taken */ - plat_state = psci_get_phys_state(system_node); /* * Arch. Management. Flush all levels of caches to PoC if @@ -139,15 +120,16 @@ */ psci_do_pwrdown_cache_maintenance(MPIDR_AFFLVL2); + if (!psci_plat_pm_ops->affinst_off) + return PSCI_E_SUCCESS; + /* * Plat. Management : Allow the platform to do its bookeeping * at this affinity level */ - if (psci_plat_pm_ops->affinst_off) - rc = psci_plat_pm_ops->affinst_off(read_mpidr_el1(), - system_node->level, - plat_state); - return rc; + return psci_plat_pm_ops->affinst_off(read_mpidr_el1(), + system_node->level, + psci_get_phys_state(system_node)); } static const afflvl_off_handler_t psci_afflvl_off_handlers[] = { @@ -161,7 +143,7 @@ * topology tree and calls the off handler for the corresponding affinity * levels ******************************************************************************/ -static int psci_call_off_handlers(mpidr_aff_map_nodes_t mpidr_nodes, +static int psci_call_off_handlers(aff_map_node_t *mpidr_nodes[], int start_afflvl, int end_afflvl) { diff --git a/services/std_svc/psci/psci_afflvl_on.c b/services/std_svc/psci/psci_afflvl_on.c index 10bc586..f1d30c9 100644 --- a/services/std_svc/psci/psci_afflvl_on.c +++ b/services/std_svc/psci/psci_afflvl_on.c @@ -75,7 +75,6 @@ unsigned long ns_entrypoint, unsigned long context_id) { - unsigned int plat_state; unsigned long psci_entrypoint; uint32_t ns_scr_el3 = read_scr_el3(); uint32_t ns_sctlr_el1 = read_sctlr_el1(); @@ -113,23 +112,19 @@ /* Set the secure world (EL3) re-entry point after BL1 */ psci_entrypoint = (unsigned long) psci_aff_on_finish_entry; + if (!psci_plat_pm_ops->affinst_on) + return PSCI_E_SUCCESS; + /* * Plat. management: Give the platform the current state * of the target cpu to allow it to perform the necessary * steps to power on. */ - if (psci_plat_pm_ops->affinst_on) { - - /* Get the current physical state of this cpu */ - plat_state = psci_get_phys_state(cpu_node); - rc = psci_plat_pm_ops->affinst_on(target_cpu, - psci_entrypoint, - ns_entrypoint, - cpu_node->level, - plat_state); - } - - return rc; + return psci_plat_pm_ops->affinst_on(target_cpu, + psci_entrypoint, + ns_entrypoint, + cpu_node->level, + psci_get_phys_state(cpu_node)); } /******************************************************************************* @@ -142,8 +137,6 @@ unsigned long ns_entrypoint, unsigned long context_id) { - int rc = PSCI_E_SUCCESS; - unsigned int plat_state; unsigned long psci_entrypoint; assert(cluster_node->level == MPIDR_AFFLVL1); @@ -155,22 +148,20 @@ /* State management: Is not required while turning a cluster on */ + if (!psci_plat_pm_ops->affinst_on) + return PSCI_E_SUCCESS; + /* * Plat. management: Give the platform the current state * of the target cpu to allow it to perform the necessary * steps to power on. */ - if (psci_plat_pm_ops->affinst_on) { - plat_state = psci_get_phys_state(cluster_node); - psci_entrypoint = (unsigned long) psci_aff_on_finish_entry; - rc = psci_plat_pm_ops->affinst_on(target_cpu, - psci_entrypoint, - ns_entrypoint, - cluster_node->level, - plat_state); - } - - return rc; + psci_entrypoint = (unsigned long) psci_aff_on_finish_entry; + return psci_plat_pm_ops->affinst_on(target_cpu, + psci_entrypoint, + ns_entrypoint, + cluster_node->level, + psci_get_phys_state(cluster_node)); } /******************************************************************************* @@ -183,8 +174,6 @@ unsigned long ns_entrypoint, unsigned long context_id) { - int rc = PSCI_E_SUCCESS; - unsigned int plat_state; unsigned long psci_entrypoint; /* Cannot go beyond affinity level 2 in this psci imp. */ @@ -197,22 +186,20 @@ /* State management: Is not required while turning a system on */ + if (!psci_plat_pm_ops->affinst_on) + return PSCI_E_SUCCESS; + /* * Plat. management: Give the platform the current state * of the target cpu to allow it to perform the necessary * steps to power on. */ - if (psci_plat_pm_ops->affinst_on) { - plat_state = psci_get_phys_state(system_node); - psci_entrypoint = (unsigned long) psci_aff_on_finish_entry; - rc = psci_plat_pm_ops->affinst_on(target_cpu, - psci_entrypoint, - ns_entrypoint, - system_node->level, - plat_state); - } - - return rc; + psci_entrypoint = (unsigned long) psci_aff_on_finish_entry; + return psci_plat_pm_ops->affinst_on(target_cpu, + psci_entrypoint, + ns_entrypoint, + system_node->level, + psci_get_phys_state(system_node)); } /* Private data structure to make this handlers accessible through indexing */ @@ -227,7 +214,7 @@ * topology tree and calls the on handler for the corresponding affinity * levels ******************************************************************************/ -static int psci_call_on_handlers(mpidr_aff_map_nodes_t target_cpu_nodes, +static int psci_call_on_handlers(aff_map_node_t *target_cpu_nodes[], int start_afflvl, int end_afflvl, unsigned long target_cpu, @@ -402,10 +389,13 @@ static unsigned int psci_afflvl1_on_finish(aff_map_node_t *cluster_node) { - unsigned int plat_state, rc = PSCI_E_SUCCESS; + unsigned int plat_state; assert(cluster_node->level == MPIDR_AFFLVL1); + if (!psci_plat_pm_ops->affinst_on_finish) + return PSCI_E_SUCCESS; + /* * Plat. management: Perform the platform specific actions * as per the old state of the cluster e.g. enabling @@ -414,27 +404,23 @@ * then assert as there is no way to recover from this * situation. */ - if (psci_plat_pm_ops->affinst_on_finish) { - - /* Get the physical state of this cluster */ - plat_state = psci_get_phys_state(cluster_node); - rc = psci_plat_pm_ops->affinst_on_finish(read_mpidr_el1(), - cluster_node->level, - plat_state); - assert(rc == PSCI_E_SUCCESS); - } - - return rc; + plat_state = psci_get_phys_state(cluster_node); + return psci_plat_pm_ops->affinst_on_finish(read_mpidr_el1(), + cluster_node->level, + plat_state); } static unsigned int psci_afflvl2_on_finish(aff_map_node_t *system_node) { - unsigned int plat_state, rc = PSCI_E_SUCCESS; + unsigned int plat_state; /* Cannot go beyond this affinity level */ assert(system_node->level == MPIDR_AFFLVL2); + if (!psci_plat_pm_ops->affinst_on_finish) + return PSCI_E_SUCCESS; + /* * Currently, there are no architectural actions to perform * at the system level. @@ -448,17 +434,10 @@ * then assert as there is no way to recover from this * situation. */ - if (psci_plat_pm_ops->affinst_on_finish) { - - /* Get the physical state of the system */ - plat_state = psci_get_phys_state(system_node); - rc = psci_plat_pm_ops->affinst_on_finish(read_mpidr_el1(), - system_node->level, - plat_state); - assert(rc == PSCI_E_SUCCESS); - } - - return rc; + plat_state = psci_get_phys_state(system_node); + return psci_plat_pm_ops->affinst_on_finish(read_mpidr_el1(), + system_node->level, + plat_state); } const afflvl_power_on_finisher_t psci_afflvl_on_finishers[] = { diff --git a/services/std_svc/psci/psci_afflvl_suspend.c b/services/std_svc/psci/psci_afflvl_suspend.c index 54f2634..4fcabfc 100644 --- a/services/std_svc/psci/psci_afflvl_suspend.c +++ b/services/std_svc/psci/psci_afflvl_suspend.c @@ -110,7 +110,6 @@ unsigned long context_id, unsigned int power_state) { - unsigned int plat_state; unsigned long psci_entrypoint; uint32_t ns_scr_el3 = read_scr_el3(); uint32_t ns_sctlr_el1 = read_sctlr_el1(); @@ -153,24 +152,20 @@ */ psci_do_pwrdown_cache_maintenance(MPIDR_AFFLVL0); + if (!psci_plat_pm_ops->affinst_suspend) + return PSCI_E_SUCCESS; + /* * Plat. management: Allow the platform to perform the * necessary actions to turn off this cpu e.g. set the * platform defined mailbox with the psci entrypoint, * program the power controller etc. */ - rc = PSCI_E_SUCCESS; - - if (psci_plat_pm_ops->affinst_suspend) { - plat_state = psci_get_phys_state(cpu_node); - rc = psci_plat_pm_ops->affinst_suspend(read_mpidr_el1(), - psci_entrypoint, - ns_entrypoint, - cpu_node->level, - plat_state); - } - - return rc; + return psci_plat_pm_ops->affinst_suspend(read_mpidr_el1(), + psci_entrypoint, + ns_entrypoint, + cpu_node->level, + psci_get_phys_state(cpu_node)); } static int psci_afflvl1_suspend(aff_map_node_t *cluster_node, @@ -178,7 +173,6 @@ unsigned long context_id, unsigned int power_state) { - int rc = PSCI_E_SUCCESS; unsigned int plat_state; unsigned long psci_entrypoint; @@ -186,39 +180,29 @@ assert(cluster_node->level == MPIDR_AFFLVL1); /* - * Keep the physical state of this cluster handy to decide - * what action needs to be taken - */ - plat_state = 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); + if (!psci_plat_pm_ops->affinst_suspend) + return PSCI_E_SUCCESS; + /* - * Plat. Management. Allow the platform to do its cluster - * specific bookeeping e.g. turn off interconnect coherency, - * program the power controller etc. + * Plat. Management. Allow the platform to do its cluster specific + * bookeeping e.g. turn off interconnect coherency, program the power + * controller etc. Sending the psci entrypoint is currently redundant + * beyond affinity level 0 but one never knows what a platform might + * do. Also it allows us to keep the platform handler prototype the + * same. */ - if (psci_plat_pm_ops->affinst_suspend) { - - /* - * Sending the psci entrypoint is currently redundant - * beyond affinity level 0 but one never knows what a - * platform might do. Also it allows us to keep the - * platform handler prototype the same. - */ - psci_entrypoint = (unsigned long) psci_aff_suspend_finish_entry; - rc = psci_plat_pm_ops->affinst_suspend(read_mpidr_el1(), - psci_entrypoint, - ns_entrypoint, - cluster_node->level, - plat_state); - } - - return rc; + plat_state = psci_get_phys_state(cluster_node); + psci_entrypoint = (unsigned long) psci_aff_suspend_finish_entry; + return psci_plat_pm_ops->affinst_suspend(read_mpidr_el1(), + psci_entrypoint, + ns_entrypoint, + cluster_node->level, + plat_state); } @@ -227,7 +211,6 @@ unsigned long context_id, unsigned int power_state) { - int rc = PSCI_E_SUCCESS; unsigned int plat_state; unsigned long psci_entrypoint; @@ -250,23 +233,22 @@ * Plat. Management : Allow the platform to do its bookeeping * at this affinity level */ - if (psci_plat_pm_ops->affinst_suspend) { + if (!psci_plat_pm_ops->affinst_suspend) + return PSCI_E_SUCCESS; - /* - * Sending the psci entrypoint is currently redundant - * beyond affinity level 0 but one never knows what a - * platform might do. Also it allows us to keep the - * platform handler prototype the same. - */ - psci_entrypoint = (unsigned long) psci_aff_suspend_finish_entry; - rc = psci_plat_pm_ops->affinst_suspend(read_mpidr_el1(), - psci_entrypoint, - ns_entrypoint, - system_node->level, - plat_state); - } - - return rc; + /* + * Sending the psci entrypoint is currently redundant + * beyond affinity level 0 but one never knows what a + * platform might do. Also it allows us to keep the + * platform handler prototype the same. + */ + plat_state = psci_get_phys_state(system_node); + psci_entrypoint = (unsigned long) psci_aff_suspend_finish_entry; + return psci_plat_pm_ops->affinst_suspend(read_mpidr_el1(), + psci_entrypoint, + ns_entrypoint, + system_node->level, + plat_state); } static const afflvl_suspend_handler_t psci_afflvl_suspend_handlers[] = { @@ -280,7 +262,7 @@ * topology tree and calls the suspend handler for the corresponding affinity * levels ******************************************************************************/ -static int psci_call_suspend_handlers(mpidr_aff_map_nodes_t mpidr_nodes, +static int psci_call_suspend_handlers(aff_map_node_t *mpidr_nodes[], int start_afflvl, int end_afflvl, unsigned long entrypoint, diff --git a/services/std_svc/psci/psci_common.c b/services/std_svc/psci/psci_common.c index e9d6e5b..2267ad0 100644 --- a/services/std_svc/psci/psci_common.c +++ b/services/std_svc/psci/psci_common.c @@ -65,7 +65,7 @@ ******************************************************************************/ uint32_t psci_find_max_phys_off_afflvl(uint32_t start_afflvl, uint32_t end_afflvl, - mpidr_aff_map_nodes_t mpidr_nodes) + aff_map_node_t *mpidr_nodes[]) { uint32_t max_afflvl = PSCI_INVALID_DATA; @@ -220,7 +220,7 @@ ******************************************************************************/ void psci_do_afflvl_state_mgmt(uint32_t start_afflvl, uint32_t end_afflvl, - mpidr_aff_map_nodes_t mpidr_nodes, + aff_map_node_t *mpidr_nodes[], uint32_t state) { uint32_t level; @@ -239,7 +239,7 @@ ******************************************************************************/ void psci_acquire_afflvl_locks(int start_afflvl, int end_afflvl, - mpidr_aff_map_nodes_t mpidr_nodes) + aff_map_node_t *mpidr_nodes[]) { int level; @@ -257,7 +257,7 @@ ******************************************************************************/ void psci_release_afflvl_locks(int start_afflvl, int end_afflvl, - mpidr_aff_map_nodes_t mpidr_nodes) + aff_map_node_t *mpidr_nodes[]) { int level; @@ -429,7 +429,7 @@ * topology tree and calls the physical power on handler for the corresponding * affinity levels ******************************************************************************/ -static int psci_call_power_on_handlers(mpidr_aff_map_nodes_t mpidr_nodes, +static int psci_call_power_on_handlers(aff_map_node_t *mpidr_nodes[], int start_afflvl, int end_afflvl, afflvl_power_on_finisher_t *pon_handlers) diff --git a/services/std_svc/psci/psci_entry.S b/services/std_svc/psci/psci_entry.S index 4b2b106..cc57aa1 100644 --- a/services/std_svc/psci/psci_entry.S +++ b/services/std_svc/psci/psci_entry.S @@ -35,8 +35,6 @@ .globl psci_aff_on_finish_entry .globl psci_aff_suspend_finish_entry - .globl __psci_cpu_off - .globl __psci_cpu_suspend .globl psci_power_down_wfi /* ----------------------------------------------------- diff --git a/services/std_svc/psci/psci_private.h b/services/std_svc/psci/psci_private.h index bbc8c32..924a24f 100644 --- a/services/std_svc/psci/psci_private.h +++ b/services/std_svc/psci/psci_private.h @@ -94,11 +94,11 @@ int psci_check_afflvl_range(int start_afflvl, int end_afflvl); void psci_do_afflvl_state_mgmt(uint32_t start_afflvl, uint32_t end_afflvl, - mpidr_aff_map_nodes_t mpidr_nodes, + aff_map_node_t *mpidr_nodes[], uint32_t state); void psci_acquire_afflvl_locks(int start_afflvl, - int end_afflvl, - mpidr_aff_map_nodes_t mpidr_nodes); + int end_afflvl, + aff_map_node_t *mpidr_nodes[]); void psci_release_afflvl_locks(int start_afflvl, int end_afflvl, mpidr_aff_map_nodes_t mpidr_nodes); @@ -106,13 +106,13 @@ void psci_set_max_phys_off_afflvl(uint32_t afflvl); uint32_t psci_find_max_phys_off_afflvl(uint32_t start_afflvl, uint32_t end_afflvl, - mpidr_aff_map_nodes_t mpidr_nodes); + aff_map_node_t *mpidr_nodes[]); /* Private exported functions from psci_setup.c */ int psci_get_aff_map_nodes(unsigned long mpidr, int start_afflvl, int end_afflvl, - mpidr_aff_map_nodes_t mpidr_nodes); + aff_map_node_t *mpidr_nodes[]); aff_map_node_t *psci_get_aff_map_node(unsigned long, int); /* Private exported functions from psci_affinity_on.c */ diff --git a/services/std_svc/psci/psci_setup.c b/services/std_svc/psci/psci_setup.c index b49b6e8..a5ae4ef 100644 --- a/services/std_svc/psci/psci_setup.c +++ b/services/std_svc/psci/psci_setup.c @@ -116,7 +116,7 @@ int psci_get_aff_map_nodes(unsigned long mpidr, int start_afflvl, int end_afflvl, - mpidr_aff_map_nodes_t mpidr_nodes) + aff_map_node_t *mpidr_nodes[]) { int rc = PSCI_E_INVALID_PARAMS, level; aff_map_node_t *node;