blob: 53c76be5ca56b884c50a071e95c962780a31c7e9 [file] [log] [blame]
Brad Bishopbec4ebc2022-08-03 09:55:16 -04001From 27248b5c8cb5c1a59b08e46eb3ab918867282c1c Mon Sep 17 00:00:00 2001
2From: Arunachalam Ganapathy <arunachalam.ganapathy@arm.com>
3Date: Fri, 14 Jan 2022 17:52:33 +0000
4Subject: [PATCH 27/32] ANDROID: trusty: Add transport descriptor
5
6Use transport descriptor to hold transport specific operations. This
7helps to add new transport to Trusty core.
8
9Signed-off-by: Arunachalam Ganapathy <arunachalam.ganapathy@arm.com>
10Change-Id: Ibbde50de0302f6d259a7d572f0910067ce712b37
11Upstream-Status: Pending [Not submitted to upstream yet]
12---
13 drivers/trusty/trusty-private.h | 20 +++++++++-
14 drivers/trusty/trusty-smc.c | 6 +++
15 drivers/trusty/trusty.c | 71 ++++++++++++++++++++++++++++++---
16 3 files changed, 90 insertions(+), 7 deletions(-)
17
18diff --git a/drivers/trusty/trusty-private.h b/drivers/trusty/trusty-private.h
19index 4d73c6ae35d4..74b88bb8f83b 100644
20--- a/drivers/trusty/trusty-private.h
21+++ b/drivers/trusty/trusty-private.h
22@@ -14,12 +14,14 @@ struct trusty_work {
23 };
24
25 struct trusty_msg_ops {
26+ const struct trusty_transport_desc *desc;
27 u32 (*send_direct_msg)(struct device *dev, unsigned long fid,
28 unsigned long a0, unsigned long a1,
29 unsigned long a2);
30 };
31
32 struct trusty_mem_ops {
33+ const struct trusty_transport_desc *desc;
34 int (*trusty_share_memory)(struct device *dev, u64 *id,
35 struct scatterlist *sglist,
36 unsigned int nents, pgprot_t pgprot, u64 tag);
37@@ -46,6 +48,19 @@ struct trusty_state {
38 struct device_dma_parameters dma_parms;
39 const struct trusty_msg_ops *msg_ops;
40 const struct trusty_mem_ops *mem_ops;
41+ struct trusty_ffa_state *ffa;
42+};
43+
44+struct trusty_ffa_state {
45+ struct device *dev; /* ffa device */
46+ const struct ffa_dev_ops *ops;
47+ struct mutex share_memory_msg_lock; /* protects share_memory_msg */
48+};
49+
50+struct trusty_transport_desc {
51+ const char *name;
52+ int (*setup)(struct device *dev);
53+ void (*cleanup)(struct device *dev);
54 };
55
56 int trusty_init_api_version(struct trusty_state *s, struct device *dev,
57@@ -55,7 +70,8 @@ int trusty_init_api_version(struct trusty_state *s, struct device *dev,
58 unsigned long a1,
59 unsigned long a2));
60
61-int trusty_smc_transport_setup(struct device *dev);
62-void trusty_smc_transport_cleanup(struct device *dev);
63+typedef const struct trusty_transport_desc *trusty_transports_t;
64+
65+extern const struct trusty_transport_desc trusty_smc_transport;
66
67 #endif /* _TRUSTY_PRIVATE_H */
68diff --git a/drivers/trusty/trusty-smc.c b/drivers/trusty/trusty-smc.c
69index 8fa841e0e253..62d1d7060744 100644
70--- a/drivers/trusty/trusty-smc.c
71+++ b/drivers/trusty/trusty-smc.c
72@@ -134,3 +134,9 @@ void trusty_smc_transport_cleanup(struct device *dev)
73 if (s->mem_ops == &trusty_smc_mem_ops)
74 s->mem_ops = NULL;
75 }
76+
77+const struct trusty_transport_desc trusty_smc_transport = {
78+ .name = "smc",
79+ .setup = trusty_smc_transport_setup,
80+ .cleanup = trusty_smc_transport_cleanup,
81+};
82diff --git a/drivers/trusty/trusty.c b/drivers/trusty/trusty.c
83index 757dd7b2c527..ec0fccfaa24c 100644
84--- a/drivers/trusty/trusty.c
85+++ b/drivers/trusty/trusty.c
86@@ -493,6 +493,46 @@ void trusty_dequeue_nop(struct device *dev, struct trusty_nop *nop)
87 }
88 EXPORT_SYMBOL(trusty_dequeue_nop);
89
90+static int
91+trusty_transports_setup(const trusty_transports_t *transports,
92+ struct device *dev)
93+{
94+ const struct trusty_transport_desc *transport;
95+ int ret;
96+ int transports_ret = -ENODEV;
97+
98+ if (!transports)
99+ return -EINVAL;
100+
101+ for (; (transport = *transports); transports++) {
102+ if (!transport->setup)
103+ return -EINVAL;
104+
105+ ret = transport->setup(dev);
106+ transports_ret &= ret;
107+ }
108+
109+ /* One transport needs to complete setup without error. */
110+ if (transports_ret < 0)
111+ return -ENODEV;
112+
113+ return 0;
114+}
115+
116+static void
117+trusty_transports_cleanup(const trusty_transports_t *transports,
118+ struct device *dev)
119+{
120+ const struct trusty_transport_desc *transport;
121+
122+ for (; (transport = *transports); transports++) {
123+ if (!transport->cleanup)
124+ continue;
125+
126+ transport->cleanup(dev);
127+ }
128+}
129+
130 static int trusty_probe(struct platform_device *pdev)
131 {
132 int ret;
133@@ -500,6 +540,7 @@ static int trusty_probe(struct platform_device *pdev)
134 work_func_t work_func;
135 struct trusty_state *s;
136 struct device_node *node = pdev->dev.of_node;
137+ const trusty_transports_t *descs;
138
139 if (!node) {
140 dev_err(&pdev->dev, "of_node required\n");
141@@ -529,8 +570,12 @@ static int trusty_probe(struct platform_device *pdev)
142
143 platform_set_drvdata(pdev, s);
144
145- /* Initialize SMC transport */
146- ret = trusty_smc_transport_setup(s->dev);
147+ /*
148+ * Initialize Trusty transport. Trusty msg and mem ops has to be
149+ * initialized as part of transport setup.
150+ */
151+ descs = of_device_get_match_data(&pdev->dev);
152+ ret = trusty_transports_setup(descs, s->dev);
153 if (ret != 0 || s->msg_ops == NULL || s->mem_ops == NULL)
154 goto err_transport_setup;
155
156@@ -581,7 +626,7 @@ static int trusty_probe(struct platform_device *pdev)
157 destroy_workqueue(s->nop_wq);
158 err_create_nop_wq:
159 kfree(s->version_str);
160- trusty_smc_transport_cleanup(s->dev);
161+ trusty_transports_cleanup(descs, s->dev);
162 err_transport_setup:
163 s->dev->dma_parms = NULL;
164 device_for_each_child(&pdev->dev, NULL, trusty_remove_child);
165@@ -595,6 +640,7 @@ static int trusty_remove(struct platform_device *pdev)
166 {
167 unsigned int cpu;
168 struct trusty_state *s = platform_get_drvdata(pdev);
169+ const trusty_transports_t *descs;
170
171 device_for_each_child(&pdev->dev, NULL, trusty_remove_child);
172
173@@ -606,7 +652,10 @@ static int trusty_remove(struct platform_device *pdev)
174 free_percpu(s->nop_works);
175 destroy_workqueue(s->nop_wq);
176
177- trusty_smc_transport_cleanup(s->dev);
178+ /* call transport cleanup */
179+ descs = of_device_get_match_data(&pdev->dev);
180+ trusty_transports_cleanup(descs, s->dev);
181+
182 mutex_destroy(&s->smc_lock);
183 s->dev->dma_parms = NULL;
184 kfree(s->version_str);
185@@ -614,8 +663,20 @@ static int trusty_remove(struct platform_device *pdev)
186 return 0;
187 }
188
189+/*
190+ * Trusty probe will try all compiled in transports and will use the transport
191+ * supported by the Trusty kernel.
192+ *
193+ * For Trusty API version < TRUSTY_API_VERSION_MEM_OBJ:
194+ * trusty_smc_transport used for messaging.
195+ */
196+static const trusty_transports_t trusty_transports[] = {
197+ &trusty_smc_transport,
198+ NULL,
199+};
200+
201 static const struct of_device_id trusty_of_match[] = {
202- { .compatible = "android,trusty-v1", },
203+ { .compatible = "android,trusty-v1", .data = trusty_transports },
204 {},
205 };
206
207--
2082.30.2
209