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