From 16e05cdbf7832cc2e7e32ed747b589fe41d749ae Mon Sep 17 00:00:00 2001 From: Soby Mathew Date: Thu, 1 Oct 2015 16:46:06 +0100 Subject: PSCI: Update state only if CPU_OFF is not denied by SPD This patch fixes an issue in the PSCI framework where the affinity info state of a core was being set to OFF even when the SPD had denied the CPU_OFF request. Now, the state remains set to ON instead. Fixes ARM-software/tf-issues#323 Change-Id: Ia9042aa41fae574eaa07fd2ce3f50cf8cae1b6fc --- services/std_svc/psci/psci_off.c | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) (limited to 'services') diff --git a/services/std_svc/psci/psci_off.c b/services/std_svc/psci/psci_off.c index f565ffb7..9ed6f0cf 100644 --- a/services/std_svc/psci/psci_off.c +++ b/services/std_svc/psci/psci_off.c @@ -62,7 +62,7 @@ static void psci_set_power_off_state(psci_power_state_t *state_info) ******************************************************************************/ int psci_do_cpu_off(unsigned int end_pwrlvl) { - int rc, idx = plat_my_core_pos(); + int rc = PSCI_E_SUCCESS, idx = plat_my_core_pos(); psci_power_state_t state_info; /* @@ -120,23 +120,27 @@ exit: psci_release_pwr_domain_locks(end_pwrlvl, idx); - /* - * Set the affinity info state to OFF. This writes directly to main - * memory as caches are disabled, so cache maintenance is required - * to ensure that later cached reads of aff_info_state return - * AFF_STATE_OFF. - */ - flush_cpu_data(psci_svc_cpu_data.aff_info_state); - psci_set_aff_info_state(AFF_STATE_OFF); - inv_cpu_data(psci_svc_cpu_data.aff_info_state); - /* * Check if all actions needed to safely power down this cpu have - * successfully completed. Enter a wfi loop which will allow the - * power controller to physically power down this cpu. + * successfully completed. */ - if (rc == PSCI_E_SUCCESS) + if (rc == PSCI_E_SUCCESS) { + /* + * Set the affinity info state to OFF. This writes directly to + * main memory as caches are disabled, so cache maintenance is + * required to ensure that later cached reads of aff_info_state + * return AFF_STATE_OFF. + */ + flush_cpu_data(psci_svc_cpu_data.aff_info_state); + psci_set_aff_info_state(AFF_STATE_OFF); + inv_cpu_data(psci_svc_cpu_data.aff_info_state); + + /* + * Enter a wfi loop which will allow the power controller to + * physically power down this cpu. + */ psci_power_down_wfi(); + } return rc; } -- cgit v1.2.3