summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorJeenu Viswambharan <jeenu.viswambharan@arm.com>2016-08-03 15:54:50 +0100
committerJeenu Viswambharan <jeenu.viswambharan@arm.com>2016-09-15 11:17:55 +0100
commit28d3d614b57730bdf364e49259d3c42599d26145 (patch)
tree5c86445a3cd7cdb46ccd2508264a7c41cc253b43 /lib
parent77b05323921c23e4261ddd8fee5c326a79b0af97 (diff)
PSCI: Add support for PSCI NODE_HW_STATE API
This patch adds support for NODE_HW_STATE PSCI API by introducing a new PSCI platform hook (get_node_hw_state). The implementation validates supplied arguments, and then invokes this platform-defined hook and returns its result to the caller. PSCI capabilities are updated accordingly. Also updates porting and firmware design guides. Change-Id: I808e55bdf0c157002a7c104b875779fe50a68a30
Diffstat (limited to 'lib')
-rw-r--r--lib/psci/psci_main.c31
-rw-r--r--lib/psci/psci_private.h1
-rw-r--r--lib/psci/psci_setup.c2
3 files changed, 34 insertions, 0 deletions
diff --git a/lib/psci/psci_main.c b/lib/psci/psci_main.c
index 3ad3dd40..23bd106c 100644
--- a/lib/psci/psci_main.c
+++ b/lib/psci/psci_main.c
@@ -295,6 +295,31 @@ long psci_migrate_info_up_cpu(void)
return resident_cpu_mpidr;
}
+int psci_node_hw_state(u_register_t target_cpu,
+ unsigned int power_level)
+{
+ int rc;
+
+ /* Validate target_cpu */
+ rc = psci_validate_mpidr(target_cpu);
+ if (rc != PSCI_E_SUCCESS)
+ return PSCI_E_INVALID_PARAMS;
+
+ /* Validate power_level against PLAT_MAX_PWR_LVL */
+ if (power_level > PLAT_MAX_PWR_LVL)
+ return PSCI_E_INVALID_PARAMS;
+
+ /*
+ * Dispatch this call to platform to query power controller, and pass on
+ * to the caller what it returns
+ */
+ assert(psci_plat_pm_ops->get_node_hw_state);
+ rc = psci_plat_pm_ops->get_node_hw_state(target_cpu, power_level);
+ assert((rc >= HW_ON && rc <= HW_STANDBY) || rc == PSCI_E_NOT_SUPPORTED
+ || rc == PSCI_E_INVALID_PARAMS);
+ return rc;
+}
+
int psci_features(unsigned int psci_fid)
{
unsigned int local_caps = psci_caps;
@@ -378,6 +403,9 @@ u_register_t psci_smc_handler(uint32_t smc_fid,
case PSCI_MIG_INFO_UP_CPU_AARCH32:
return psci_migrate_info_up_cpu();
+ case PSCI_NODE_HW_STATE_AARCH32:
+ return psci_node_hw_state(x1, x2);
+
case PSCI_SYSTEM_SUSPEND_AARCH32:
return psci_system_suspend(x1, x2);
@@ -422,6 +450,9 @@ u_register_t psci_smc_handler(uint32_t smc_fid,
case PSCI_MIG_INFO_UP_CPU_AARCH64:
return psci_migrate_info_up_cpu();
+ case PSCI_NODE_HW_STATE_AARCH64:
+ return psci_node_hw_state(x1, x2);
+
case PSCI_SYSTEM_SUSPEND_AARCH64:
return psci_system_suspend(x1, x2);
diff --git a/lib/psci/psci_private.h b/lib/psci/psci_private.h
index b795c8e0..781b3b52 100644
--- a/lib/psci/psci_private.h
+++ b/lib/psci/psci_private.h
@@ -68,6 +68,7 @@
define_psci_cap(PSCI_AFFINITY_INFO_AARCH64) | \
define_psci_cap(PSCI_MIG_AARCH64) | \
define_psci_cap(PSCI_MIG_INFO_UP_CPU_AARCH64) | \
+ define_psci_cap(PSCI_NODE_HW_STATE_AARCH64) | \
define_psci_cap(PSCI_SYSTEM_SUSPEND_AARCH64) | \
define_psci_cap(PSCI_STAT_RESIDENCY_AARCH64) | \
define_psci_cap(PSCI_STAT_COUNT_AARCH64))
diff --git a/lib/psci/psci_setup.c b/lib/psci/psci_setup.c
index 20d06352..1ac1f23d 100644
--- a/lib/psci/psci_setup.c
+++ b/lib/psci/psci_setup.c
@@ -256,6 +256,8 @@ int psci_setup(uintptr_t mailbox_ep)
psci_caps |= define_psci_cap(PSCI_SYSTEM_OFF);
if (psci_plat_pm_ops->system_reset)
psci_caps |= define_psci_cap(PSCI_SYSTEM_RESET);
+ if (psci_plat_pm_ops->get_node_hw_state)
+ psci_caps |= define_psci_cap(PSCI_NODE_HW_STATE_AARCH64);
#if ENABLE_PSCI_STAT
psci_caps |= define_psci_cap(PSCI_STAT_RESIDENCY_AARCH64);