Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

rtc: optee: add alarm related rtc ops to optee rtc driver

Add read_alarm and set_alarm ops from the rtc framework.
The support of an alarm is handled by a kernel thread waiting in OP-TEE
for an asynchronous notification that comes in the interrupt
handler of the alarm interruption on OP-TEE secure world.

Once the notification arrives, the kernel thread previously suspended
is rescheduled (this is handled by the OP-TEE kernel driver) and comes
back with the alarm information to the kernel.

A second session is therefore needed to enable/disable/cancel a waiting
alarm event as the kernel thread stopped in OP-TEE takes a form of mutex
on the session and so no one can use this session in parallel.

Signed-off-by: Clément Le Goffic <clement.legoffic@foss.st.com>
Link: https://lore.kernel.org/r/20250715-upstream-optee-rtc-v1-3-e0fdf8aae545@foss.st.com
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>

authored by

Clément Le Goffic and committed by
Alexandre Belloni
6266aea8 44fee00f

+413 -21
+413 -21
drivers/rtc/rtc-optee.c
··· 5 5 6 6 #include <linux/device.h> 7 7 #include <linux/kernel.h> 8 + #include <linux/kthread.h> 8 9 #include <linux/module.h> 9 10 #include <linux/rtc.h> 10 11 #include <linux/tee_drv.h> 11 12 12 - #define RTC_INFO_VERSION 0x1 13 + #define RTC_INFO_VERSION 0x1 13 14 14 - #define TA_CMD_RTC_GET_INFO 0x0 15 - #define TA_CMD_RTC_GET_TIME 0x1 16 - #define TA_CMD_RTC_SET_TIME 0x2 17 - #define TA_CMD_RTC_GET_OFFSET 0x3 18 - #define TA_CMD_RTC_SET_OFFSET 0x4 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) 19 18 20 - #define TA_RTC_FEATURE_CORRECTION BIT(0) 19 + enum 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 + 101 + enum rtc_wait_alarm_status { 102 + WAIT_ALARM_RESET = 0x0, 103 + WAIT_ALARM_ALARM_OCCURRED = 0x1, 104 + WAIT_ALARM_CANCELED = 0x2, 105 + }; 21 106 22 107 struct optee_rtc_time { 23 108 u32 tm_sec; ··· 112 27 u32 tm_mon; 113 28 u32 tm_year; 114 29 u32 tm_wday; 30 + }; 31 + 32 + struct optee_rtc_alarm { 33 + u8 enabled; 34 + u8 pending; 35 + struct optee_rtc_time time; 115 36 }; 116 37 117 38 struct optee_rtc_info { ··· 132 41 * @dev: OP-TEE based RTC device. 133 42 * @ctx: OP-TEE context handler. 134 43 * @session_id: RTC TA session identifier. 44 + * @session2_id: RTC wait alarm session identifier. 135 45 * @shm: Memory pool shared with RTC device. 136 46 * @features: Bitfield of RTC features 47 + * @alarm_task: RTC wait alamr task. 48 + * @rtc: RTC device. 137 49 */ 138 50 struct optee_rtc { 139 51 struct device *dev; 140 52 struct tee_context *ctx; 141 53 u32 session_id; 54 + u32 session2_id; 142 55 struct tee_shm *shm; 143 56 u64 features; 57 + struct task_struct *alarm_task; 58 + struct rtc_device *rtc; 144 59 }; 145 60 146 61 static int optee_rtc_readtime(struct device *dev, struct rtc_time *tm) ··· 157 60 struct tee_param param[4] = {0}; 158 61 int ret; 159 62 160 - inv_arg.func = TA_CMD_RTC_GET_TIME; 63 + inv_arg.func = PTA_CMD_RTC_GET_TIME; 161 64 inv_arg.session = priv->session_id; 162 65 inv_arg.num_params = 4; 163 66 ··· 197 100 struct optee_rtc_time *optee_tm; 198 101 int ret; 199 102 200 - inv_arg.func = TA_CMD_RTC_SET_TIME; 103 + inv_arg.func = PTA_CMD_RTC_SET_TIME; 201 104 inv_arg.session = priv->session_id; 202 105 inv_arg.num_params = 4; 203 106 ··· 234 137 if (!(priv->features & TA_RTC_FEATURE_CORRECTION)) 235 138 return -EOPNOTSUPP; 236 139 237 - inv_arg.func = TA_CMD_RTC_GET_OFFSET; 140 + inv_arg.func = PTA_CMD_RTC_GET_OFFSET; 238 141 inv_arg.session = priv->session_id; 239 142 inv_arg.num_params = 4; 240 143 ··· 259 162 if (!(priv->features & TA_RTC_FEATURE_CORRECTION)) 260 163 return -EOPNOTSUPP; 261 164 262 - inv_arg.func = TA_CMD_RTC_SET_OFFSET; 165 + inv_arg.func = PTA_CMD_RTC_SET_OFFSET; 263 166 inv_arg.session = priv->session_id; 264 167 inv_arg.num_params = 4; 265 168 ··· 273 176 return 0; 274 177 } 275 178 179 + static int optee_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) 180 + { 181 + struct optee_rtc *priv = dev_get_drvdata(dev); 182 + struct tee_ioctl_invoke_arg inv_arg = {0}; 183 + struct optee_rtc_alarm *optee_alarm; 184 + struct tee_param param[1] = {0}; 185 + int ret; 186 + 187 + if (!(priv->features & TA_RTC_FEATURE_ALARM)) 188 + return -EOPNOTSUPP; 189 + 190 + inv_arg.func = PTA_CMD_RTC_READ_ALARM; 191 + inv_arg.session = priv->session_id; 192 + inv_arg.num_params = 1; 193 + 194 + /* Fill invoke cmd params */ 195 + param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_OUTPUT; 196 + param[0].u.memref.shm = priv->shm; 197 + param[0].u.memref.size = sizeof(struct optee_rtc_alarm); 198 + 199 + ret = tee_client_invoke_func(priv->ctx, &inv_arg, param); 200 + if (ret < 0 || inv_arg.ret != 0) 201 + return ret ? ret : -EPROTO; 202 + 203 + optee_alarm = tee_shm_get_va(priv->shm, 0); 204 + if (IS_ERR(optee_alarm)) 205 + return PTR_ERR(alarm); 206 + 207 + if (param[0].u.memref.size != sizeof(*optee_alarm)) 208 + return -EPROTO; 209 + 210 + alarm->enabled = optee_alarm->enabled; 211 + alarm->pending = optee_alarm->pending; 212 + alarm->time.tm_sec = optee_alarm->time.tm_sec; 213 + alarm->time.tm_min = optee_alarm->time.tm_min; 214 + alarm->time.tm_hour = optee_alarm->time.tm_hour; 215 + alarm->time.tm_mday = optee_alarm->time.tm_mday; 216 + alarm->time.tm_mon = optee_alarm->time.tm_mon; 217 + alarm->time.tm_year = optee_alarm->time.tm_year - 1900; 218 + alarm->time.tm_wday = optee_alarm->time.tm_wday; 219 + alarm->time.tm_yday = rtc_year_days(alarm->time.tm_mday, 220 + alarm->time.tm_mon, 221 + alarm->time.tm_year); 222 + 223 + return 0; 224 + } 225 + 226 + static int optee_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) 227 + { 228 + struct optee_rtc *priv = dev_get_drvdata(dev); 229 + struct tee_ioctl_invoke_arg inv_arg = {0}; 230 + struct optee_rtc_alarm *optee_alarm; 231 + struct tee_param param[1] = {0}; 232 + int ret; 233 + 234 + if (!(priv->features & TA_RTC_FEATURE_ALARM)) 235 + return -EOPNOTSUPP; 236 + 237 + inv_arg.func = PTA_CMD_RTC_SET_ALARM; 238 + inv_arg.session = priv->session_id; 239 + inv_arg.num_params = 1; 240 + 241 + param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_MEMREF_INPUT; 242 + param[0].u.memref.shm = priv->shm; 243 + param[0].u.memref.size = sizeof(struct optee_rtc_alarm); 244 + 245 + optee_alarm = tee_shm_get_va(priv->shm, 0); 246 + if (IS_ERR(optee_alarm)) 247 + return PTR_ERR(optee_alarm); 248 + 249 + optee_alarm->enabled = alarm->enabled; 250 + optee_alarm->pending = alarm->pending; 251 + optee_alarm->time.tm_sec = alarm->time.tm_sec; 252 + optee_alarm->time.tm_min = alarm->time.tm_min; 253 + optee_alarm->time.tm_hour = alarm->time.tm_hour; 254 + optee_alarm->time.tm_mday = alarm->time.tm_mday; 255 + optee_alarm->time.tm_mon = alarm->time.tm_mon; 256 + optee_alarm->time.tm_year = alarm->time.tm_year + 1900; 257 + optee_alarm->time.tm_wday = alarm->time.tm_wday; 258 + 259 + ret = tee_client_invoke_func(priv->ctx, &inv_arg, param); 260 + if (ret < 0 || inv_arg.ret != 0) 261 + return ret ? ret : -EPROTO; 262 + 263 + return 0; 264 + } 265 + 266 + static int optee_rtc_enable_alarm(struct device *dev, unsigned int enabled) 267 + { 268 + struct optee_rtc *priv = dev_get_drvdata(dev); 269 + struct tee_ioctl_invoke_arg inv_arg = {0}; 270 + struct tee_param param[1] = {0}; 271 + int ret; 272 + 273 + if (!(priv->features & TA_RTC_FEATURE_ALARM)) 274 + return -EOPNOTSUPP; 275 + 276 + inv_arg.func = PTA_CMD_RTC_ENABLE_ALARM; 277 + inv_arg.session = priv->session_id; 278 + inv_arg.num_params = 1; 279 + 280 + param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT; 281 + param[0].u.value.a = (bool)enabled; 282 + 283 + ret = tee_client_invoke_func(priv->ctx, &inv_arg, param); 284 + if (ret < 0 || inv_arg.ret != 0) 285 + return ret ? ret : -EPROTO; 286 + 287 + return 0; 288 + } 289 + 276 290 static const struct rtc_class_ops optee_rtc_ops = { 277 - .read_time = optee_rtc_readtime, 278 - .set_time = optee_rtc_settime, 279 - .set_offset = optee_rtc_setoffset, 280 - .read_offset = optee_rtc_readoffset, 291 + .read_time = optee_rtc_readtime, 292 + .set_time = optee_rtc_settime, 293 + .set_offset = optee_rtc_setoffset, 294 + .read_offset = optee_rtc_readoffset, 295 + .read_alarm = optee_rtc_read_alarm, 296 + .set_alarm = optee_rtc_set_alarm, 297 + .alarm_irq_enable = optee_rtc_enable_alarm, 281 298 }; 299 + 300 + static int optee_rtc_wait_alarm(struct device *dev, int *return_status) 301 + { 302 + struct optee_rtc *priv = dev_get_drvdata(dev); 303 + struct tee_ioctl_invoke_arg inv_arg = {0}; 304 + struct tee_param param[1] = {0}; 305 + int ret; 306 + 307 + if (!(priv->features & TA_RTC_FEATURE_ALARM)) 308 + return -EOPNOTSUPP; 309 + 310 + inv_arg.func = PTA_CMD_RTC_WAIT_ALARM; 311 + inv_arg.session = priv->session2_id; 312 + inv_arg.num_params = 1; 313 + 314 + param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_OUTPUT; 315 + 316 + ret = tee_client_invoke_func(priv->ctx, &inv_arg, param); 317 + if (ret < 0 || inv_arg.ret != 0) 318 + return ret ? ret : -EPROTO; 319 + 320 + *return_status = param[0].u.value.a; 321 + 322 + return 0; 323 + } 324 + 325 + static int optee_rtc_cancel_wait_alarm(struct device *dev) 326 + { 327 + struct optee_rtc *priv = dev_get_drvdata(dev); 328 + struct tee_ioctl_invoke_arg inv_arg = {0}; 329 + struct tee_param param[1] = {0}; 330 + int ret; 331 + 332 + if (!(priv->features & TA_RTC_FEATURE_ALARM)) 333 + return -EOPNOTSUPP; 334 + 335 + inv_arg.func = PTA_CMD_RTC_CANCEL_WAIT; 336 + inv_arg.session = priv->session_id; 337 + inv_arg.num_params = 0; 338 + 339 + ret = tee_client_invoke_func(priv->ctx, &inv_arg, param); 340 + if (ret < 0 || inv_arg.ret != 0) 341 + return ret ? ret : -EPROTO; 342 + 343 + return 0; 344 + } 345 + 346 + static int optee_rtc_set_alarm_wake_status(struct device *dev, bool status) 347 + { 348 + struct optee_rtc *priv = dev_get_drvdata(dev); 349 + struct tee_ioctl_invoke_arg inv_arg = {0}; 350 + struct tee_param param[1] = {0}; 351 + int ret; 352 + 353 + if (!(priv->features & TA_RTC_FEATURE_ALARM)) 354 + return -EOPNOTSUPP; 355 + 356 + inv_arg.func = PTA_CMD_RTC_SET_WAKE_ALARM_STATUS; 357 + inv_arg.session = priv->session_id; 358 + inv_arg.num_params = 1; 359 + 360 + param[0].attr = TEE_IOCTL_PARAM_ATTR_TYPE_VALUE_INPUT; 361 + param[0].u.value.a = status; 362 + 363 + ret = tee_client_invoke_func(priv->ctx, &inv_arg, param); 364 + 365 + if (ret < 0 || inv_arg.ret != 0) 366 + return ret ? ret : -EPROTO; 367 + 368 + return 0; 369 + } 370 + 371 + static int optee_rtc_handle_alarm_event(void *data) 372 + { 373 + struct optee_rtc *priv = (struct optee_rtc *)data; 374 + int wait_alarm_return_status = 0; 375 + int ret; 376 + 377 + while (!kthread_should_stop()) { 378 + ret = optee_rtc_wait_alarm(priv->dev, &wait_alarm_return_status); 379 + if (ret) { 380 + dev_err(priv->dev, "Failed to wait for alarm: %d\n", ret); 381 + return ret; 382 + } 383 + switch (wait_alarm_return_status) { 384 + case WAIT_ALARM_ALARM_OCCURRED: 385 + dev_dbg(priv->dev, "Alarm occurred\n"); 386 + rtc_update_irq(priv->rtc, 1, RTC_IRQF | RTC_AF); 387 + break; 388 + case WAIT_ALARM_CANCELED: 389 + dev_dbg(priv->dev, "Alarm canceled\n"); 390 + break; 391 + default: 392 + dev_warn(priv->dev, "Unknown return status: %d\n", 393 + wait_alarm_return_status); 394 + break; 395 + } 396 + } 397 + 398 + return 0; 399 + } 282 400 283 401 static int optee_rtc_read_info(struct device *dev, struct rtc_device *rtc, 284 402 u64 *features) ··· 505 193 struct optee_rtc_time *tm; 506 194 int ret; 507 195 508 - inv_arg.func = TA_CMD_RTC_GET_INFO; 196 + inv_arg.func = PTA_CMD_RTC_GET_INF; 509 197 inv_arg.session = priv->session_id; 510 198 inv_arg.num_params = 4; 511 199 ··· 550 238 static int optee_rtc_probe(struct device *dev) 551 239 { 552 240 struct tee_client_device *rtc_device = to_tee_client_device(dev); 241 + struct tee_ioctl_open_session_arg sess2_arg = {0}; 553 242 struct tee_ioctl_open_session_arg sess_arg = {0}; 554 243 struct optee_rtc *priv; 555 244 struct rtc_device *rtc; ··· 565 252 if (IS_ERR(rtc)) 566 253 return PTR_ERR(rtc); 567 254 255 + priv->rtc = rtc; 256 + 568 257 /* Open context with TEE driver */ 569 258 priv->ctx = tee_client_open_context(NULL, optee_ctx_match, NULL, NULL); 570 259 if (IS_ERR(priv->ctx)) 571 260 return -ENODEV; 572 261 573 - /* Open session with rtc Trusted App */ 262 + /* Open first session with rtc Pseudo Trusted App */ 574 263 export_uuid(sess_arg.uuid, &rtc_device->id.uuid); 575 264 sess_arg.clnt_login = TEE_IOCTL_LOGIN_REE_KERNEL; 576 265 ··· 584 269 } 585 270 priv->session_id = sess_arg.session; 586 271 272 + /* 273 + * Shared memory is used for passing an instance of either struct optee_rtc_info, 274 + * struct optee_rtc_time or struct optee_rtc_alarm to OP-TEE service. 275 + * The former is by definition large enough to cover both parameter cases. 276 + */ 587 277 shm = tee_shm_alloc_kernel_buf(priv->ctx, sizeof(struct optee_rtc_info)); 588 278 if (IS_ERR(shm)) { 589 279 dev_err(priv->dev, "tee_shm_alloc_kernel_buf failed\n"); ··· 608 288 goto out_shm; 609 289 } 610 290 291 + /* Handle feature's related setup before registering to rtc framework */ 292 + if (priv->features & TA_RTC_FEATURE_ALARM) { 293 + priv->alarm_task = kthread_create(optee_rtc_handle_alarm_event, 294 + priv, "rtc_alarm_evt"); 295 + if (IS_ERR(priv->alarm_task)) { 296 + dev_err(dev, "Failed to create alarm thread\n"); 297 + goto out_shm; 298 + } 299 + 300 + /* 301 + * In case of supported alarm feature on optee side, we create a kthread 302 + * that will, in a new optee session, call a PTA interface "rtc_wait_alarm". 303 + * This call return in case of alarm and in case of canceled alarm. 304 + * The new optee session is therefore only needed in this case as we cannot 305 + * use the same session for parallel calls to optee PTA. 306 + * Hence one session is reserved to wait for alarms and the other to make 307 + * standard calls to RTC PTA. 308 + */ 309 + 310 + /* Open second session with rtc Trusted App */ 311 + export_uuid(sess2_arg.uuid, &rtc_device->id.uuid); 312 + sess2_arg.clnt_login = TEE_IOCTL_LOGIN_REE_KERNEL; 313 + 314 + ret = tee_client_open_session(priv->ctx, &sess2_arg, NULL); 315 + if (ret < 0 || sess2_arg.ret != 0) { 316 + dev_err(dev, "tee_client_open_session failed, err: %x\n", sess2_arg.ret); 317 + err = -EINVAL; 318 + goto out_thrd; 319 + } 320 + priv->session2_id = sess2_arg.session; 321 + 322 + if (priv->features & TA_RTC_FEATURE_WAKEUP_ALARM) 323 + device_init_wakeup(dev, true); 324 + } 325 + 611 326 err = devm_rtc_register_device(rtc); 612 327 if (err) 613 - goto out_shm; 328 + goto out_wk; 614 329 615 330 /* 616 - * We must clear this bit after registering because rtc_register_device 617 - * will set it if it sees that .set_offset is provided. 331 + * We must clear those bits after registering because registering a rtc_device 332 + * will set them if it sees that .set_offset and .set_alarm are provided. 618 333 */ 619 334 if (!(priv->features & TA_RTC_FEATURE_CORRECTION)) 620 335 clear_bit(RTC_FEATURE_CORRECTION, rtc->features); 336 + if (!(priv->features & TA_RTC_FEATURE_ALARM)) 337 + clear_bit(RTC_FEATURE_ALARM, rtc->features); 338 + 339 + /* Start the thread after the rtc is setup */ 340 + if (priv->alarm_task) { 341 + wake_up_process(priv->alarm_task); 342 + dev_dbg(dev, "Wait alarm thread successfully started\n"); 343 + } 621 344 622 345 return 0; 623 - 346 + out_wk: 347 + if (priv->features & TA_RTC_FEATURE_ALARM) { 348 + device_init_wakeup(dev, false); 349 + tee_client_close_session(priv->ctx, priv->session2_id); 350 + } 351 + out_thrd: 352 + if (priv->features & TA_RTC_FEATURE_ALARM) 353 + kthread_stop(priv->alarm_task); 624 354 out_shm: 625 355 tee_shm_free(priv->shm); 626 356 out_sess: ··· 685 315 { 686 316 struct optee_rtc *priv = dev_get_drvdata(dev); 687 317 318 + if (priv->features & TA_RTC_FEATURE_ALARM) { 319 + optee_rtc_cancel_wait_alarm(dev); 320 + kthread_stop(priv->alarm_task); 321 + device_init_wakeup(dev, false); 322 + tee_client_close_session(priv->ctx, priv->session2_id); 323 + } 324 + 688 325 tee_shm_free(priv->shm); 689 326 tee_client_close_session(priv->ctx, priv->session_id); 690 327 tee_client_close_context(priv->ctx); 691 328 692 329 return 0; 693 330 } 331 + 332 + static int optee_rtc_suspend(struct device *dev) 333 + { 334 + int res = optee_rtc_set_alarm_wake_status(dev, device_may_wakeup(dev)); 335 + 336 + if (res) { 337 + dev_err(dev, "Unable to transmit wakeup information to optee rtc\n"); 338 + return res; 339 + } 340 + 341 + return 0; 342 + } 343 + 344 + DEFINE_SIMPLE_DEV_PM_OPS(optee_rtc_pm_ops, optee_rtc_suspend, NULL); 694 345 695 346 static const struct tee_client_device_id optee_rtc_id_table[] = { 696 347 {UUID_INIT(0xf389f8c8, 0x845f, 0x496c, ··· 728 337 .bus = &tee_bus_type, 729 338 .probe = optee_rtc_probe, 730 339 .remove = optee_rtc_remove, 340 + .pm = pm_sleep_ptr(&optee_rtc_pm_ops), 731 341 }, 732 342 }; 733 343