• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (C) 2019-2021 Linaro Ltd.
4  */
5 
6 #include <linux/io.h>
7 #include <linux/of.h>
8 #include <linux/of_address.h>
9 #include <linux/kernel.h>
10 #include <linux/module.h>
11 #include <linux/mutex.h>
12 #include <linux/slab.h>
13 #include <linux/tee_drv.h>
14 #include <linux/uuid.h>
15 #include <uapi/linux/tee.h>
16 
17 #include "common.h"
18 
19 #define SCMI_OPTEE_MAX_MSG_SIZE		128
20 
21 enum scmi_optee_pta_cmd {
22 	/*
23 	 * PTA_SCMI_CMD_CAPABILITIES - Get channel capabilities
24 	 *
25 	 * [out]    value[0].a: Capability bit mask (enum pta_scmi_caps)
26 	 * [out]    value[0].b: Extended capabilities or 0
27 	 */
28 	PTA_SCMI_CMD_CAPABILITIES = 0,
29 
30 	/*
31 	 * PTA_SCMI_CMD_PROCESS_SMT_CHANNEL - Process SCMI message in SMT buffer
32 	 *
33 	 * [in]     value[0].a: Channel handle
34 	 *
35 	 * Shared memory used for SCMI message/response exhange is expected
36 	 * already identified and bound to channel handle in both SCMI agent
37 	 * and SCMI server (OP-TEE) parts.
38 	 * The memory uses SMT header to carry SCMI meta-data (protocol ID and
39 	 * protocol message ID).
40 	 */
41 	PTA_SCMI_CMD_PROCESS_SMT_CHANNEL = 1,
42 
43 	/*
44 	 * PTA_SCMI_CMD_PROCESS_SMT_CHANNEL_MESSAGE - Process SMT/SCMI message
45 	 *
46 	 * [in]     value[0].a: Channel handle
47 	 * [in/out] memref[1]: Message/response buffer (SMT and SCMI payload)
48 	 *
49 	 * Shared memory used for SCMI message/response is a SMT buffer
50 	 * referenced by param[1]. It shall be 128 bytes large to fit response
51 	 * payload whatever message playload size.
52 	 * The memory uses SMT header to carry SCMI meta-data (protocol ID and
53 	 * protocol message ID).
54 	 */
55 	PTA_SCMI_CMD_PROCESS_SMT_CHANNEL_MESSAGE = 2,
56 
57 	/*
58 	 * PTA_SCMI_CMD_GET_CHANNEL - Get channel handle
59 	 *
60 	 * SCMI shm information are 0 if agent expects to use OP-TEE regular SHM
61 	 *
62 	 * [in]     value[0].a: Channel identifier
63 	 * [out]    value[0].a: Returned channel handle
64 	 * [in]     value[0].b: Requested capabilities mask (enum pta_scmi_caps)
65 	 */
66 	PTA_SCMI_CMD_GET_CHANNEL = 3,
67 
68 	/*
69 	 * PTA_SCMI_CMD_PROCESS_MSG_CHANNEL - Process SCMI message in a MSG
70 	 * buffer pointed by memref parameters
71 	 *
72 	 * [in]     value[0].a: Channel handle
73 	 * [in]     memref[1]: Message buffer (MSG and SCMI payload)
74 	 * [out]    memref[2]: Response buffer (MSG and SCMI payload)
75 	 *
76 	 * Shared memories used for SCMI message/response are MSG buffers
77 	 * referenced by param[1] and param[2]. MSG transport protocol
78 	 * uses a 32bit header to carry SCMI meta-data (protocol ID and
79 	 * protocol message ID) followed by the effective SCMI message
80 	 * payload.
81 	 */
82 	PTA_SCMI_CMD_PROCESS_MSG_CHANNEL = 4,
83 };
84 
85 /*
86  * OP-TEE SCMI service capabilities bit flags (32bit)
87  *
88  * PTA_SCMI_CAPS_SMT_HEADER
89  * When set, OP-TEE supports command using SMT header protocol (SCMI shmem) in
90  * shared memory buffers to carry SCMI protocol synchronisation information.
91  *
92  * PTA_SCMI_CAPS_MSG_HEADER
93  * When set, OP-TEE supports command using MSG header protocol in an OP-TEE
94  * shared memory to carry SCMI protocol synchronisation information and SCMI
95  * message payload.
96  */
97 #define PTA_SCMI_CAPS_NONE		0
98 #define PTA_SCMI_CAPS_SMT_HEADER	BIT(0)
99 #define PTA_SCMI_CAPS_MSG_HEADER	BIT(1)
100 #define PTA_SCMI_CAPS_MASK		(PTA_SCMI_CAPS_SMT_HEADER | \
101 					 PTA_SCMI_CAPS_MSG_HEADER)
102 
103 /**
104  * struct scmi_optee_channel - Description of an OP-TEE SCMI channel
105  *
106  * @channel_id: OP-TEE channel ID used for this transport
107  * @tee_session: TEE session identifier
108  * @caps: OP-TEE SCMI channel capabilities
109  * @rx_len: Response size
110  * @mu: Mutex protection on channel access
111  * @cinfo: SCMI channel information
112  * @shmem: Virtual base address of the shared memory
113  * @req: Shared memory protocol handle for SCMI request and synchronous response
114  * @tee_shm: TEE shared memory handle @req or NULL if using IOMEM shmem
115  * @link: Reference in agent's channel list
116  */
117 struct scmi_optee_channel {
118 	u32 channel_id;
119 	u32 tee_session;
120 	u32 caps;
121 	u32 rx_len;
122 	struct mutex mu;
123 	struct scmi_chan_info *cinfo;
124 	union {
125 		struct scmi_shared_mem __iomem *shmem;
126 		struct scmi_msg_payld *msg;
127 	} req;
128 	struct tee_shm *tee_shm;
129 	struct list_head link;
130 };
131 
132 /**
133  * struct scmi_optee_agent - OP-TEE transport private data
134  *
135  * @dev: Device used for communication with TEE
136  * @tee_ctx: TEE context used for communication
137  * @caps: Supported channel capabilities
138  * @mu: Mutex for protection of @channel_list
139  * @channel_list: List of all created channels for the agent
140  */
141 struct scmi_optee_agent {
142 	struct device *dev;
143 	struct tee_context *tee_ctx;
144 	u32 caps;
145 	struct mutex mu;
146 	struct list_head channel_list;
147 };
148 
149 /* There can be only 1 SCMI service in OP-TEE we connect to */
150 static struct scmi_optee_agent *scmi_optee_private;
151 
152 /* Forward reference to scmi_optee transport initialization */
153 static int scmi_optee_init(void);
154 
155 /* Open a session toward SCMI OP-TEE service with REE_KERNEL identity */
open_session(struct scmi_optee_agent * agent,u32 * tee_session)156 static int open_session(struct scmi_optee_agent *agent, u32 *tee_session)
157 {
158 	struct device *dev = agent->dev;
159 	struct tee_client_device *scmi_pta = to_tee_client_device(dev);
160 	struct tee_ioctl_open_session_arg arg = { };
161 	int ret;
162 
163 	memcpy(arg.uuid, scmi_pta->id.uuid.b, TEE_IOCTL_UUID_LEN);
164 	arg.clnt_login = TEE_IOCTL_LOGIN_REE_KERNEL;
165 
166 	ret = tee_client_open_session(agent->tee_ctx, &arg, NULL);
167 	if (ret < 0 || arg.ret) {
168 		dev_err(dev, "Can't open tee session: %d / %#x\n", ret, arg.ret);
169 		return -EOPNOTSUPP;
170 	}
171 
172 	*tee_session = arg.session;
173 
174 	return 0;
175 }
176 
close_session(struct scmi_optee_agent * agent,u32 tee_session)177 static void close_session(struct scmi_optee_agent *agent, u32 tee_session)
178 {
179 	tee_client_close_session(agent->tee_ctx, tee_session);
180 }
181 
get_capabilities(struct scmi_optee_agent * agent)182 static int get_capabilities(struct scmi_optee_agent *agent)
183 {
184 	struct tee_ioctl_invoke_arg arg = { };
185 	struct tee_param param[1] = { };
186 	u32 caps;
187 	u32 tee_session;
188 	int ret;
189 
190 	ret = open_session(agent, &tee_session);
191 	if (ret)
192 		return ret;
193 
194 	arg.func = PTA_SCMI_CMD_CAPABILITIES;
195 	arg.session = tee_session;
196 	arg.num_params = 1;
197 
198 	param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT;
199 
200 	ret = tee_client_invoke_func(agent->tee_ctx, &arg, param);
201 
202 	close_session(agent, tee_session);
203 
204 	if (ret < 0 || arg.ret) {
205 		dev_err(agent->dev, "Can't get capabilities: %d / %#x\n", ret, arg.ret);
206 		return -EOPNOTSUPP;
207 	}
208 
209 	caps = param[0].u.value.a;
210 
211 	if (!(caps & (PTA_SCMI_CAPS_SMT_HEADER | PTA_SCMI_CAPS_MSG_HEADER))) {
212 		dev_err(agent->dev, "OP-TEE SCMI PTA doesn't support SMT and MSG\n");
213 		return -EOPNOTSUPP;
214 	}
215 
216 	agent->caps = caps;
217 
218 	return 0;
219 }
220 
get_channel(struct scmi_optee_channel * channel)221 static int get_channel(struct scmi_optee_channel *channel)
222 {
223 	struct device *dev = scmi_optee_private->dev;
224 	struct tee_ioctl_invoke_arg arg = { };
225 	struct tee_param param[1] = { };
226 	unsigned int caps = 0;
227 	int ret;
228 
229 	if (channel->tee_shm)
230 		caps = PTA_SCMI_CAPS_MSG_HEADER;
231 	else
232 		caps = PTA_SCMI_CAPS_SMT_HEADER;
233 
234 	arg.func = PTA_SCMI_CMD_GET_CHANNEL;
235 	arg.session = channel->tee_session;
236 	arg.num_params = 1;
237 
238 	param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INOUT;
239 	param[0].u.value.a = channel->channel_id;
240 	param[0].u.value.b = caps;
241 
242 	ret = tee_client_invoke_func(scmi_optee_private->tee_ctx, &arg, param);
243 
244 	if (ret || arg.ret) {
245 		dev_err(dev, "Can't get channel with caps %#x: %d / %#x\n", caps, ret, arg.ret);
246 		return -EOPNOTSUPP;
247 	}
248 
249 	/* From now on use channel identifer provided by OP-TEE SCMI service */
250 	channel->channel_id = param[0].u.value.a;
251 	channel->caps = caps;
252 
253 	return 0;
254 }
255 
invoke_process_smt_channel(struct scmi_optee_channel * channel)256 static int invoke_process_smt_channel(struct scmi_optee_channel *channel)
257 {
258 	struct tee_ioctl_invoke_arg arg = {
259 		.func = PTA_SCMI_CMD_PROCESS_SMT_CHANNEL,
260 		.session = channel->tee_session,
261 		.num_params = 1,
262 	};
263 	struct tee_param param[1] = { };
264 	int ret;
265 
266 	param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT;
267 	param[0].u.value.a = channel->channel_id;
268 
269 	ret = tee_client_invoke_func(scmi_optee_private->tee_ctx, &arg, param);
270 	if (ret < 0 || arg.ret) {
271 		dev_err(scmi_optee_private->dev, "Can't invoke channel %u: %d / %#x\n",
272 			channel->channel_id, ret, arg.ret);
273 		return -EIO;
274 	}
275 
276 	return 0;
277 }
278 
invoke_process_msg_channel(struct scmi_optee_channel * channel,size_t msg_size)279 static int invoke_process_msg_channel(struct scmi_optee_channel *channel, size_t msg_size)
280 {
281 	struct tee_ioctl_invoke_arg arg = {
282 		.func = PTA_SCMI_CMD_PROCESS_MSG_CHANNEL,
283 		.session = channel->tee_session,
284 		.num_params = 3,
285 	};
286 	struct tee_param param[3] = { };
287 	int ret;
288 
289 	param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT;
290 	param[0].u.value.a = channel->channel_id;
291 
292 	param[1].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT;
293 	param[1].u.memref.shm = channel->tee_shm;
294 	param[1].u.memref.size = msg_size;
295 
296 	param[2].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT;
297 	param[2].u.memref.shm = channel->tee_shm;
298 	param[2].u.memref.size = SCMI_OPTEE_MAX_MSG_SIZE;
299 
300 	ret = tee_client_invoke_func(scmi_optee_private->tee_ctx, &arg, param);
301 	if (ret < 0 || arg.ret) {
302 		dev_err(scmi_optee_private->dev, "Can't invoke channel %u: %d / %#x\n",
303 			channel->channel_id, ret, arg.ret);
304 		return -EIO;
305 	}
306 
307 	/* Save response size */
308 	channel->rx_len = param[2].u.memref.size;
309 
310 	return 0;
311 }
312 
scmi_optee_link_supplier(struct device * dev)313 static int scmi_optee_link_supplier(struct device *dev)
314 {
315 	if (!scmi_optee_private) {
316 		if (scmi_optee_init())
317 			dev_dbg(dev, "Optee bus not yet ready\n");
318 
319 		/* Wait for optee bus */
320 		return -EPROBE_DEFER;
321 	}
322 
323 	if (!device_link_add(dev, scmi_optee_private->dev, DL_FLAG_AUTOREMOVE_CONSUMER)) {
324 		dev_err(dev, "Adding link to supplier optee device failed\n");
325 		return -ECANCELED;
326 	}
327 
328 	return 0;
329 }
330 
scmi_optee_chan_available(struct device_node * of_node,int idx)331 static bool scmi_optee_chan_available(struct device_node *of_node, int idx)
332 {
333 	u32 channel_id;
334 
335 	return !of_property_read_u32_index(of_node, "linaro,optee-channel-id",
336 					   idx, &channel_id);
337 }
338 
scmi_optee_clear_channel(struct scmi_chan_info * cinfo)339 static void scmi_optee_clear_channel(struct scmi_chan_info *cinfo)
340 {
341 	struct scmi_optee_channel *channel = cinfo->transport_info;
342 
343 	if (!channel->tee_shm)
344 		shmem_clear_channel(channel->req.shmem);
345 }
346 
setup_dynamic_shmem(struct device * dev,struct scmi_optee_channel * channel)347 static int setup_dynamic_shmem(struct device *dev, struct scmi_optee_channel *channel)
348 {
349 	const size_t msg_size = SCMI_OPTEE_MAX_MSG_SIZE;
350 	void *shbuf;
351 
352 	channel->tee_shm = tee_shm_alloc_kernel_buf(scmi_optee_private->tee_ctx, msg_size);
353 	if (IS_ERR(channel->tee_shm)) {
354 		dev_err(channel->cinfo->dev, "shmem allocation failed\n");
355 		return -ENOMEM;
356 	}
357 
358 	shbuf = tee_shm_get_va(channel->tee_shm, 0);
359 	memset(shbuf, 0, msg_size);
360 	channel->req.msg = shbuf;
361 	channel->rx_len = msg_size;
362 
363 	return 0;
364 }
365 
setup_static_shmem(struct device * dev,struct scmi_chan_info * cinfo,struct scmi_optee_channel * channel)366 static int setup_static_shmem(struct device *dev, struct scmi_chan_info *cinfo,
367 			      struct scmi_optee_channel *channel)
368 {
369 	struct device_node *np;
370 	resource_size_t size;
371 	struct resource res;
372 	int ret;
373 
374 	np = of_parse_phandle(cinfo->dev->of_node, "shmem", 0);
375 	if (!of_device_is_compatible(np, "arm,scmi-shmem")) {
376 		ret = -ENXIO;
377 		goto out;
378 	}
379 
380 	ret = of_address_to_resource(np, 0, &res);
381 	if (ret) {
382 		dev_err(dev, "Failed to get SCMI Tx shared memory\n");
383 		goto out;
384 	}
385 
386 	size = resource_size(&res);
387 
388 	channel->req.shmem = devm_ioremap(dev, res.start, size);
389 	if (!channel->req.shmem) {
390 		dev_err(dev, "Failed to ioremap SCMI Tx shared memory\n");
391 		ret = -EADDRNOTAVAIL;
392 		goto out;
393 	}
394 
395 	ret = 0;
396 
397 out:
398 	of_node_put(np);
399 
400 	return ret;
401 }
402 
setup_shmem(struct device * dev,struct scmi_chan_info * cinfo,struct scmi_optee_channel * channel)403 static int setup_shmem(struct device *dev, struct scmi_chan_info *cinfo,
404 		       struct scmi_optee_channel *channel)
405 {
406 	if (of_property_present(cinfo->dev->of_node, "shmem"))
407 		return setup_static_shmem(dev, cinfo, channel);
408 	else
409 		return setup_dynamic_shmem(dev, channel);
410 }
411 
scmi_optee_chan_setup(struct scmi_chan_info * cinfo,struct device * dev,bool tx)412 static int scmi_optee_chan_setup(struct scmi_chan_info *cinfo, struct device *dev, bool tx)
413 {
414 	struct scmi_optee_channel *channel;
415 	uint32_t channel_id;
416 	int ret;
417 
418 	if (!tx)
419 		return -ENODEV;
420 
421 	channel = devm_kzalloc(dev, sizeof(*channel), GFP_KERNEL);
422 	if (!channel)
423 		return -ENOMEM;
424 
425 	ret = of_property_read_u32_index(cinfo->dev->of_node, "linaro,optee-channel-id",
426 					 0, &channel_id);
427 	if (ret)
428 		return ret;
429 
430 	cinfo->transport_info = channel;
431 	channel->cinfo = cinfo;
432 	channel->channel_id = channel_id;
433 	mutex_init(&channel->mu);
434 
435 	ret = setup_shmem(dev, cinfo, channel);
436 	if (ret)
437 		return ret;
438 
439 	ret = open_session(scmi_optee_private, &channel->tee_session);
440 	if (ret)
441 		goto err_free_shm;
442 
443 	ret = get_channel(channel);
444 	if (ret)
445 		goto err_close_sess;
446 
447 	/* Enable polling */
448 	cinfo->no_completion_irq = true;
449 
450 	mutex_lock(&scmi_optee_private->mu);
451 	list_add(&channel->link, &scmi_optee_private->channel_list);
452 	mutex_unlock(&scmi_optee_private->mu);
453 
454 	return 0;
455 
456 err_close_sess:
457 	close_session(scmi_optee_private, channel->tee_session);
458 err_free_shm:
459 	if (channel->tee_shm)
460 		tee_shm_free(channel->tee_shm);
461 
462 	return ret;
463 }
464 
scmi_optee_chan_free(int id,void * p,void * data)465 static int scmi_optee_chan_free(int id, void *p, void *data)
466 {
467 	struct scmi_chan_info *cinfo = p;
468 	struct scmi_optee_channel *channel = cinfo->transport_info;
469 
470 	mutex_lock(&scmi_optee_private->mu);
471 	list_del(&channel->link);
472 	mutex_unlock(&scmi_optee_private->mu);
473 
474 	close_session(scmi_optee_private, channel->tee_session);
475 
476 	if (channel->tee_shm) {
477 		tee_shm_free(channel->tee_shm);
478 		channel->tee_shm = NULL;
479 	}
480 
481 	cinfo->transport_info = NULL;
482 	channel->cinfo = NULL;
483 
484 	return 0;
485 }
486 
scmi_optee_send_message(struct scmi_chan_info * cinfo,struct scmi_xfer * xfer)487 static int scmi_optee_send_message(struct scmi_chan_info *cinfo,
488 				   struct scmi_xfer *xfer)
489 {
490 	struct scmi_optee_channel *channel = cinfo->transport_info;
491 	int ret;
492 
493 	mutex_lock(&channel->mu);
494 
495 	if (channel->tee_shm) {
496 		msg_tx_prepare(channel->req.msg, xfer);
497 		ret = invoke_process_msg_channel(channel, msg_command_size(xfer));
498 	} else {
499 		shmem_tx_prepare(channel->req.shmem, xfer, cinfo);
500 		ret = invoke_process_smt_channel(channel);
501 	}
502 
503 	if (ret)
504 		mutex_unlock(&channel->mu);
505 
506 	return ret;
507 }
508 
scmi_optee_fetch_response(struct scmi_chan_info * cinfo,struct scmi_xfer * xfer)509 static void scmi_optee_fetch_response(struct scmi_chan_info *cinfo,
510 				      struct scmi_xfer *xfer)
511 {
512 	struct scmi_optee_channel *channel = cinfo->transport_info;
513 
514 	if (channel->tee_shm)
515 		msg_fetch_response(channel->req.msg, channel->rx_len, xfer);
516 	else
517 		shmem_fetch_response(channel->req.shmem, xfer);
518 }
519 
scmi_optee_mark_txdone(struct scmi_chan_info * cinfo,int ret,struct scmi_xfer * __unused)520 static void scmi_optee_mark_txdone(struct scmi_chan_info *cinfo, int ret,
521 				   struct scmi_xfer *__unused)
522 {
523 	struct scmi_optee_channel *channel = cinfo->transport_info;
524 
525 	mutex_unlock(&channel->mu);
526 }
527 
528 static struct scmi_transport_ops scmi_optee_ops = {
529 	.link_supplier = scmi_optee_link_supplier,
530 	.chan_available = scmi_optee_chan_available,
531 	.chan_setup = scmi_optee_chan_setup,
532 	.chan_free = scmi_optee_chan_free,
533 	.send_message = scmi_optee_send_message,
534 	.mark_txdone = scmi_optee_mark_txdone,
535 	.fetch_response = scmi_optee_fetch_response,
536 	.clear_channel = scmi_optee_clear_channel,
537 };
538 
scmi_optee_ctx_match(struct tee_ioctl_version_data * ver,const void * data)539 static int scmi_optee_ctx_match(struct tee_ioctl_version_data *ver, const void *data)
540 {
541 	return ver->impl_id == TEE_IMPL_ID_OPTEE;
542 }
543 
scmi_optee_service_probe(struct device * dev)544 static int scmi_optee_service_probe(struct device *dev)
545 {
546 	struct scmi_optee_agent *agent;
547 	struct tee_context *tee_ctx;
548 	int ret;
549 
550 	/* Only one SCMI OP-TEE device allowed */
551 	if (scmi_optee_private) {
552 		dev_err(dev, "An SCMI OP-TEE device was already initialized: only one allowed\n");
553 		return -EBUSY;
554 	}
555 
556 	tee_ctx = tee_client_open_context(NULL, scmi_optee_ctx_match, NULL, NULL);
557 	if (IS_ERR(tee_ctx))
558 		return -ENODEV;
559 
560 	agent = devm_kzalloc(dev, sizeof(*agent), GFP_KERNEL);
561 	if (!agent) {
562 		ret = -ENOMEM;
563 		goto err;
564 	}
565 
566 	agent->dev = dev;
567 	agent->tee_ctx = tee_ctx;
568 	INIT_LIST_HEAD(&agent->channel_list);
569 	mutex_init(&agent->mu);
570 
571 	ret = get_capabilities(agent);
572 	if (ret)
573 		goto err;
574 
575 	/* Ensure agent resources are all visible before scmi_optee_private is */
576 	smp_mb();
577 	scmi_optee_private = agent;
578 
579 	return 0;
580 
581 err:
582 	tee_client_close_context(tee_ctx);
583 
584 	return ret;
585 }
586 
scmi_optee_service_remove(struct device * dev)587 static int scmi_optee_service_remove(struct device *dev)
588 {
589 	struct scmi_optee_agent *agent = scmi_optee_private;
590 
591 	if (!scmi_optee_private)
592 		return -EINVAL;
593 
594 	if (!list_empty(&scmi_optee_private->channel_list))
595 		return -EBUSY;
596 
597 	/* Ensure cleared reference is visible before resources are released */
598 	smp_store_mb(scmi_optee_private, NULL);
599 
600 	tee_client_close_context(agent->tee_ctx);
601 
602 	return 0;
603 }
604 
605 static const struct tee_client_device_id scmi_optee_service_id[] = {
606 	{
607 		UUID_INIT(0xa8cfe406, 0xd4f5, 0x4a2e,
608 			  0x9f, 0x8d, 0xa2, 0x5d, 0xc7, 0x54, 0xc0, 0x99)
609 	},
610 	{ }
611 };
612 
613 MODULE_DEVICE_TABLE(tee, scmi_optee_service_id);
614 
615 static struct tee_client_driver scmi_optee_driver = {
616 	.id_table	= scmi_optee_service_id,
617 	.driver		= {
618 		.name = "scmi-optee",
619 		.bus = &tee_bus_type,
620 		.probe = scmi_optee_service_probe,
621 		.remove = scmi_optee_service_remove,
622 	},
623 };
624 
scmi_optee_init(void)625 static int scmi_optee_init(void)
626 {
627 	return driver_register(&scmi_optee_driver.driver);
628 }
629 
scmi_optee_exit(void)630 static void scmi_optee_exit(void)
631 {
632 	if (scmi_optee_private)
633 		driver_unregister(&scmi_optee_driver.driver);
634 }
635 
636 const struct scmi_desc scmi_optee_desc = {
637 	.transport_exit = scmi_optee_exit,
638 	.ops = &scmi_optee_ops,
639 	.max_rx_timeout_ms = 30,
640 	.max_msg = 20,
641 	.max_msg_size = SCMI_OPTEE_MAX_MSG_SIZE,
642 	.sync_cmds_completed_on_ret = true,
643 };
644