summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/porting-guide.rst16
-rw-r--r--include/lib/psci/psci.h2
-rw-r--r--lib/psci/psci_off.c14
3 files changed, 32 insertions, 0 deletions
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
*/
@@ -57,6 +58,19 @@ int psci_do_cpu_off(unsigned int end_pwrlvl)
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
* have exited coherency and its cache may be disabled, any access to