firmware: arm_ffa: Add support for SMCCC as transport to FFA driver
authorSudeep Holla <sudeep.holla@arm.com>
Fri, 21 May 2021 15:10:31 +0000 (16:10 +0100)
committerSudeep Holla <sudeep.holla@arm.com>
Wed, 26 May 2021 21:36:46 +0000 (22:36 +0100)
There are requests to keep the transport separate in order to allow
other possible transports like virtio. So let us keep the SMCCC transport
specific routines abstracted.

It is kept simple for now. Once we add another transport, we can develop
better abstraction.

Link: https://lore.kernel.org/r/20210521151033.181846-4-sudeep.holla@arm.com
Tested-by: Jens Wiklander <jens.wiklander@linaro.org>
Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
drivers/firmware/arm_ffa/Kconfig
drivers/firmware/arm_ffa/Makefile
drivers/firmware/arm_ffa/common.h
drivers/firmware/arm_ffa/smccc.c [new file with mode: 0644]

index 261a3660650ae78f15961e8898676fa322b7ecab..5e3ae5cf82e8e1d4b84671ba749f7cdf5d18e8b8 100644 (file)
@@ -14,3 +14,8 @@ config ARM_FFA_TRANSPORT
 
          This driver provides interface for all the client drivers making
          use of the features offered by ARM FF-A.
+
+config ARM_FFA_SMCCC
+       bool
+       default ARM_FFA_TRANSPORT
+       depends on ARM64 && HAVE_ARM_SMCCC_DISCOVERY
index 82d0d35c5324868bc0fcb77c87d09d7d3378e6a3..9d9f375232003e0aeaf66730fda99d1861f7b467 100644 (file)
@@ -1,5 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0-only
 ffa-bus-y = bus.o
 ffa-driver-y = driver.o
-ffa-module-objs := $(ffa-bus-y) $(ffa-driver-y)
+ffa-transport-$(CONFIG_ARM_FFA_SMCCC) += smccc.o
+ffa-module-objs := $(ffa-bus-y) $(ffa-driver-y) $(ffa-transport-y)
 obj-$(CONFIG_ARM_FFA_TRANSPORT) = ffa-module.o
index 2d3a32f67d5def352626fc01244762f429afc775..f24754a59f47689cca13f11bd131b452df4b16d5 100644 (file)
@@ -16,9 +16,13 @@ typedef void (ffa_fn)(ffa_value_t, ffa_value_t *);
 int arm_ffa_bus_init(void);
 void arm_ffa_bus_exit(void);
 
+#ifdef CONFIG_ARM_FFA_SMCCC
+int __init ffa_transport_init(ffa_fn **invoke_ffa_fn);
+#else
 static inline int __init ffa_transport_init(ffa_fn **invoke_ffa_fn)
 {
        return -EOPNOTSUPP;
 }
+#endif
 
 #endif /* _FFA_COMMON_H */
diff --git a/drivers/firmware/arm_ffa/smccc.c b/drivers/firmware/arm_ffa/smccc.c
new file mode 100644 (file)
index 0000000..4d85bff
--- /dev/null
@@ -0,0 +1,39 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2021 ARM Ltd.
+ */
+
+#include <linux/printk.h>
+
+#include "common.h"
+
+static void __arm_ffa_fn_smc(ffa_value_t args, ffa_value_t *res)
+{
+       arm_smccc_1_2_smc(&args, res);
+}
+
+static void __arm_ffa_fn_hvc(ffa_value_t args, ffa_value_t *res)
+{
+       arm_smccc_1_2_hvc(&args, res);
+}
+
+int __init ffa_transport_init(ffa_fn **invoke_ffa_fn)
+{
+       enum arm_smccc_conduit conduit;
+
+       if (arm_smccc_get_version() < ARM_SMCCC_VERSION_1_2)
+               return -EOPNOTSUPP;
+
+       conduit = arm_smccc_1_1_get_conduit();
+       if (conduit == SMCCC_CONDUIT_NONE) {
+               pr_err("%s: invalid SMCCC conduit\n", __func__);
+               return -EOPNOTSUPP;
+       }
+
+       if (conduit == SMCCC_CONDUIT_SMC)
+               *invoke_ffa_fn = __arm_ffa_fn_smc;
+       else
+               *invoke_ffa_fn = __arm_ffa_fn_hvc;
+
+       return 0;
+}