Browse Source

Miscellaneous PSCI code cleanups

This patch implements the following cleanups in PSCI generic code:

1. It reworks the affinity level specific handlers in the PSCI implementation
   such that.

   a. Usage of the 'rc' local variable is restricted to only where it is
      absolutely needed

   b. 'plat_state' local variable is defined only when a direct invocation of
      plat_get_phys_state() does not suffice.

   c. If a platform handler is not registered then the level specific handler
      returns early.

2. It limits the use of the mpidr_aff_map_nodes_t typedef to declaration of
   arrays of the type instead of using it in function prototypes as well.

3. It removes dangling declarations of __psci_cpu_off() and
   __psci_cpu_suspend(). The definitions of these functions were removed in
   earlier patches.

Change-Id: I51e851967c148be9c2eeda3a3c41878f7b4d6978
pull/192/head
Achin Gupta 10 years ago
committed by Soby Mathew
parent
commit
a4a8eaeb36
  1. 2
      include/bl31/services/psci.h
  2. 56
      services/std_svc/psci/psci_afflvl_off.c
  3. 107
      services/std_svc/psci/psci_afflvl_on.c
  4. 98
      services/std_svc/psci/psci_afflvl_suspend.c
  5. 10
      services/std_svc/psci/psci_common.c
  6. 2
      services/std_svc/psci/psci_entry.S
  7. 10
      services/std_svc/psci/psci_private.h
  8. 2
      services/std_svc/psci/psci_setup.c

2
include/bl31/services/psci.h

@ -189,8 +189,6 @@ typedef struct spd_pm_ops {
* 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);

56
services/std_svc/psci/psci_afflvl_off.c

@ -42,7 +42,6 @@ typedef int (*afflvl_off_handler_t)(aff_map_node_t *);
******************************************************************************/
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 @@ static int psci_afflvl0_off(aff_map_node_t *cpu_node)
*/
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 @@ static int psci_afflvl2_off(aff_map_node_t *system_node)
* 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 @@ static int psci_afflvl2_off(aff_map_node_t *system_node)
*/
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 @@ static const afflvl_off_handler_t psci_afflvl_off_handlers[] = {
* 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)
{

107
services/std_svc/psci/psci_afflvl_on.c

@ -75,7 +75,6 @@ static int psci_afflvl0_on(unsigned long target_cpu,
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 @@ static int psci_afflvl0_on(unsigned long target_cpu,
/* 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 @@ static int psci_afflvl1_on(unsigned long target_cpu,
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 @@ static int psci_afflvl1_on(unsigned long target_cpu,
/* 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 @@ static int psci_afflvl2_on(unsigned long target_cpu,
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 @@ static int psci_afflvl2_on(unsigned long target_cpu,
/* 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 @@ static const afflvl_on_handler_t psci_afflvl_on_handlers[] = {
* 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_afflvl0_on_finish(aff_map_node_t *cpu_node)
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 @@ static unsigned int psci_afflvl1_on_finish(aff_map_node_t *cluster_node)
* 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 @@ static unsigned int psci_afflvl2_on_finish(aff_map_node_t *system_node)
* 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[] = {

98
services/std_svc/psci/psci_afflvl_suspend.c

@ -110,7 +110,6 @@ static int psci_afflvl0_suspend(aff_map_node_t *cpu_node,
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 @@ static int psci_afflvl0_suspend(aff_map_node_t *cpu_node,
*/
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,47 +173,36 @@ static int psci_afflvl1_suspend(aff_map_node_t *cluster_node,
unsigned long context_id,
unsigned int power_state)
{
int rc = PSCI_E_SUCCESS;
unsigned int plat_state;
unsigned long psci_entrypoint;
/* 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_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 @@ static int psci_afflvl2_suspend(aff_map_node_t *system_node,
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 @@ static int psci_afflvl2_suspend(aff_map_node_t *system_node,
* Plat. Management : Allow the platform to do its bookeeping
* at this affinity level
*/
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,
system_node->level,
plat_state);
}
if (!psci_plat_pm_ops->affinst_suspend)
return PSCI_E_SUCCESS;
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 @@ static const afflvl_suspend_handler_t psci_afflvl_suspend_handlers[] = {
* 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,

10
services/std_svc/psci/psci_common.c

@ -65,7 +65,7 @@ const plat_pm_ops_t *psci_plat_pm_ops;
******************************************************************************/
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 @@ 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)
{
uint32_t level;
@ -239,7 +239,7 @@ void psci_do_afflvl_state_mgmt(uint32_t start_afflvl,
******************************************************************************/
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_acquire_afflvl_locks(int start_afflvl,
******************************************************************************/
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 @@ unsigned short psci_get_phys_state(aff_map_node_t *node)
* 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)

2
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
/* -----------------------------------------------------

10
services/std_svc/psci/psci_private.h

@ -94,11 +94,11 @@ int psci_save_ns_entry(uint64_t mpidr,
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_print_affinity_map(void);
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 */

2
services/std_svc/psci/psci_setup.c

@ -116,7 +116,7 @@ aff_map_node_t *psci_get_aff_map_node(unsigned long mpidr, int aff_lvl)
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;

Loading…
Cancel
Save