blob: 340e12dc649ca05c4a5596c95a1bef966ef45c9f [file] [log] [blame]
From e7fe12a5a7e3eac7a7d549ef9a7d88e9baba1832 Mon Sep 17 00:00:00 2001
From: Arunachalam Ganapathy <arunachalam.ganapathy@arm.com>
Date: Fri, 14 Jan 2022 17:52:33 +0000
Subject: [PATCH 32/40] ANDROID: trusty: Add transport descriptor
Use transport descriptor to hold transport specific operations. This
helps to add new transport to Trusty core.
Signed-off-by: Arunachalam Ganapathy <arunachalam.ganapathy@arm.com>
Change-Id: Ibbde50de0302f6d259a7d572f0910067ce712b37
Upstream-Status: Pending [Not submitted to upstream yet]
Signed-off-by: Rupinderjit Singh <rupinderjit.singh@arm.com
---
drivers/trusty/trusty-private.h | 20 +++++++++-
drivers/trusty/trusty-smc.c | 6 +++
drivers/trusty/trusty.c | 71 ++++++++++++++++++++++++++++++---
3 files changed, 90 insertions(+), 7 deletions(-)
diff --git a/drivers/trusty/trusty-private.h b/drivers/trusty/trusty-private.h
index 4d73c6ae35d4..74b88bb8f83b 100644
--- a/drivers/trusty/trusty-private.h
+++ b/drivers/trusty/trusty-private.h
@@ -14,12 +14,14 @@ struct trusty_work {
};
struct trusty_msg_ops {
+ const struct trusty_transport_desc *desc;
u32 (*send_direct_msg)(struct device *dev, unsigned long fid,
unsigned long a0, unsigned long a1,
unsigned long a2);
};
struct trusty_mem_ops {
+ const struct trusty_transport_desc *desc;
int (*trusty_share_memory)(struct device *dev, u64 *id,
struct scatterlist *sglist,
unsigned int nents, pgprot_t pgprot, u64 tag);
@@ -46,6 +48,19 @@ struct trusty_state {
struct device_dma_parameters dma_parms;
const struct trusty_msg_ops *msg_ops;
const struct trusty_mem_ops *mem_ops;
+ struct trusty_ffa_state *ffa;
+};
+
+struct trusty_ffa_state {
+ struct device *dev; /* ffa device */
+ const struct ffa_dev_ops *ops;
+ struct mutex share_memory_msg_lock; /* protects share_memory_msg */
+};
+
+struct trusty_transport_desc {
+ const char *name;
+ int (*setup)(struct device *dev);
+ void (*cleanup)(struct device *dev);
};
int trusty_init_api_version(struct trusty_state *s, struct device *dev,
@@ -55,7 +70,8 @@ int trusty_init_api_version(struct trusty_state *s, struct device *dev,
unsigned long a1,
unsigned long a2));
-int trusty_smc_transport_setup(struct device *dev);
-void trusty_smc_transport_cleanup(struct device *dev);
+typedef const struct trusty_transport_desc *trusty_transports_t;
+
+extern const struct trusty_transport_desc trusty_smc_transport;
#endif /* _TRUSTY_PRIVATE_H */
diff --git a/drivers/trusty/trusty-smc.c b/drivers/trusty/trusty-smc.c
index 8fa841e0e253..62d1d7060744 100644
--- a/drivers/trusty/trusty-smc.c
+++ b/drivers/trusty/trusty-smc.c
@@ -134,3 +134,9 @@ void trusty_smc_transport_cleanup(struct device *dev)
if (s->mem_ops == &trusty_smc_mem_ops)
s->mem_ops = NULL;
}
+
+const struct trusty_transport_desc trusty_smc_transport = {
+ .name = "smc",
+ .setup = trusty_smc_transport_setup,
+ .cleanup = trusty_smc_transport_cleanup,
+};
diff --git a/drivers/trusty/trusty.c b/drivers/trusty/trusty.c
index 757dd7b2c527..ec0fccfaa24c 100644
--- a/drivers/trusty/trusty.c
+++ b/drivers/trusty/trusty.c
@@ -493,6 +493,46 @@ void trusty_dequeue_nop(struct device *dev, struct trusty_nop *nop)
}
EXPORT_SYMBOL(trusty_dequeue_nop);
+static int
+trusty_transports_setup(const trusty_transports_t *transports,
+ struct device *dev)
+{
+ const struct trusty_transport_desc *transport;
+ int ret;
+ int transports_ret = -ENODEV;
+
+ if (!transports)
+ return -EINVAL;
+
+ for (; (transport = *transports); transports++) {
+ if (!transport->setup)
+ return -EINVAL;
+
+ ret = transport->setup(dev);
+ transports_ret &= ret;
+ }
+
+ /* One transport needs to complete setup without error. */
+ if (transports_ret < 0)
+ return -ENODEV;
+
+ return 0;
+}
+
+static void
+trusty_transports_cleanup(const trusty_transports_t *transports,
+ struct device *dev)
+{
+ const struct trusty_transport_desc *transport;
+
+ for (; (transport = *transports); transports++) {
+ if (!transport->cleanup)
+ continue;
+
+ transport->cleanup(dev);
+ }
+}
+
static int trusty_probe(struct platform_device *pdev)
{
int ret;
@@ -500,6 +540,7 @@ static int trusty_probe(struct platform_device *pdev)
work_func_t work_func;
struct trusty_state *s;
struct device_node *node = pdev->dev.of_node;
+ const trusty_transports_t *descs;
if (!node) {
dev_err(&pdev->dev, "of_node required\n");
@@ -529,8 +570,12 @@ static int trusty_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, s);
- /* Initialize SMC transport */
- ret = trusty_smc_transport_setup(s->dev);
+ /*
+ * Initialize Trusty transport. Trusty msg and mem ops has to be
+ * initialized as part of transport setup.
+ */
+ descs = of_device_get_match_data(&pdev->dev);
+ ret = trusty_transports_setup(descs, s->dev);
if (ret != 0 || s->msg_ops == NULL || s->mem_ops == NULL)
goto err_transport_setup;
@@ -581,7 +626,7 @@ static int trusty_probe(struct platform_device *pdev)
destroy_workqueue(s->nop_wq);
err_create_nop_wq:
kfree(s->version_str);
- trusty_smc_transport_cleanup(s->dev);
+ trusty_transports_cleanup(descs, s->dev);
err_transport_setup:
s->dev->dma_parms = NULL;
device_for_each_child(&pdev->dev, NULL, trusty_remove_child);
@@ -595,6 +640,7 @@ static int trusty_remove(struct platform_device *pdev)
{
unsigned int cpu;
struct trusty_state *s = platform_get_drvdata(pdev);
+ const trusty_transports_t *descs;
device_for_each_child(&pdev->dev, NULL, trusty_remove_child);
@@ -606,7 +652,10 @@ static int trusty_remove(struct platform_device *pdev)
free_percpu(s->nop_works);
destroy_workqueue(s->nop_wq);
- trusty_smc_transport_cleanup(s->dev);
+ /* call transport cleanup */
+ descs = of_device_get_match_data(&pdev->dev);
+ trusty_transports_cleanup(descs, s->dev);
+
mutex_destroy(&s->smc_lock);
s->dev->dma_parms = NULL;
kfree(s->version_str);
@@ -614,8 +663,20 @@ static int trusty_remove(struct platform_device *pdev)
return 0;
}
+/*
+ * Trusty probe will try all compiled in transports and will use the transport
+ * supported by the Trusty kernel.
+ *
+ * For Trusty API version < TRUSTY_API_VERSION_MEM_OBJ:
+ * trusty_smc_transport used for messaging.
+ */
+static const trusty_transports_t trusty_transports[] = {
+ &trusty_smc_transport,
+ NULL,
+};
+
static const struct of_device_id trusty_of_match[] = {
- { .compatible = "android,trusty-v1", },
+ { .compatible = "android,trusty-v1", .data = trusty_transports },
{},
};
--
2.34.1