summaryrefslogtreecommitdiff
path: root/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-arm64-ack-5.15/tc/0033-ANDROID-trusty-Add-trusty-ffa-driver.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-arm64-ack-5.15/tc/0033-ANDROID-trusty-Add-trusty-ffa-driver.patch')
-rw-r--r--meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-arm64-ack-5.15/tc/0033-ANDROID-trusty-Add-trusty-ffa-driver.patch313
1 files changed, 313 insertions, 0 deletions
diff --git a/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-arm64-ack-5.15/tc/0033-ANDROID-trusty-Add-trusty-ffa-driver.patch b/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-arm64-ack-5.15/tc/0033-ANDROID-trusty-Add-trusty-ffa-driver.patch
new file mode 100644
index 0000000000..4c70e34d12
--- /dev/null
+++ b/meta-arm/meta-arm-bsp/recipes-kernel/linux/linux-arm64-ack-5.15/tc/0033-ANDROID-trusty-Add-trusty-ffa-driver.patch
@@ -0,0 +1,313 @@
+From 34236d8df51d00d1167481760fda5abb56850765 Mon Sep 17 00:00:00 2001
+From: Arunachalam Ganapathy <arunachalam.ganapathy@arm.com>
+Date: Fri, 14 Jan 2022 18:47:08 +0000
+Subject: [PATCH 33/40] ANDROID: trusty: Add trusty-ffa driver
+
+Initial changes related to FFA transport support
+ - Adds FFA transport descriptor
+ - Defines Trusty UUID
+ - Initializes FFA transport does probe, sets ffa_ops
+ - Defers Trusty probe if ARM FF-A driver is not initialized or
+ Trusty SP not found.
+ - Link FF-A device as the supplier for Trusty platform device.
+
+Signed-off-by: Arunachalam Ganapathy <arunachalam.ganapathy@arm.com>
+Change-Id: I78f72b85c20e4bad4c24cf0826e96f27dcf2ee1d
+Upstream-Status: Pending [Not submitted to upstream yet]
+Signed-off-by: Rupinderjit Singh <rupinderjit.singh@arm.com
+---
+ drivers/trusty/Makefile | 1 +
+ drivers/trusty/trusty-ffa.c | 196 ++++++++++++++++++++++++++++++++
+ drivers/trusty/trusty-ffa.h | 28 +++++
+ drivers/trusty/trusty-private.h | 1 +
+ drivers/trusty/trusty.c | 6 +
+ 5 files changed, 232 insertions(+)
+ create mode 100644 drivers/trusty/trusty-ffa.c
+ create mode 100644 drivers/trusty/trusty-ffa.h
+
+diff --git a/drivers/trusty/Makefile b/drivers/trusty/Makefile
+index fbb53ee93003..797d61bf68ef 100644
+--- a/drivers/trusty/Makefile
++++ b/drivers/trusty/Makefile
+@@ -6,6 +6,7 @@
+ obj-$(CONFIG_TRUSTY) += trusty-core.o
+ trusty-core-objs += trusty.o trusty-mem.o
+ trusty-core-objs += trusty-smc.o
++trusty-core-objs += trusty-ffa.o
+ trusty-core-$(CONFIG_ARM) += trusty-smc-arm.o
+ trusty-core-$(CONFIG_ARM64) += trusty-smc-arm64.o
+ obj-$(CONFIG_TRUSTY_IRQ) += trusty-irq.o
+diff --git a/drivers/trusty/trusty-ffa.c b/drivers/trusty/trusty-ffa.c
+new file mode 100644
+index 000000000000..c8c16a1fc700
+--- /dev/null
++++ b/drivers/trusty/trusty-ffa.c
+@@ -0,0 +1,196 @@
++/* SPDX-License-Identifier: GPL-2.0-only */
++/*
++ * Copyright (C) 2022 ARM Ltd.
++ */
++
++#include <linux/platform_device.h>
++#include <linux/slab.h>
++#include <linux/trusty/smcall.h>
++#include <linux/arm_ffa.h>
++#include <linux/trusty/trusty.h>
++
++#include <linux/scatterlist.h>
++#include <linux/dma-mapping.h>
++
++#include "trusty-ffa.h"
++#include "trusty-private.h"
++
++static const struct trusty_mem_ops trusty_ffa_mem_ops = {
++ .desc = &trusty_ffa_transport,
++};
++
++static const struct ffa_device_id trusty_ffa_device_id[] = {
++ /*
++ * Trusty UID: RFC-4122 compliant UUID version 4
++ * 40ee25f0-a2bc-304c-8c4ca173c57d8af1
++ */
++ { UUID_INIT(0x40ee25f0, 0xa2bc, 0x304c,
++ 0x8c, 0x4c, 0xa1, 0x73, 0xc5, 0x7d, 0x8a, 0xf1) },
++ {}
++};
++
++static int trusty_ffa_dev_match(struct device *dev, const void *uuid)
++{
++ struct ffa_device *ffa_dev;
++
++ ffa_dev = to_ffa_dev(dev);
++ if (uuid_equal(&ffa_dev->uuid, uuid))
++ return 1;
++
++ return 0;
++}
++
++static struct ffa_device *trusty_ffa_dev_find(void)
++{
++ const void *data;
++ struct device *dev;
++
++ /* currently only one trusty instance is probed */
++ data = &trusty_ffa_device_id[0].uuid;
++
++ dev = bus_find_device(&ffa_bus_type, NULL, data, trusty_ffa_dev_match);
++ if (dev) {
++ /* drop reference count */
++ put_device(dev);
++ return to_ffa_dev(dev);
++ }
++
++ return NULL;
++}
++
++static int trusty_ffa_link_supplier(struct device *c_dev, struct device *s_dev)
++{
++ if (!c_dev || !s_dev)
++ return -EINVAL;
++
++ if (!device_link_add(c_dev, s_dev, DL_FLAG_AUTOREMOVE_CONSUMER)) {
++ return -ENODEV;
++ }
++
++ return 0;
++}
++
++/*
++ * called from trusty probe
++ */
++static int trusty_ffa_transport_setup(struct device *dev)
++{
++ int rc;
++ struct trusty_state *s = platform_get_drvdata(to_platform_device(dev));
++ struct trusty_ffa_state *ffa_state;
++ struct ffa_device *ffa_dev;
++
++ /* ffa transport not required for lower api versions */
++ if (s->api_version != 0 && s->api_version < TRUSTY_API_VERSION_MEM_OBJ) {
++ return -EINVAL;
++ }
++
++ ffa_dev = trusty_ffa_dev_find();
++ if (!ffa_dev) {
++ dev_dbg(dev, "FFA: Trusty device not found defer probe\n");
++ return -EPROBE_DEFER;
++ }
++
++ ffa_state = ffa_dev_get_drvdata(ffa_dev);
++ if (!ffa_state)
++ return -EINVAL;
++
++ rc = trusty_ffa_link_supplier(dev, &ffa_dev->dev);
++ if (rc != 0)
++ return rc;
++
++ /* FFA used only for memory sharing operations */
++ if (s->api_version == TRUSTY_API_VERSION_MEM_OBJ) {
++ s->ffa = ffa_state;
++ s->mem_ops = &trusty_ffa_mem_ops;
++ return 0;
++ }
++
++ return -EINVAL;
++}
++
++static void trusty_ffa_transport_cleanup(struct device *dev)
++{
++ struct trusty_state *s = platform_get_drvdata(to_platform_device(dev));
++
++ /* ffa transport not setup for lower api versions */
++ if (s->api_version < TRUSTY_API_VERSION_MEM_OBJ) {
++ return;
++ }
++
++ s->ffa = NULL;
++ s->mem_ops = NULL;
++}
++
++static int trusty_ffa_probe(struct ffa_device *ffa_dev)
++{
++ const struct ffa_dev_ops *ffa_ops;
++ struct trusty_ffa_state *s;
++ u32 ffa_drv_version;
++
++ ffa_ops = ffa_dev_ops_get(ffa_dev);
++ if (!ffa_ops) {
++ dev_dbg(&ffa_dev->dev, "ffa_dev_ops_get: failed\n");
++ return -ENOENT;
++ }
++
++ /* check ffa driver version compatibility */
++ ffa_drv_version = ffa_ops->api_version_get();
++ if (TO_TRUSTY_FFA_MAJOR(ffa_drv_version) != TRUSTY_FFA_VERSION_MAJOR ||
++ TO_TRUSTY_FFA_MINOR(ffa_drv_version) < TRUSTY_FFA_VERSION_MINOR)
++ return -EINVAL;
++
++ s = kzalloc(sizeof(*s), GFP_KERNEL);
++ if (!s)
++ return -ENOMEM;
++
++ s->dev = &ffa_dev->dev;
++ s->ops = ffa_ops;
++ mutex_init(&s->share_memory_msg_lock);
++ ffa_dev_set_drvdata(ffa_dev, s);
++
++ ffa_ops->mode_32bit_set(ffa_dev);
++
++ return 0;
++}
++
++static void trusty_ffa_remove(struct ffa_device *ffa_dev)
++{
++ struct trusty_ffa_state *s;
++
++ s = ffa_dev_get_drvdata(ffa_dev);
++
++ mutex_destroy(&s->share_memory_msg_lock);
++ memset(s, 0, sizeof(struct trusty_ffa_state));
++ kfree(s);
++}
++
++static struct ffa_driver trusty_ffa_driver = {
++ .name = "trusty-ffa",
++ .probe = trusty_ffa_probe,
++ .remove = trusty_ffa_remove,
++ .id_table = trusty_ffa_device_id,
++};
++
++static int __init trusty_ffa_transport_init(void)
++{
++ if (IS_REACHABLE(CONFIG_ARM_FFA_TRANSPORT)) {
++ return ffa_register(&trusty_ffa_driver);
++ } else
++ return -ENODEV;
++}
++
++static void __exit trusty_ffa_transport_exit(void)
++{
++ if (IS_REACHABLE(CONFIG_ARM_FFA_TRANSPORT))
++ ffa_unregister(&trusty_ffa_driver);
++}
++
++const struct trusty_transport_desc trusty_ffa_transport = {
++ .name = "ffa",
++ .setup = trusty_ffa_transport_setup,
++ .cleanup = trusty_ffa_transport_cleanup,
++};
++
++module_init(trusty_ffa_transport_init);
++module_exit(trusty_ffa_transport_exit);
+diff --git a/drivers/trusty/trusty-ffa.h b/drivers/trusty/trusty-ffa.h
+new file mode 100644
+index 000000000000..267ca2c5db29
+--- /dev/null
++++ b/drivers/trusty/trusty-ffa.h
+@@ -0,0 +1,28 @@
++/* SPDX-License-Identifier: GPL-2.0-only */
++/*
++ * Copyright (C) 2022 ARM Ltd.
++ */
++
++#ifndef __LINUX_TRUSTY_FFA_H
++#define __LINUX_TRUSTY_FFA_H
++
++#include <linux/types.h>
++#include <linux/uuid.h>
++#include <linux/arm_ffa.h>
++
++#define TRUSTY_FFA_VERSION_MAJOR (1U)
++#define TRUSTY_FFA_VERSION_MINOR (0U)
++#define TRUSTY_FFA_VERSION_MAJOR_SHIFT (16U)
++#define TRUSTY_FFA_VERSION_MAJOR_MASK (0x7fffU)
++#define TRUSTY_FFA_VERSION_MINOR_SHIFT (0U)
++#define TRUSTY_FFA_VERSION_MINOR_MASK (0U)
++
++#define TO_TRUSTY_FFA_MAJOR(v) \
++ ((u16)((v >> TRUSTY_FFA_VERSION_MAJOR_SHIFT) & \
++ TRUSTY_FFA_VERSION_MAJOR_MASK))
++
++#define TO_TRUSTY_FFA_MINOR(v) \
++ ((u16)((v >> TRUSTY_FFA_VERSION_MINOR_SHIFT) & \
++ TRUSTY_FFA_VERSION_MINOR_MASK))
++
++#endif /* __LINUX_TRUSTY_FFA_H */
+diff --git a/drivers/trusty/trusty-private.h b/drivers/trusty/trusty-private.h
+index 74b88bb8f83b..2496f397e5d2 100644
+--- a/drivers/trusty/trusty-private.h
++++ b/drivers/trusty/trusty-private.h
+@@ -73,5 +73,6 @@ int trusty_init_api_version(struct trusty_state *s, struct device *dev,
+ typedef const struct trusty_transport_desc *trusty_transports_t;
+
+ extern const struct trusty_transport_desc trusty_smc_transport;
++extern const struct trusty_transport_desc trusty_ffa_transport;
+
+ #endif /* _TRUSTY_PRIVATE_H */
+diff --git a/drivers/trusty/trusty.c b/drivers/trusty/trusty.c
+index ec0fccfaa24c..4686b0d34f61 100644
+--- a/drivers/trusty/trusty.c
++++ b/drivers/trusty/trusty.c
+@@ -509,6 +509,11 @@ trusty_transports_setup(const trusty_transports_t *transports,
+ return -EINVAL;
+
+ ret = transport->setup(dev);
++ if (ret == -EPROBE_DEFER) {
++ dev_notice(dev, "transport %s: defer probe\n",
++ transport->name);
++ return ret;
++ }
+ transports_ret &= ret;
+ }
+
+@@ -672,6 +677,7 @@ static int trusty_remove(struct platform_device *pdev)
+ */
+ static const trusty_transports_t trusty_transports[] = {
+ &trusty_smc_transport,
++ &trusty_ffa_transport,
+ NULL,
+ };
+
+--
+2.34.1
+