diff --git a/docs/porting-guide.rst b/docs/porting-guide.rst index 25b55e813..fc7266ece 100644 --- a/docs/porting-guide.rst +++ b/docs/porting-guide.rst @@ -2785,6 +2785,22 @@ Perform the platform specific actions to power on a CPU, specified by the ``MPIDR`` (first argument). The generic code expects the platform to return PSCI_E_SUCCESS on success or PSCI_E_INTERN_FAIL for any failure. +plat_psci_ops.pwr_domain_off_early() [optional] +............................................... + +This optional function performs the platform specific actions to check if +powering off the calling CPU and its higher parent power domain levels as +indicated by the ``target_state`` (first argument) is possible or allowed. + +The ``target_state`` encodes the platform coordinated target local power states +for the CPU power domain and its parent power domain levels. + +For this handler, the local power state for the CPU power domain will be a +power down state where as it could be either power down, retention or run state +for the higher power domain levels depending on the result of state +coordination. The generic code expects PSCI_E_DENIED return code if the +platform thinks that CPU_OFF should not proceed on the calling CPU. + plat_psci_ops.pwr_domain_off() .............................. diff --git a/include/lib/psci/psci.h b/include/lib/psci/psci.h index 6d27b7b61..4d7e58e93 100644 --- a/include/lib/psci/psci.h +++ b/include/lib/psci/psci.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2023, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -317,6 +318,7 @@ typedef struct plat_psci_ops { void (*cpu_standby)(plat_local_state_t cpu_state); int (*pwr_domain_on)(u_register_t mpidr); void (*pwr_domain_off)(const psci_power_state_t *target_state); + int (*pwr_domain_off_early)(const psci_power_state_t *target_state); void (*pwr_domain_suspend_pwrdown_early)( const psci_power_state_t *target_state); #if PSCI_OS_INIT_MODE diff --git a/lib/psci/psci_off.c b/lib/psci/psci_off.c index 637adb97e..9f36ac719 100644 --- a/lib/psci/psci_off.c +++ b/lib/psci/psci_off.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2023, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -56,6 +57,19 @@ int psci_do_cpu_off(unsigned int end_pwrlvl) /* Construct the psci_power_state for CPU_OFF */ psci_set_power_off_state(&state_info); + /* + * Call the platform provided early CPU_OFF handler to allow + * platforms to perform any housekeeping activities before + * actually powering the CPU off. PSCI_E_DENIED indicates that + * the CPU off sequence should be aborted at this time. + */ + if (psci_plat_pm_ops->pwr_domain_off_early) { + rc = psci_plat_pm_ops->pwr_domain_off_early(&state_info); + if (rc == PSCI_E_DENIED) { + return rc; + } + } + /* * Get the parent nodes here, this is important to do before we * initiate the power down sequence as after that point the core may