Loading drivers/soc/qcom/smcinvoke.c +33 −12 Original line number Diff line number Diff line Loading @@ -139,6 +139,7 @@ static LIST_HEAD(g_mem_objs); static uint16_t g_last_cb_server_id = CBOBJ_SERVER_ID_START; static uint16_t g_last_mem_rgn_id, g_last_mem_map_obj_id; static size_t g_max_cb_buf_size = SMCINVOKE_TZ_MIN_BUF_SIZE; static unsigned int cb_reqs_inflight; static long smcinvoke_ioctl(struct file *, unsigned int, unsigned long); static int smcinvoke_open(struct inode *, struct file *); Loading Loading @@ -944,6 +945,7 @@ static void process_tzcb_req(void *buf, size_t buf_len, struct file **arr_filp) kref_init(&cb_txn->ref_cnt); mutex_lock(&g_smcinvoke_lock); ++cb_reqs_inflight; srvr_info = get_cb_server_locked( TZHANDLE_GET_SERVER(cb_req->hdr.tzhandle)); if (!srvr_info || srvr_info->state == SMCINVOKE_SERVER_STATE_DEFUNCT) { Loading @@ -959,10 +961,12 @@ static void process_tzcb_req(void *buf, size_t buf_len, struct file **arr_filp) * we need not worry that server_info will be deleted because as long * as this CBObj is served by this server, srvr_info will be valid. */ wake_up_interruptible(&srvr_info->req_wait_q); if (wq_has_sleeper(&srvr_info->req_wait_q)) { wake_up_interruptible_all(&srvr_info->req_wait_q); ret = wait_event_interruptible(srvr_info->rsp_wait_q, (cb_txn->state == SMCINVOKE_REQ_PROCESSED) || (srvr_info->state == SMCINVOKE_SERVER_STATE_DEFUNCT)); } out: /* * we could be here because of either: a. Req is PROCESSED Loading @@ -983,6 +987,7 @@ static void process_tzcb_req(void *buf, size_t buf_len, struct file **arr_filp) pr_debug("%s wait_event interrupted ret = %d\n", __func__, ret); cb_req->result = OBJECT_ERROR_ABORT; } --cb_reqs_inflight; memcpy(buf, cb_req, buf_len); kref_put(&cb_txn->ref_cnt, delete_cb_txn); if (srvr_info) Loading Loading @@ -1497,7 +1502,6 @@ static long process_accept_req(struct file *filp, unsigned int cmd, unsigned long arg) { int ret = -1; sigset_t pending_sig; struct smcinvoke_file_data *server_obj = filp->private_data; struct smcinvoke_accept user_args = {0}; struct smcinvoke_cb_txn *cb_txn = NULL; Loading @@ -1523,6 +1527,9 @@ static long process_accept_req(struct file *filp, unsigned int cmd, if (!server_info) return -EINVAL; if (server_info->state == SMCINVOKE_SERVER_STATE_DEFUNCT) server_info->state = 0; /* First check if it has response otherwise wait for req */ if (user_args.has_resp) { mutex_lock(&g_smcinvoke_lock); Loading Loading @@ -1579,17 +1586,12 @@ static long process_accept_req(struct file *filp, unsigned int cmd, * server_info invalid. Other accept/invoke threads are * using server_info and would crash. So dont do that. */ pending_sig = (¤t->pending)->signal; if (sigismember(&pending_sig, SIGKILL)) { mutex_lock(&g_smcinvoke_lock); server_info->state = SMCINVOKE_SERVER_STATE_DEFUNCT; wake_up_interruptible(&server_info->rsp_wait_q); server_info->state = SMCINVOKE_SERVER_STATE_DEFUNCT; mutex_unlock(&g_smcinvoke_lock); } wake_up_interruptible(&server_info->rsp_wait_q); goto out; } mutex_lock(&g_smcinvoke_lock); cb_txn = find_cbtxn_locked(server_info, SMCINVOKE_NEXT_AVAILABLE_TXN, Loading Loading @@ -1881,6 +1883,7 @@ static int smcinvoke_probe(struct platform_device *pdev) goto exit_destroy_device; } smcinvoke_pdev = pdev; cb_reqs_inflight = 0; return 0; Loading @@ -1904,6 +1907,22 @@ static int smcinvoke_remove(struct platform_device *pdev) return 0; } static int __maybe_unused smcinvoke_suspend(struct platform_device *pdev, pm_message_t state) { if (cb_reqs_inflight) { pr_err("Failed to suspend smcinvoke driver\n"); return -EIO; } return 0; } static int __maybe_unused smcinvoke_resume(struct platform_device *pdev) { return 0; } static const struct of_device_id smcinvoke_match[] = { { .compatible = "qcom,smcinvoke", Loading @@ -1914,6 +1933,8 @@ static const struct of_device_id smcinvoke_match[] = { static struct platform_driver smcinvoke_plat_driver = { .probe = smcinvoke_probe, .remove = smcinvoke_remove, .suspend = smcinvoke_suspend, .resume = smcinvoke_resume, .driver = { .name = "smcinvoke", .of_match_table = smcinvoke_match, Loading Loading
drivers/soc/qcom/smcinvoke.c +33 −12 Original line number Diff line number Diff line Loading @@ -139,6 +139,7 @@ static LIST_HEAD(g_mem_objs); static uint16_t g_last_cb_server_id = CBOBJ_SERVER_ID_START; static uint16_t g_last_mem_rgn_id, g_last_mem_map_obj_id; static size_t g_max_cb_buf_size = SMCINVOKE_TZ_MIN_BUF_SIZE; static unsigned int cb_reqs_inflight; static long smcinvoke_ioctl(struct file *, unsigned int, unsigned long); static int smcinvoke_open(struct inode *, struct file *); Loading Loading @@ -944,6 +945,7 @@ static void process_tzcb_req(void *buf, size_t buf_len, struct file **arr_filp) kref_init(&cb_txn->ref_cnt); mutex_lock(&g_smcinvoke_lock); ++cb_reqs_inflight; srvr_info = get_cb_server_locked( TZHANDLE_GET_SERVER(cb_req->hdr.tzhandle)); if (!srvr_info || srvr_info->state == SMCINVOKE_SERVER_STATE_DEFUNCT) { Loading @@ -959,10 +961,12 @@ static void process_tzcb_req(void *buf, size_t buf_len, struct file **arr_filp) * we need not worry that server_info will be deleted because as long * as this CBObj is served by this server, srvr_info will be valid. */ wake_up_interruptible(&srvr_info->req_wait_q); if (wq_has_sleeper(&srvr_info->req_wait_q)) { wake_up_interruptible_all(&srvr_info->req_wait_q); ret = wait_event_interruptible(srvr_info->rsp_wait_q, (cb_txn->state == SMCINVOKE_REQ_PROCESSED) || (srvr_info->state == SMCINVOKE_SERVER_STATE_DEFUNCT)); } out: /* * we could be here because of either: a. Req is PROCESSED Loading @@ -983,6 +987,7 @@ static void process_tzcb_req(void *buf, size_t buf_len, struct file **arr_filp) pr_debug("%s wait_event interrupted ret = %d\n", __func__, ret); cb_req->result = OBJECT_ERROR_ABORT; } --cb_reqs_inflight; memcpy(buf, cb_req, buf_len); kref_put(&cb_txn->ref_cnt, delete_cb_txn); if (srvr_info) Loading Loading @@ -1497,7 +1502,6 @@ static long process_accept_req(struct file *filp, unsigned int cmd, unsigned long arg) { int ret = -1; sigset_t pending_sig; struct smcinvoke_file_data *server_obj = filp->private_data; struct smcinvoke_accept user_args = {0}; struct smcinvoke_cb_txn *cb_txn = NULL; Loading @@ -1523,6 +1527,9 @@ static long process_accept_req(struct file *filp, unsigned int cmd, if (!server_info) return -EINVAL; if (server_info->state == SMCINVOKE_SERVER_STATE_DEFUNCT) server_info->state = 0; /* First check if it has response otherwise wait for req */ if (user_args.has_resp) { mutex_lock(&g_smcinvoke_lock); Loading Loading @@ -1579,17 +1586,12 @@ static long process_accept_req(struct file *filp, unsigned int cmd, * server_info invalid. Other accept/invoke threads are * using server_info and would crash. So dont do that. */ pending_sig = (¤t->pending)->signal; if (sigismember(&pending_sig, SIGKILL)) { mutex_lock(&g_smcinvoke_lock); server_info->state = SMCINVOKE_SERVER_STATE_DEFUNCT; wake_up_interruptible(&server_info->rsp_wait_q); server_info->state = SMCINVOKE_SERVER_STATE_DEFUNCT; mutex_unlock(&g_smcinvoke_lock); } wake_up_interruptible(&server_info->rsp_wait_q); goto out; } mutex_lock(&g_smcinvoke_lock); cb_txn = find_cbtxn_locked(server_info, SMCINVOKE_NEXT_AVAILABLE_TXN, Loading Loading @@ -1881,6 +1883,7 @@ static int smcinvoke_probe(struct platform_device *pdev) goto exit_destroy_device; } smcinvoke_pdev = pdev; cb_reqs_inflight = 0; return 0; Loading @@ -1904,6 +1907,22 @@ static int smcinvoke_remove(struct platform_device *pdev) return 0; } static int __maybe_unused smcinvoke_suspend(struct platform_device *pdev, pm_message_t state) { if (cb_reqs_inflight) { pr_err("Failed to suspend smcinvoke driver\n"); return -EIO; } return 0; } static int __maybe_unused smcinvoke_resume(struct platform_device *pdev) { return 0; } static const struct of_device_id smcinvoke_match[] = { { .compatible = "qcom,smcinvoke", Loading @@ -1914,6 +1933,8 @@ static const struct of_device_id smcinvoke_match[] = { static struct platform_driver smcinvoke_plat_driver = { .probe = smcinvoke_probe, .remove = smcinvoke_remove, .suspend = smcinvoke_suspend, .resume = smcinvoke_resume, .driver = { .name = "smcinvoke", .of_match_table = smcinvoke_match, Loading