File Index
Files and directories
Sign in
FILE

rtc-optee.c

File preview with syntax highlighting.

linux-6.19.14/drivers/rtc/rtc-optee.c C
  1// SPDX-License-Identifier: GPL-2.0
  2/*
  3 * Copyright (C) 2022 Microchip.
  4 */
  5
  6#include <linux/device.h>
  7#include <linux/kernel.h>
  8#include <linux/kthread.h>
  9#include <linux/module.h>
 10#include <linux/rtc.h>
 11#include <linux/tee_drv.h>
 12
 13#define RTC_INFO_VERSION			0x1
 14
 15#define TA_RTC_FEATURE_CORRECTION		BIT(0)
 16#define TA_RTC_FEATURE_ALARM			BIT(1)
 17#define TA_RTC_FEATURE_WAKEUP_ALARM		BIT(2)
 18
 19enum rtc_optee_pta_cmd {
 20	/*  PTA_CMD_RTC_GET_INFO - Get RTC information
 21	 *
 22	 * [out]        memref[0]  RTC buffer memory reference containing a struct pta_rtc_info
 23	 */
 24	PTA_CMD_RTC_GET_INF = 0x0,
 25
 26	/*
 27	 * PTA_CMD_RTC_GET_TIME - Get time from RTC
 28	 *
 29	 * [out]    memref[0]  RTC buffer memory reference containing a struct pta_rtc_time
 30	 */
 31	PTA_CMD_RTC_GET_TIME = 0x1,
 32
 33	/*
 34	 * PTA_CMD_RTC_SET_TIME - Set time from RTC
 35	 *
 36	 * [in]     memref[0]  RTC buffer memory reference containing a struct pta_rtc_time to be
 37	 *                     used as RTC time
 38	 */
 39	PTA_CMD_RTC_SET_TIME = 0x2,
 40
 41	/*
 42	 * PTA_CMD_RTC_GET_OFFSET - Get RTC offset
 43	 *
 44	 * [out]    value[0].a  RTC offset (signed 32bit value)
 45	 */
 46	PTA_CMD_RTC_GET_OFFSET = 0x3,
 47
 48	/*
 49	 * PTA_CMD_RTC_SET_OFFSET - Set RTC offset
 50	 *
 51	 * [in]     value[0].a  RTC offset to be set (signed 32bit value)
 52	 */
 53	PTA_CMD_RTC_SET_OFFSET = 0x4,
 54
 55	/*
 56	 * PTA_CMD_RTC_READ_ALARM - Read RTC alarm
 57	 *
 58	 * [out]     memref[0]  RTC buffer memory reference containing a struct pta_rtc_alarm
 59	 */
 60	PTA_CMD_RTC_READ_ALARM = 0x5,
 61
 62	/*
 63	 * PTA_CMD_RTC_SET_ALARM - Set RTC alarm
 64	 *
 65	 * [in]     memref[0]  RTC buffer memory reference containing a struct pta_rtc_alarm to be
 66	 *                     used as RTC alarm
 67	 */
 68	PTA_CMD_RTC_SET_ALARM = 0x6,
 69
 70	/*
 71	 * PTA_CMD_RTC_ENABLE_ALARM - Enable Alarm
 72	 *
 73	 * [in]     value[0].a  RTC IRQ flag (uint32_t), 0 to disable the alarm, 1 to enable
 74	 */
 75	PTA_CMD_RTC_ENABLE_ALARM = 0x7,
 76
 77	/*
 78	 * PTA_CMD_RTC_WAIT_ALARM - Get alarm event
 79	 *
 80	 * [out]     value[0].a  RTC wait alarm return status (uint32_t):
 81	 *                       - 0: No alarm event
 82	 *                       - 1: Alarm event occurred
 83	 *                       - 2: Alarm event canceled
 84	 */
 85	PTA_CMD_RTC_WAIT_ALARM = 0x8,
 86
 87	/*
 88	 * PTA_CMD_RTC_CANCEL_WAIT - Cancel wait for alarm event
 89	 */
 90	PTA_CMD_RTC_CANCEL_WAIT = 0x9,
 91
 92	/*
 93	 * PTA_CMD_RTC_SET_WAKE_ALARM_STATUS - Set RTC wake alarm status flag
 94	 *
 95	 * [in]     value[0].a RTC IRQ wake alarm flag (uint32_t), 0 to disable the wake up
 96	 *                     capability, 1 to enable.
 97	 */
 98	PTA_CMD_RTC_SET_WAKE_ALARM_STATUS = 0xA,
 99};
