aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firmware/psci.c
diff options
context:
space:
mode:
authorMarc Zyngier <marc.zyngier@arm.com>2018-02-06 12:56:17 -0500
committerCatalin Marinas <catalin.marinas@arm.com>2018-02-06 17:54:11 -0500
commite78eef554a912ef6c1e0bbf97619dafbeae3339f (patch)
tree2e68319038f14390223f645e4b8af4f68219031a /drivers/firmware/psci.c
parent09a8d6d48499f93e2abde691f5800081cd858726 (diff)
firmware/psci: Expose SMCCC version through psci_ops
Since PSCI 1.0 allows the SMCCC version to be (indirectly) probed, let's do that at boot time, and expose the version of the calling convention as part of the psci_ops structure. Acked-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> Reviewed-by: Robin Murphy <robin.murphy@arm.com> Tested-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Diffstat (limited to 'drivers/firmware/psci.c')
-rw-r--r--drivers/firmware/psci.c27
1 files changed, 27 insertions, 0 deletions
diff --git a/drivers/firmware/psci.c b/drivers/firmware/psci.c
index e9493da2b111..c80ec1d03274 100644
--- a/drivers/firmware/psci.c
+++ b/drivers/firmware/psci.c
@@ -61,6 +61,7 @@ bool psci_tos_resident_on(int cpu)
61 61
62struct psci_operations psci_ops = { 62struct psci_operations psci_ops = {
63 .conduit = PSCI_CONDUIT_NONE, 63 .conduit = PSCI_CONDUIT_NONE,
64 .smccc_version = SMCCC_VERSION_1_0,
64}; 65};
65 66
66typedef unsigned long (psci_fn)(unsigned long, unsigned long, 67typedef unsigned long (psci_fn)(unsigned long, unsigned long,
@@ -511,6 +512,31 @@ static void __init psci_init_migrate(void)
511 pr_info("Trusted OS resident on physical CPU 0x%lx\n", cpuid); 512 pr_info("Trusted OS resident on physical CPU 0x%lx\n", cpuid);
512} 513}
513 514
515static void __init psci_init_smccc(void)
516{
517 u32 ver = ARM_SMCCC_VERSION_1_0;
518 int feature;
519
520 feature = psci_features(ARM_SMCCC_VERSION_FUNC_ID);
521
522 if (feature != PSCI_RET_NOT_SUPPORTED) {
523 u32 ret;
524 ret = invoke_psci_fn(ARM_SMCCC_VERSION_FUNC_ID, 0, 0, 0);
525 if (ret == ARM_SMCCC_VERSION_1_1) {
526 psci_ops.smccc_version = SMCCC_VERSION_1_1;
527 ver = ret;
528 }
529 }
530
531 /*
532 * Conveniently, the SMCCC and PSCI versions are encoded the
533 * same way. No, this isn't accidental.
534 */
535 pr_info("SMC Calling Convention v%d.%d\n",
536 PSCI_VERSION_MAJOR(ver), PSCI_VERSION_MINOR(ver));
537
538}
539
514static void __init psci_0_2_set_functions(void) 540static void __init psci_0_2_set_functions(void)
515{ 541{
516 pr_info("Using standard PSCI v0.2 function IDs\n"); 542 pr_info("Using standard PSCI v0.2 function IDs\n");
@@ -559,6 +585,7 @@ static int __init psci_probe(void)
559 psci_init_migrate(); 585 psci_init_migrate();
560 586
561 if (PSCI_VERSION_MAJOR(ver) >= 1) { 587 if (PSCI_VERSION_MAJOR(ver) >= 1) {
588 psci_init_smccc();
562 psci_init_cpu_suspend(); 589 psci_init_cpu_suspend();
563 psci_init_system_suspend(); 590 psci_init_system_suspend();
564 } 591 }