diff options
Diffstat (limited to 'services/psci')
-rw-r--r-- | services/psci/psci_afflvl_off.c | 4 | ||||
-rw-r--r-- | services/psci/psci_afflvl_on.c | 8 | ||||
-rw-r--r-- | services/psci/psci_afflvl_suspend.c | 8 | ||||
-rw-r--r-- | services/psci/psci_common.c | 16 | ||||
-rw-r--r-- | services/psci/psci_private.h | 5 |
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 |