100
101enum rtc_wait_alarm_status {
102	WAIT_ALARM_RESET = 0x0,
103	WAIT_ALARM_ALARM_OCCURRED = 0x1,
104	WAIT_ALARM_CANCELED = 0x2,
105};
106
107struct optee_rtc_time {
108	u32 tm_sec;
109	u32 tm_min;
110	u32 tm_hour;
111	u32 tm_mday;
112	u32 tm_mon;
113	u32 tm_year;
114	u32 tm_wday;
115};
116
117struct optee_rtc_alarm {
118	u8 enabled;
119	u8 pending;
120	struct optee_rtc_time time;
121};
122
123struct optee_rtc_info {
124	u64 version;
125	u64 features;
126	struct optee_rtc_time range_min;
127	struct optee_rtc_time range_max;
128};
129
130/**
131 * struct optee_rtc - OP-TEE RTC private data
132 * @dev:		OP-TEE based RTC device.
133 * @ctx:		OP-TEE context handler.
134 * @session_id:		RTC TA session identifier.
135 * @session2_id:	RTC wait alarm session identifier.
136 * @shm:		Memory pool shared with RTC device.
137 * @features:		Bitfield of RTC features
138 * @alarm_task:		RTC wait alamr task.
139 * @rtc:		RTC device.
140 */
141struct optee_rtc {
142	struct device *dev;
143	struct tee_context *ctx;
144	u32 session_id;
145	u32 session2_id;
146	struct tee_shm *shm;
147	u64 features;
148	struct task_struct *alarm_task;
149	struct rtc_device *rtc;
150};
151
152static int optee_rtc_readtime(struct device *dev, struct rtc_time *tm)
153{
154	struct optee_rtc *priv = dev_get_drvdata(dev);
155	struct tee_ioctl_invoke_arg inv_arg = {0};
156	struct optee_rtc_time *optee_tm;
157	struct tee_param param[4] = {0};
158	int ret;
159
160	inv_arg.func = PTA_CMD_RTC_GET_TIME;
161	inv_arg.session = priv->session_id;
162	inv_arg.num_params = 4;
163
164	/* Fill invoke cmd params */
165	param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT;
166	param[0].u.memref.shm = priv->shm;
167	param[0].u.memref.size = sizeof(struct optee_rtc_time);
168
169	ret = tee_client_invoke_func(priv->ctx, &inv_arg, param);
170	if (ret < 0 || inv_arg.ret != 0)
171		return ret ? ret : -EPROTO;
172
173	optee_tm = tee_shm_get_va(priv->shm, 0);
174	if (IS_ERR(optee_tm))
175		return PTR_ERR(optee_tm);
176
177	if (param[0].u.memref.size != sizeof(*optee_tm))
178		return -EPROTO;
179
180	tm->tm_sec = optee_tm->tm_sec;
181	tm->tm_min = optee_tm->tm_min;
182	tm->tm_hour = optee_tm->tm_hour;
183	tm->tm_mday = optee_tm->tm_mday;
184	tm->tm_mon = optee_tm->tm_mon;
185	tm->tm_year = optee_tm->tm_year - 1900;
186	tm->tm_wday = optee_tm->tm_wday;
187	tm->tm_yday = rtc_year_days(tm->tm_mday, tm->tm_mon, tm->tm_year);
188
189	return 0;
190}
191
192static int optee_rtc_settime(struct device *dev, struct rtc_time *tm)
193{
194	struct optee_rtc *priv = dev_get_drvdata(dev);
195	struct tee_ioctl_invoke_arg inv_arg = {0};
196	struct tee_param param[4] = {0};
197	struct optee_rtc_time *optee_tm;
198	int ret;
199
200	inv_arg.func = PTA_CMD_RTC_SET_TIME;
201	inv_arg.session = priv->session_id;
202	inv_arg.num_params = 4;
203
204	param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT;
205	param[0].u.memref.shm = priv->shm;
206	param[0].u.memref.size = sizeof(struct optee_rtc_time);
207
208	optee_tm = tee_shm_get_va(priv->shm, 0);
209	if (IS_ERR(optee_tm))
210		return PTR_ERR(optee_tm);
211
212	optee_tm->tm_min = tm->tm_min;
213	optee_tm->tm_sec = tm->tm_sec;
214	optee_tm->tm_hour = tm->tm_hour;
215	optee_tm->tm_mday = tm->tm_mday;
216	optee_tm->tm_mon = tm->tm_mon;
217	optee_tm->tm_year = tm->tm_year + 1900;
218	optee_tm->tm_wday = tm->tm_wday;
219
220	ret = tee_client_invoke_func(priv->ctx, &inv_arg, param);
221	if (ret < 0 || inv_arg.ret != 0)
222		return ret ? ret : -EPROTO;
223
224	return 0;
225}
226
227static int optee_rtc_readoffset(struct device *dev, long *offset)
228{
229	struct optee_rtc *priv = dev_get_drvdata(dev);
230	struct tee_ioctl_invoke_arg inv_arg = {0};
231	struct tee_param param[4] = {0};
232	int ret;
233
234	if (!(priv->features & TA_RTC_FEATURE_CORRECTION))
235		return -EOPNOTSUPP;
236
237	inv_arg.func = PTA_CMD_RTC_GET_OFFSET;
238	inv_arg.session = priv->session_id;
239	inv_arg.num_params = 4;
240
241	param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT;
242
243	ret = tee_client_invoke_func(priv->ctx, &inv_arg, param);
244	if (ret < 0 || inv_arg.ret != 0)
245		return ret ? ret : -EPROTO;
246
247	*offset = param[0].u.value.a;
248
249	return 0;
250}
251
252static int optee_rtc_setoffset(struct device *dev, long offset)
253{
254	struct optee_rtc *priv = dev_get_drvdata(dev);
255	struct tee_ioctl_invoke_arg inv_arg = {0};
256	struct tee_param param[4] = {0};
257	int ret;
258
259	if (!(priv->features & TA_RTC_FEATURE_CORRECTION))
260		return -EOPNOTSUPP;
261
262	inv_arg.func = PTA_CMD_RTC_SET_OFFSET;
263	inv_arg.session = priv->session_id;
264	inv_arg.num_params = 4;
265
266	param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT;
267	param[0].u.value.a = offset;
268
269	ret = tee_client_invoke_func(priv->ctx, &inv_arg, param);
270	if (ret < 0 || inv_arg.ret != 0)
271		return ret ? ret : -EPROTO;
272
273	return 0;
274}
275
276static int optee_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
277{
278	struct optee_rtc *priv = dev_get_drvdata(dev);
279	struct tee_ioctl_invoke_arg inv_arg = {0};
280	struct optee_rtc_alarm *optee_alarm;
281	struct tee_param param[1] = {0};
282	int ret;
283
284	if (!(priv->features & TA_RTC_FEATURE_ALARM))
285		return -EOPNOTSUPP;
286
287	inv_arg.func = PTA_CMD_RTC_READ_ALARM;
288	inv_arg.session = priv->session_id;
289	inv_arg.num_params = 1;
290
291	/* Fill invoke cmd params */
292	param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT;
293	param[0].u.memref.shm = priv->shm;
294	param[0].u.memref.size = sizeof(struct optee_rtc_alarm);
295
296	ret = tee_client_invoke_func(priv->ctx, &inv_arg, param);
297	if (ret < 0 || inv_arg.ret != 0)
298		return ret ? ret : -EPROTO;
299
300	optee_alarm = tee_shm_get_va(priv->shm, 0);
301	if (IS_ERR(optee_alarm))
302		return PTR_ERR(optee_alarm);
303
304	if (param[0].u.memref.size != sizeof(*optee_alarm))
305		return -EPROTO;
306
307	alarm->enabled = optee_alarm->enabled;
308	alarm->pending = optee_alarm->pending;
309	alarm->time.tm_sec = optee_alarm->time.tm_sec;
310	alarm->time.tm_min = optee_alarm->time.tm_min;
311	alarm->time.tm_hour = optee_alarm->time.tm_hour;
312	alarm->time.tm_mday = optee_alarm->time.tm_mday;
313	alarm->time.tm_mon = optee_alarm->time.tm_mon;
314	alarm->time.tm_year = optee_alarm->time.tm_year - 1900;
315	alarm->time.tm_wday = optee_alarm->time.tm_wday;
316	alarm->time.tm_yday = rtc_year_days(alarm->time.tm_mday,
317					    alarm->time.tm_mon,
318					    alarm->time.tm_year);
319
320	return 0;
321}
322
323static int optee_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
324{
325	struct optee_rtc *priv = dev_get_drvdata(dev);
326	struct tee_ioctl_invoke_arg inv_arg = {0};
327	struct optee_rtc_alarm *optee_alarm;
328	struct tee_param param[1] = {0};
329	int ret;
330
331	if (!(priv->features & TA_RTC_FEATURE_ALARM))
332		return -EOPNOTSUPP;
333
334	inv_arg.func = PTA_CMD_RTC_SET_ALARM;
335	inv_arg.session = priv->session_id;
336	inv_arg.num_params = 1;
337
338	param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT;
339	param[0].u.memref.shm = priv->shm;
340	param[0].u.memref.size = sizeof(struct optee_rtc_alarm);
341
342	optee_alarm = tee_shm_get_va(priv->shm, 0);
343	if (IS_ERR(optee_alarm))
344		return PTR_ERR(optee_alarm);
345
346	optee_alarm->enabled = alarm->enabled;
347	optee_alarm->pending = alarm->pending;
348	optee_alarm->time.tm_sec = alarm->time.tm_sec;
349	optee_alarm->time.tm_min = alarm->time.tm_min;
350	optee_alarm->time.tm_hour = alarm->time.tm_hour;
351	optee_alarm->time.tm_mday = alarm->time.tm_mday;
352	optee_alarm->time.tm_mon = alarm->time.tm_mon;
353	optee_alarm->time.tm_year = alarm->time.tm_year + 1900;
354	optee_alarm->time.tm_wday = alarm->time.tm_wday;
355
356	ret = tee_client_invoke_func(priv->ctx, &inv_arg, param);
357	if (ret < 0 || inv_arg.ret != 0)
358		return ret ? ret : -EPROTO;
359
360	return 0;
361}
362
363static int optee_rtc_enable_alarm(struct device *dev, unsigned int enabled)
364{
365	struct optee_rtc *priv = dev_get_drvdata(dev);
366	struct tee_ioctl_invoke_arg inv_arg = {0};
367	struct tee_param param[1] = {0};
368	int ret;
369
370	if (!(priv->features & TA_RTC_FEATURE_ALARM))
371		return -EOPNOTSUPP;
372
373	inv_arg.func = PTA_CMD_RTC_ENABLE_ALARM;
374	inv_arg.session = priv->session_id;
375	inv_arg.num_params = 1;
376
377	param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT;
378	param[0].u.value.a = (bool)enabled;
379
380	ret = tee_client_invoke_func(priv->ctx, &inv_arg, param);
381	if (ret < 0 || inv_arg.ret != 0)
382		return ret ? ret : -EPROTO;
383
384	return 0;
385}
386
387static const struct rtc_class_ops optee_rtc_ops = {
388	.read_time		= optee_rtc_readtime,
389	.set_time		= optee_rtc_settime,
390	.set_offset		= optee_rtc_setoffset,
391	.read_offset		= optee_rtc_readoffset,
392	.read_alarm		= optee_rtc_read_alarm,
393	.set_alarm		= optee_rtc_set_alarm,
394	.alarm_irq_enable	= optee_rtc_enable_alarm,
395};
396
397static int optee_rtc_wait_alarm(struct device *dev, int *return_status)
398{
399	struct optee_rtc *priv = dev_get_drvdata(dev);
400	struct tee_ioctl_invoke_arg inv_arg = {0};
401	struct tee_param param[1] = {0};
402	int ret;
403
404	if (!(priv->features & TA_RTC_FEATURE_ALARM))
405		return -EOPNOTSUPP;
406
407	inv_arg.func = PTA_CMD_RTC_WAIT_ALARM;
408	inv_arg.session = priv->session2_id;
409	inv_arg.num_params = 1;
410
411	param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT;
412
413	ret = tee_client_invoke_func(priv->ctx, &inv_arg, param);
414	if (ret < 0 || inv_arg.ret != 0)
415		return ret ? ret : -EPROTO;
416
417	*return_status = param[0].u.value.a;
418
419	return 0;
420}
421
422static int optee_rtc_cancel_wait_alarm(struct device *dev)
423{
424	struct optee_rtc *priv = dev_get_drvdata(dev);
425	struct tee_ioctl_invoke_arg inv_arg = {0};
426	struct tee_param param[1] = {0};
427	int ret;
428
429	if (!(priv->features & TA_RTC_FEATURE_ALARM))
430		return -EOPNOTSUPP;
431
432	inv_arg.func = PTA_CMD_RTC_CANCEL_WAIT;
433	inv_arg.session = priv->session_id;
434	inv_arg.num_params = 0;
435
436	ret = tee_client_invoke_func(priv->ctx, &inv_arg, param);
437	if (ret < 0 || inv_arg.ret != 0)
438		return ret ? ret : -EPROTO;
439
440	return 0;
441}
442
443static int optee_rtc_set_alarm_wake_status(struct device *dev, bool status)
444{
445	struct optee_rtc *priv = dev_get_drvdata(dev);
446	struct tee_ioctl_invoke_arg inv_arg = {0};
447	struct tee_param param[1] = {0};
448	int ret;
449
450	if (!(priv->features & TA_RTC_FEATURE_ALARM))
451		return -EOPNOTSUPP;
452
453	inv_arg.func = PTA_CMD_RTC_SET_WAKE_ALARM_STATUS;
454	inv_arg.session = priv->session_id;
455	inv_arg.num_params = 1;
456
457	param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT;
458	param[0].u.value.a = status;
459
460	ret = tee_client_invoke_func(priv->ctx, &inv_arg, param);
461
462	if (ret < 0 || inv_arg.ret != 0)
463		return ret ? ret : -EPROTO;
464
465	return 0;
466}
467
468static int optee_rtc_handle_alarm_event(void *data)
469{
470	struct optee_rtc *priv = (struct optee_rtc *)data;
471	int wait_alarm_return_status = 0;
472	int ret;
473
474	while (!kthread_should_stop()) {
475		ret = optee_rtc_wait_alarm(priv->dev, &wait_alarm_return_status);
476		if (ret) {
477			dev_err(priv->dev, "Failed to wait for alarm: %d\n", ret);
478			return ret;
479		}
480		switch (wait_alarm_return_status) {
481		case WAIT_ALARM_ALARM_OCCURRED:
482			dev_dbg(priv->dev, "Alarm occurred\n");
483			rtc_update_irq(priv->rtc, 1, RTC_IRQF | RTC_AF);
484			break;
485		case WAIT_ALARM_CANCELED:
486			dev_dbg(priv->dev, "Alarm canceled\n");
487			break;
488		default:
489			dev_warn(priv->dev, "Unknown return status: %d\n",
490				 wait_alarm_return_status);
491			break;
492		}
493	}
494
495	return 0;
496}
497
498static int optee_rtc_read_info(struct device *dev, struct rtc_device *rtc,
499			       u64 *features)
500{
501	struct optee_rtc *priv = dev_get_drvdata(dev);
502	struct tee_ioctl_invoke_arg inv_arg = {0};
503	struct tee_param param[4] = {0};
504	struct optee_rtc_info *info;
505	struct optee_rtc_time *tm;
506	int ret;
507
508	inv_arg.func = PTA_CMD_RTC_GET_INF;
509	inv_arg.session = priv->session_id;
510	inv_arg.num_params = 4;
511
512	param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT;
513	param[0].u.memref.shm = priv->shm;
514	param[0].u.memref.size = sizeof(*info);
515
516	ret = tee_client_invoke_func(priv->ctx, &inv_arg, param);
517	if (ret < 0 || inv_arg.ret != 0)
518		return ret ? ret : -EPROTO;
519
520	info = tee_shm_get_va(priv->shm, 0);
521	if (IS_ERR(info))
522		return PTR_ERR(info);
523
524	if (param[0].u.memref.size != sizeof(*info))
525		return -EPROTO;
526
527	if (info->version != RTC_INFO_VERSION)
528		return -EPROTO;
529
530	*features = info->features;
531
532	tm = &info->range_min;
533	rtc->range_min = mktime64(tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min,
534				  tm->tm_sec);
535	tm = &info->range_max;
536	rtc->range_max = mktime64(tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min,
537				  tm->tm_sec);
538
539	return 0;
540}
541
542static int optee_ctx_match(struct tee_ioctl_version_data *ver, const void *data)
543{
544	if (ver->impl_id == TEE_IMPL_ID_OPTEE)
545		return 1;
546	else
547		return 0;
548}
549
550static int optee_rtc_probe(struct device *dev)
551{
552	struct tee_client_device *rtc_device = to_tee_client_device(dev);
553	struct tee_ioctl_open_session_arg sess2_arg = {0};
554	struct tee_ioctl_open_session_arg sess_arg = {0};
555	struct optee_rtc *priv;
556	struct rtc_device *rtc;
557	struct tee_shm *shm;
558	int ret, err;
559
560	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
561	if (!priv)
562		return -ENOMEM;
563
564	rtc = devm_rtc_allocate_device(dev);
565	if (IS_ERR(rtc))
566		return PTR_ERR(rtc);
567
568	priv->rtc = rtc;
569
570	/* Open context with TEE driver */
571	priv->ctx = tee_client_open_context(NULL, optee_ctx_match, NULL, NULL);
572	if (IS_ERR(priv->ctx))
573		return -ENODEV;
574
575	/* Open first session with rtc Pseudo Trusted App */
576	export_uuid(sess_arg.uuid, &rtc_device->id.uuid);
577	sess_arg.clnt_login = TEE_IOCTL_LOGIN_REE_KERNEL;
578
579	ret = tee_client_open_session(priv->ctx, &sess_arg, NULL);
580	if (ret < 0 || sess_arg.ret != 0) {
581		dev_err(dev, "tee_client_open_session failed, err: %x\n", sess_arg.ret);
582		err = -EINVAL;
583		goto out_ctx;
584	}
585	priv->session_id = sess_arg.session;
586
587	/*
588	 * Shared memory is used for passing an instance of either struct optee_rtc_info,
589	 * struct optee_rtc_time or struct optee_rtc_alarm to OP-TEE service.
590	 * The former is by definition large enough to cover both parameter cases.
591	 */
592	shm = tee_shm_alloc_kernel_buf(priv->ctx, sizeof(struct optee_rtc_info));
593	if (IS_ERR(shm)) {
594		dev_err(priv->dev, "tee_shm_alloc_kernel_buf failed\n");
595		err = PTR_ERR(shm);
596		goto out_sess;
597	}
598
599	priv->shm = shm;
600	priv->dev = dev;
601	dev_set_drvdata(dev, priv);
602
603	rtc->ops = &optee_rtc_ops;
604
605	err = optee_rtc_read_info(dev, rtc, &priv->features);
606	if (err) {
607		dev_err(dev, "Failed to get RTC features from OP-TEE\n");
608		goto out_shm;
609	}
610
611	/* Handle feature's related setup before registering to rtc framework */
612	if (priv->features & TA_RTC_FEATURE_ALARM) {
613		priv->alarm_task = kthread_create(optee_rtc_handle_alarm_event,
614						  priv, "rtc_alarm_evt");
615		if (IS_ERR(priv->alarm_task)) {
616			dev_err(dev, "Failed to create alarm thread\n");
617			err = PTR_ERR(priv->alarm_task);
618			goto out_shm;
619		}
620
621		/*
622		 * In case of supported alarm feature on optee side, we create a kthread
623		 * that will, in a new optee session, call a PTA interface "rtc_wait_alarm".
624		 * This call return in case of alarm and in case of canceled alarm.
625		 * The new optee session is therefore only needed in this case as we cannot
626		 * use the same session for parallel calls to optee PTA.
627		 * Hence one session is reserved to wait for alarms and the other to make
628		 * standard calls to RTC PTA.
629		 */
630
631		/* Open second session with rtc Trusted App */
632		export_uuid(sess2_arg.uuid, &rtc_device->id.uuid);
633		sess2_arg.clnt_login = TEE_IOCTL_LOGIN_REE_KERNEL;
634
635		ret = tee_client_open_session(priv->ctx, &sess2_arg, NULL);
636		if (ret < 0 || sess2_arg.ret != 0) {
637			dev_err(dev, "tee_client_open_session failed, err: %x\n", sess2_arg.ret);
638			err = -EINVAL;
639			goto out_thrd;
640		}
641		priv->session2_id = sess2_arg.session;
642
643		if (priv->features & TA_RTC_FEATURE_WAKEUP_ALARM)
644			device_init_wakeup(dev, true);
645	}
646
647	err = devm_rtc_register_device(rtc);
648	if (err)
649		goto out_wk;
650
651	/*
652	 * We must clear those bits after registering because registering a rtc_device
653	 * will set them if it sees that .set_offset and .set_alarm are provided.
654	 */
655	if (!(priv->features & TA_RTC_FEATURE_CORRECTION))
656		clear_bit(RTC_FEATURE_CORRECTION, rtc->features);
657	if (!(priv->features & TA_RTC_FEATURE_ALARM))
658		clear_bit(RTC_FEATURE_ALARM, rtc->features);
659
660	/* Start the thread after the rtc is setup */
661	if (priv->alarm_task) {
662		wake_up_process(priv->alarm_task);
663		dev_dbg(dev, "Wait alarm thread successfully started\n");
664	}
665
666	return 0;
667out_wk:
668	if (priv->features & TA_RTC_FEATURE_ALARM) {
669		device_init_wakeup(dev, false);
670		tee_client_close_session(priv->ctx, priv->session2_id);
671	}
672out_thrd:
673	if (priv->features & TA_RTC_FEATURE_ALARM)
674		kthread_stop(priv->alarm_task);
675out_shm:
676	tee_shm_free(priv->shm);
677out_sess:
678	tee_client_close_session(priv->ctx, priv->session_id);
679out_ctx:
680	tee_client_close_context(priv->ctx);
681
682	return err;
683}
684
685static int optee_rtc_remove(struct device *dev)
686{
687	struct optee_rtc *priv = dev_get_drvdata(dev);
688
689	if (priv->features & TA_RTC_FEATURE_ALARM) {
690		optee_rtc_cancel_wait_alarm(dev);
691		kthread_stop(priv->alarm_task);
692		device_init_wakeup(dev, false);
693		tee_client_close_session(priv->ctx, priv->session2_id);
694	}
695
696	tee_shm_free(priv->shm);
697	tee_client_close_session(priv->ctx, priv->session_id);
698	tee_client_close_context(priv->ctx);
699
700	return 0;
701}
702
703static int optee_rtc_suspend(struct device *dev)
704{
705	int res = optee_rtc_set_alarm_wake_status(dev, device_may_wakeup(dev));
706
707	if (res) {
708		dev_err(dev, "Unable to transmit wakeup information to optee rtc\n");
709		return res;
710	}
711
712	return 0;
713}
714
715static DEFINE_SIMPLE_DEV_PM_OPS(optee_rtc_pm_ops, optee_rtc_suspend, NULL);
716
717static const struct tee_client_device_id optee_rtc_id_table[] = {
718	{UUID_INIT(0xf389f8c8, 0x845f, 0x496c,
719		   0x8b, 0xbe, 0xd6, 0x4b, 0xd2, 0x4c, 0x92, 0xfd)},
720	{}
721};
722
723MODULE_DEVICE_TABLE(tee, optee_rtc_id_table);
724
725static struct tee_client_driver optee_rtc_driver = {
726	.id_table	= optee_rtc_id_table,
727	.driver		= {
728		.name		= "optee_rtc",
729		.bus		= &tee_bus_type,
730		.probe		= optee_rtc_probe,
731		.remove		= optee_rtc_remove,
732		.pm		= pm_sleep_ptr(&optee_rtc_pm_ops),
733	},
734};
735
736static int __init optee_rtc_mod_init(void)
737{
738	return driver_register(&optee_rtc_driver.driver);
739}
740
741static void __exit optee_rtc_mod_exit(void)
742{
743	driver_unregister(&optee_rtc_driver.driver);
744}
745
746module_init(optee_rtc_mod_init);
747module_exit(optee_rtc_mod_exit);
748
749MODULE_LICENSE("GPL v2");
750MODULE_AUTHOR("Clément Léger <clement.leger@bootlin.com>");
751MODULE_DESCRIPTION("OP-TEE based RTC driver");
~/ Read-only file preview.