aboutsummaryrefslogtreecommitdiff
path: root/services/psci
diff options
context:
space:
mode:
Diffstat (limited to 'services/psci')
-rw-r--r--services/psci/psci_afflvl_off.c4
-rw-r--r--services/psci/psci_afflvl_on.c8
-rw-r--r--services/psci/psci_afflvl_suspend.c8
-rw-r--r--services/psci/psci_common.c16
-rw-r--r--services/psci/psci_private.h5
5 files changed, 25 insertions, 16 deletions
diff --git a/services/psci/psci_afflvl_off.c b/services/psci/psci_afflvl_off.c
index 24c212f..3763f6f 100644
--- a/services/psci/psci_afflvl_off.c
+++ b/services/psci/psci_afflvl_off.c
@@ -65,8 +65,8 @@ static int psci_afflvl0_off(unsigned long mpidr, aff_map_node *cpu_node)
* to let it do any bookeeping. Assume that the SPD always reports an
* E_DENIED error if SP refuse to power down
*/
- if (spd_pm.svc_off) {
- rc = spd_pm.svc_off(0);
+ if (psci_spd_pm && psci_spd_pm->svc_off) {
+ rc = psci_spd_pm->svc_off(0);
if (rc)
return rc;
}
diff --git a/services/psci/psci_afflvl_on.c b/services/psci/psci_afflvl_on.c
index ee16c73..0878f21 100644
--- a/services/psci/psci_afflvl_on.c
+++ b/services/psci/psci_afflvl_on.c
@@ -95,8 +95,8 @@ static int psci_afflvl0_on(unsigned long target_cpu,
* to let it do any bookeeping. If the handler encounters an error, it's
* expected to assert within
*/
- if (spd_pm.svc_on)
- spd_pm.svc_on(target_cpu);
+ if (psci_spd_pm && psci_spd_pm->svc_on)
+ psci_spd_pm->svc_on(target_cpu);
/*
* Arch. management: Derive the re-entry information for
@@ -387,8 +387,8 @@ static unsigned int psci_afflvl0_on_finish(unsigned long mpidr,
* Dispatcher to let it do any bookeeping. If the handler encounters an
* error, it's expected to assert within
*/
- if (spd_pm.svc_on_finish)
- spd_pm.svc_on_finish(0);
+ if (psci_spd_pm && psci_spd_pm->svc_on_finish)
+ psci_spd_pm->svc_on_finish(0);
/*
* Generic management: Now we just need to retrieve the
diff --git a/services/psci/psci_afflvl_suspend.c b/services/psci/psci_afflvl_suspend.c
index 62d270f..138d033 100644
--- a/services/psci/psci_afflvl_suspend.c
+++ b/services/psci/psci_afflvl_suspend.c
@@ -104,8 +104,8 @@ static int psci_afflvl0_suspend(unsigned long mpidr,
* Dispatcher to let it do any bookeeping. If the handler encounters an
* error, it's expected to assert within
*/
- if (spd_pm.svc_suspend)
- spd_pm.svc_suspend(power_state);
+ if (psci_spd_pm && psci_spd_pm->svc_suspend)
+ psci_spd_pm->svc_suspend(power_state);
/* State management: mark this cpu as suspended */
psci_set_state(cpu_node, PSCI_STATE_SUSPEND);
@@ -459,9 +459,9 @@ static unsigned int psci_afflvl0_suspend_finish(unsigned long mpidr,
* Dispatcher to let it do any bookeeping. If the handler encounters an
* error, it's expected to assert within
*/
- if (spd_pm.svc_suspend) {
+ if (psci_spd_pm && psci_spd_pm->svc_suspend) {
suspend_level = psci_get_suspend_afflvl(cpu_node);
- spd_pm.svc_suspend_finish(suspend_level);
+ psci_spd_pm->svc_suspend_finish(suspend_level);
}
/*
diff --git a/services/psci/psci_common.c b/services/psci/psci_common.c
index cacd97e..236309c 100644
--- a/services/psci/psci_common.c
+++ b/services/psci/psci_common.c
@@ -41,10 +41,10 @@
#include "debug.h"
/*
- * Provide a null weak instantiation for SPD power management operations. An SPD
- * can define its own instance overriding this one
+ * SPD power management operations, expected to be supplied by the registered
+ * SPD on successful SP initialization
*/
-const spd_pm_ops __attribute__((weak)) spd_pm = {0};
+const spd_pm_ops *psci_spd_pm;
/*******************************************************************************
* Arrays that contains information needs to resume a cpu's execution when woken
@@ -556,3 +556,13 @@ void psci_afflvl_power_on_finish(unsigned long mpidr,
end_afflvl,
mpidr_nodes);
}
+
+/*******************************************************************************
+ * This function initializes the set of hooks that PSCI invokes as part of power
+ * management operation. The power management hooks are expected to be provided
+ * by the SPD, after it finishes all its initialization
+ ******************************************************************************/
+void psci_register_spd_pm_hook(const spd_pm_ops *pm)
+{
+ psci_spd_pm = pm;
+}
diff --git a/services/psci/psci_private.h b/services/psci/psci_private.h
index 351cbe8..4f47ca5 100644
--- a/services/psci/psci_private.h
+++ b/services/psci/psci_private.h
@@ -96,10 +96,9 @@ extern afflvl_power_on_finisher psci_afflvl_off_finish_handlers[];
extern afflvl_power_on_finisher psci_afflvl_sus_finish_handlers[];
/*******************************************************************************
- * Weak declarations to allow PSCI to cope on a system where the Secure Payload
- * Dispatcher is missing. An SPD will define this structure when present.
+ * SPD's power management hooks registered with PSCI
******************************************************************************/
-extern const spd_pm_ops spd_pm;
+extern const spd_pm_ops *psci_spd_pm;
/*******************************************************************************
* Function prototypes