blob: a61d2c882ed692ec5bdb16e1eeb6f200dcf4c4ec [file] [log] [blame]
Brad Bishopbec4ebc2022-08-03 09:55:16 -04001From 3104eb14f62df1c7c4b9038eb914514b0ff371dc Mon Sep 17 00:00:00 2001
2From: Arunachalam Ganapathy <arunachalam.ganapathy@arm.com>
3Date: Fri, 14 Jan 2022 18:47:08 +0000
4Subject: [PATCH 28/32] ANDROID: trusty: Add trusty-ffa driver
5
6Initial changes related to FFA transport support
7 - Adds FFA transport descriptor
8 - Defines Trusty UUID
9 - Initializes FFA transport does probe, sets ffa_ops
10 - Defers Trusty probe if ARM FF-A driver is not initialized or
11 Trusty SP not found.
12 - Link FF-A device as the supplier for Trusty platform device.
13
14Signed-off-by: Arunachalam Ganapathy <arunachalam.ganapathy@arm.com>
15Change-Id: I78f72b85c20e4bad4c24cf0826e96f27dcf2ee1d
16Upstream-Status: Pending [Not submitted to upstream yet]
17---
18 drivers/trusty/Makefile | 1 +
19 drivers/trusty/trusty-ffa.c | 196 ++++++++++++++++++++++++++++++++
20 drivers/trusty/trusty-ffa.h | 28 +++++
21 drivers/trusty/trusty-private.h | 1 +
22 drivers/trusty/trusty.c | 6 +
23 5 files changed, 232 insertions(+)
24 create mode 100644 drivers/trusty/trusty-ffa.c
25 create mode 100644 drivers/trusty/trusty-ffa.h
26
27diff --git a/drivers/trusty/Makefile b/drivers/trusty/Makefile
28index fbb53ee93003..797d61bf68ef 100644
29--- a/drivers/trusty/Makefile
30+++ b/drivers/trusty/Makefile
31@@ -6,6 +6,7 @@
32 obj-$(CONFIG_TRUSTY) += trusty-core.o
33 trusty-core-objs += trusty.o trusty-mem.o
34 trusty-core-objs += trusty-smc.o
35+trusty-core-objs += trusty-ffa.o
36 trusty-core-$(CONFIG_ARM) += trusty-smc-arm.o
37 trusty-core-$(CONFIG_ARM64) += trusty-smc-arm64.o
38 obj-$(CONFIG_TRUSTY_IRQ) += trusty-irq.o
39diff --git a/drivers/trusty/trusty-ffa.c b/drivers/trusty/trusty-ffa.c
40new file mode 100644
41index 000000000000..c8c16a1fc700
42--- /dev/null
43+++ b/drivers/trusty/trusty-ffa.c
44@@ -0,0 +1,196 @@
45+/* SPDX-License-Identifier: GPL-2.0-only */
46+/*
47+ * Copyright (C) 2022 ARM Ltd.
48+ */
49+
50+#include <linux/platform_device.h>
51+#include <linux/slab.h>
52+#include <linux/trusty/smcall.h>
53+#include <linux/arm_ffa.h>
54+#include <linux/trusty/trusty.h>
55+
56+#include <linux/scatterlist.h>
57+#include <linux/dma-mapping.h>
58+
59+#include "trusty-ffa.h"
60+#include "trusty-private.h"
61+
62+static const struct trusty_mem_ops trusty_ffa_mem_ops = {
63+ .desc = &trusty_ffa_transport,
64+};
65+
66+static const struct ffa_device_id trusty_ffa_device_id[] = {
67+ /*
68+ * Trusty UID: RFC-4122 compliant UUID version 4
69+ * 40ee25f0-a2bc-304c-8c4ca173c57d8af1
70+ */
71+ { UUID_INIT(0x40ee25f0, 0xa2bc, 0x304c,
72+ 0x8c, 0x4c, 0xa1, 0x73, 0xc5, 0x7d, 0x8a, 0xf1) },
73+ {}
74+};
75+
76+static int trusty_ffa_dev_match(struct device *dev, const void *uuid)
77+{
78+ struct ffa_device *ffa_dev;
79+
80+ ffa_dev = to_ffa_dev(dev);
81+ if (uuid_equal(&ffa_dev->uuid, uuid))
82+ return 1;
83+
84+ return 0;
85+}
86+
87+static struct ffa_device *trusty_ffa_dev_find(void)
88+{
89+ const void *data;
90+ struct device *dev;
91+
92+ /* currently only one trusty instance is probed */
93+ data = &trusty_ffa_device_id[0].uuid;
94+
95+ dev = bus_find_device(&ffa_bus_type, NULL, data, trusty_ffa_dev_match);
96+ if (dev) {
97+ /* drop reference count */
98+ put_device(dev);
99+ return to_ffa_dev(dev);
100+ }
101+
102+ return NULL;
103+}
104+
105+static int trusty_ffa_link_supplier(struct device *c_dev, struct device *s_dev)
106+{
107+ if (!c_dev || !s_dev)
108+ return -EINVAL;
109+
110+ if (!device_link_add(c_dev, s_dev, DL_FLAG_AUTOREMOVE_CONSUMER)) {
111+ return -ENODEV;
112+ }
113+
114+ return 0;
115+}
116+
117+/*
118+ * called from trusty probe
119+ */
120+static int trusty_ffa_transport_setup(struct device *dev)
121+{
122+ int rc;
123+ struct trusty_state *s = platform_get_drvdata(to_platform_device(dev));
124+ struct trusty_ffa_state *ffa_state;
125+ struct ffa_device *ffa_dev;
126+
127+ /* ffa transport not required for lower api versions */
128+ if (s->api_version != 0 && s->api_version < TRUSTY_API_VERSION_MEM_OBJ) {
129+ return -EINVAL;
130+ }
131+
132+ ffa_dev = trusty_ffa_dev_find();
133+ if (!ffa_dev) {
134+ dev_dbg(dev, "FFA: Trusty device not found defer probe\n");
135+ return -EPROBE_DEFER;
136+ }
137+
138+ ffa_state = ffa_dev_get_drvdata(ffa_dev);
139+ if (!ffa_state)
140+ return -EINVAL;
141+
142+ rc = trusty_ffa_link_supplier(dev, &ffa_dev->dev);
143+ if (rc != 0)
144+ return rc;
145+
146+ /* FFA used only for memory sharing operations */
147+ if (s->api_version == TRUSTY_API_VERSION_MEM_OBJ) {
148+ s->ffa = ffa_state;
149+ s->mem_ops = &trusty_ffa_mem_ops;
150+ return 0;
151+ }
152+
153+ return -EINVAL;
154+}
155+
156+static void trusty_ffa_transport_cleanup(struct device *dev)
157+{
158+ struct trusty_state *s = platform_get_drvdata(to_platform_device(dev));
159+
160+ /* ffa transport not setup for lower api versions */
161+ if (s->api_version < TRUSTY_API_VERSION_MEM_OBJ) {
162+ return;
163+ }
164+
165+ s->ffa = NULL;
166+ s->mem_ops = NULL;
167+}
168+
169+static int trusty_ffa_probe(struct ffa_device *ffa_dev)
170+{
171+ const struct ffa_dev_ops *ffa_ops;
172+ struct trusty_ffa_state *s;
173+ u32 ffa_drv_version;
174+
175+ ffa_ops = ffa_dev_ops_get(ffa_dev);
176+ if (!ffa_ops) {
177+ dev_dbg(&ffa_dev->dev, "ffa_dev_ops_get: failed\n");
178+ return -ENOENT;
179+ }
180+
181+ /* check ffa driver version compatibility */
182+ ffa_drv_version = ffa_ops->api_version_get();
183+ if (TO_TRUSTY_FFA_MAJOR(ffa_drv_version) != TRUSTY_FFA_VERSION_MAJOR ||
184+ TO_TRUSTY_FFA_MINOR(ffa_drv_version) < TRUSTY_FFA_VERSION_MINOR)
185+ return -EINVAL;
186+
187+ s = kzalloc(sizeof(*s), GFP_KERNEL);
188+ if (!s)
189+ return -ENOMEM;
190+
191+ s->dev = &ffa_dev->dev;
192+ s->ops = ffa_ops;
193+ mutex_init(&s->share_memory_msg_lock);
194+ ffa_dev_set_drvdata(ffa_dev, s);
195+
196+ ffa_ops->mode_32bit_set(ffa_dev);
197+
198+ return 0;
199+}
200+
201+static void trusty_ffa_remove(struct ffa_device *ffa_dev)
202+{
203+ struct trusty_ffa_state *s;
204+
205+ s = ffa_dev_get_drvdata(ffa_dev);
206+
207+ mutex_destroy(&s->share_memory_msg_lock);
208+ memset(s, 0, sizeof(struct trusty_ffa_state));
209+ kfree(s);
210+}
211+
212+static struct ffa_driver trusty_ffa_driver = {
213+ .name = "trusty-ffa",
214+ .probe = trusty_ffa_probe,
215+ .remove = trusty_ffa_remove,
216+ .id_table = trusty_ffa_device_id,
217+};
218+
219+static int __init trusty_ffa_transport_init(void)
220+{
221+ if (IS_REACHABLE(CONFIG_ARM_FFA_TRANSPORT)) {
222+ return ffa_register(&trusty_ffa_driver);
223+ } else
224+ return -ENODEV;
225+}
226+
227+static void __exit trusty_ffa_transport_exit(void)
228+{
229+ if (IS_REACHABLE(CONFIG_ARM_FFA_TRANSPORT))
230+ ffa_unregister(&trusty_ffa_driver);
231+}
232+
233+const struct trusty_transport_desc trusty_ffa_transport = {
234+ .name = "ffa",
235+ .setup = trusty_ffa_transport_setup,
236+ .cleanup = trusty_ffa_transport_cleanup,
237+};
238+
239+module_init(trusty_ffa_transport_init);
240+module_exit(trusty_ffa_transport_exit);
241diff --git a/drivers/trusty/trusty-ffa.h b/drivers/trusty/trusty-ffa.h
242new file mode 100644
243index 000000000000..267ca2c5db29
244--- /dev/null
245+++ b/drivers/trusty/trusty-ffa.h
246@@ -0,0 +1,28 @@
247+/* SPDX-License-Identifier: GPL-2.0-only */
248+/*
249+ * Copyright (C) 2022 ARM Ltd.
250+ */
251+
252+#ifndef __LINUX_TRUSTY_FFA_H
253+#define __LINUX_TRUSTY_FFA_H
254+
255+#include <linux/types.h>
256+#include <linux/uuid.h>
257+#include <linux/arm_ffa.h>
258+
259+#define TRUSTY_FFA_VERSION_MAJOR (1U)
260+#define TRUSTY_FFA_VERSION_MINOR (0U)
261+#define TRUSTY_FFA_VERSION_MAJOR_SHIFT (16U)
262+#define TRUSTY_FFA_VERSION_MAJOR_MASK (0x7fffU)
263+#define TRUSTY_FFA_VERSION_MINOR_SHIFT (0U)
264+#define TRUSTY_FFA_VERSION_MINOR_MASK (0U)
265+
266+#define TO_TRUSTY_FFA_MAJOR(v) \
267+ ((u16)((v >> TRUSTY_FFA_VERSION_MAJOR_SHIFT) & \
268+ TRUSTY_FFA_VERSION_MAJOR_MASK))
269+
270+#define TO_TRUSTY_FFA_MINOR(v) \
271+ ((u16)((v >> TRUSTY_FFA_VERSION_MINOR_SHIFT) & \
272+ TRUSTY_FFA_VERSION_MINOR_MASK))
273+
274+#endif /* __LINUX_TRUSTY_FFA_H */
275diff --git a/drivers/trusty/trusty-private.h b/drivers/trusty/trusty-private.h
276index 74b88bb8f83b..2496f397e5d2 100644
277--- a/drivers/trusty/trusty-private.h
278+++ b/drivers/trusty/trusty-private.h
279@@ -73,5 +73,6 @@ int trusty_init_api_version(struct trusty_state *s, struct device *dev,
280 typedef const struct trusty_transport_desc *trusty_transports_t;
281
282 extern const struct trusty_transport_desc trusty_smc_transport;
283+extern const struct trusty_transport_desc trusty_ffa_transport;
284
285 #endif /* _TRUSTY_PRIVATE_H */
286diff --git a/drivers/trusty/trusty.c b/drivers/trusty/trusty.c
287index ec0fccfaa24c..4686b0d34f61 100644
288--- a/drivers/trusty/trusty.c
289+++ b/drivers/trusty/trusty.c
290@@ -509,6 +509,11 @@ trusty_transports_setup(const trusty_transports_t *transports,
291 return -EINVAL;
292
293 ret = transport->setup(dev);
294+ if (ret == -EPROBE_DEFER) {
295+ dev_notice(dev, "transport %s: defer probe\n",
296+ transport->name);
297+ return ret;
298+ }
299 transports_ret &= ret;
300 }
301
302@@ -672,6 +677,7 @@ static int trusty_remove(struct platform_device *pdev)
303 */
304 static const trusty_transports_t trusty_transports[] = {
305 &trusty_smc_transport,
306+ &trusty_ffa_transport,
307 NULL,
308 };
309
310--
3112.30.2
312