From 785f45b6036532800fa6727679962e677865f7b5 Mon Sep 17 00:00:00 2001 From: Yong Ding Date: Wed, 28 Mar 2018 10:22:29 +0800 Subject: [PATCH 1/2] soc: qcom: hab: add the uninterruptible receive support In the blocking mode of habmm_socket_recv(), it is an interruptible wait by default. Here, the uninterruptible version is added. Change-Id: Iba9ee10afb3f2529a99a9c90f6fc0cb56fb9cb08 Signed-off-by: Yong Ding --- drivers/soc/qcom/hab/hab.c | 2 +- drivers/soc/qcom/hab/hab.h | 2 +- drivers/soc/qcom/hab/hab_msg.c | 24 ++++++++++++++++-------- drivers/soc/qcom/hab/hab_vchan.c | 2 +- include/linux/habmm.h | 5 +++++ 5 files changed, 24 insertions(+), 11 deletions(-) diff --git a/drivers/soc/qcom/hab/hab.c b/drivers/soc/qcom/hab/hab.c index 1e568c79fcae..3294fc34bdf8 100644 --- a/drivers/soc/qcom/hab/hab.c +++ b/drivers/soc/qcom/hab/hab.c @@ -378,7 +378,7 @@ struct hab_message *hab_vchan_recv(struct uhab_context *ctx, physical_channel_rx_dispatch((unsigned long) vchan->pchan); } - message = hab_msg_dequeue(vchan, !nonblocking_flag); + message = hab_msg_dequeue(vchan, flags); if (!message) { if (nonblocking_flag) ret = -EAGAIN; diff --git a/drivers/soc/qcom/hab/hab.h b/drivers/soc/qcom/hab/hab.h index 72635e70c94c..ce4c94fa75c9 100644 --- a/drivers/soc/qcom/hab/hab.h +++ b/drivers/soc/qcom/hab/hab.h @@ -427,7 +427,7 @@ int habmem_imp_hyp_mmap(struct file *flip, struct vm_area_struct *vma); void hab_msg_free(struct hab_message *message); struct hab_message *hab_msg_dequeue(struct virtual_channel *vchan, - int wait_flag); + unsigned int flags); void hab_msg_recv(struct physical_channel *pchan, struct hab_header *header); diff --git a/drivers/soc/qcom/hab/hab_msg.c b/drivers/soc/qcom/hab/hab_msg.c index 700239a25652..d5c625e8c1c9 100644 --- a/drivers/soc/qcom/hab/hab_msg.c +++ b/drivers/soc/qcom/hab/hab_msg.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -43,16 +43,24 @@ void hab_msg_free(struct hab_message *message) } struct hab_message * -hab_msg_dequeue(struct virtual_channel *vchan, int wait_flag) +hab_msg_dequeue(struct virtual_channel *vchan, unsigned int flags) { struct hab_message *message = NULL; int ret = 0; + int wait = !(flags & HABMM_SOCKET_RECV_FLAGS_NON_BLOCKING); + int interruptible = !(flags & HABMM_SOCKET_RECV_FLAGS_UNINTERRUPTIBLE); - if (wait_flag) { - if (hab_rx_queue_empty(vchan)) - ret = wait_event_interruptible(vchan->rx_queue, - !hab_rx_queue_empty(vchan) || - vchan->otherend_closed); + if (wait) { + if (hab_rx_queue_empty(vchan)) { + if (interruptible) + ret = wait_event_interruptible(vchan->rx_queue, + !hab_rx_queue_empty(vchan) || + vchan->otherend_closed); + else + wait_event(vchan->rx_queue, + !hab_rx_queue_empty(vchan) || + vchan->otherend_closed); + } } /* return all the received messages before the remote close */ @@ -74,7 +82,7 @@ static void hab_msg_queue(struct virtual_channel *vchan, list_add_tail(&message->node, &vchan->rx_list); spin_unlock_bh(&vchan->rx_lock); - wake_up_interruptible(&vchan->rx_queue); + wake_up(&vchan->rx_queue); } static int hab_export_enqueue(struct virtual_channel *vchan, diff --git a/drivers/soc/qcom/hab/hab_vchan.c b/drivers/soc/qcom/hab/hab_vchan.c index e8b8866d570d..140d75656353 100644 --- a/drivers/soc/qcom/hab/hab_vchan.c +++ b/drivers/soc/qcom/hab/hab_vchan.c @@ -160,7 +160,7 @@ void hab_vchan_stop(struct virtual_channel *vchan) { if (vchan) { vchan->otherend_closed = 1; - wake_up_interruptible(&vchan->rx_queue); + wake_up(&vchan->rx_queue); } } diff --git a/include/linux/habmm.h b/include/linux/habmm.h index b4b31dc36faf..966c5ee91be4 100644 --- a/include/linux/habmm.h +++ b/include/linux/habmm.h @@ -143,6 +143,11 @@ int32_t habmm_socket_send(int32_t handle, void *src_buff, uint32_t size_bytes, */ #define HABMM_SOCKET_RECV_FLAGS_NON_BLOCKING 0x00000001 +/* In the blocking mode, this flag is used to indicate it is an + * uninterruptbile blocking call. + */ +#define HABMM_SOCKET_RECV_FLAGS_UNINTERRUPTIBLE 0x00000002 + int32_t habmm_socket_recv(int32_t handle, void *dst_buff, uint32_t *size_bytes, uint32_t timeout, uint32_t flags); From eddcb311588bdb49ef4168a23b977d879d372f4a Mon Sep 17 00:00:00 2001 From: Zhiqiang Tu Date: Wed, 11 Apr 2018 09:32:09 +0800 Subject: [PATCH 2/2] clk: msm: Fix signal interrupt issue for virtual clock Virtual clock operations returned error when received signal. Uninterruptible flag is added in receiving response to avoid being interrupted by signal. Change-Id: Id3b5b56432751ec5b49c36a028444c0360fe811f Signed-off-by: Zhiqiang Tu --- drivers/clk/msm/virtclk-front.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/drivers/clk/msm/virtclk-front.c b/drivers/clk/msm/virtclk-front.c index 4018c4922574..2d8a9e8ec61c 100644 --- a/drivers/clk/msm/virtclk-front.c +++ b/drivers/clk/msm/virtclk-front.c @@ -77,7 +77,7 @@ static int virtclk_front_get_id(struct clk *clk) } ret = habmm_socket_recv(handle, &rsp, &rsp_size, - UINT_MAX, 0); + UINT_MAX, HABMM_SOCKET_RECV_FLAGS_UNINTERRUPTIBLE); if (ret) { pr_err("%s: habmm socket receive failed (%d)\n", clk->dbg_name, ret); @@ -132,7 +132,8 @@ static int virtclk_front_prepare(struct clk *clk) goto err_out; } - ret = habmm_socket_recv(handle, &rsp, &rsp_size, UINT_MAX, 0); + ret = habmm_socket_recv(handle, &rsp, &rsp_size, UINT_MAX, + HABMM_SOCKET_RECV_FLAGS_UNINTERRUPTIBLE); if (ret) { pr_err("%s: habmm socket receive failed (%d)\n", clk->dbg_name, ret); @@ -185,7 +186,8 @@ static void virtclk_front_unprepare(struct clk *clk) goto err_out; } - ret = habmm_socket_recv(handle, &rsp, &rsp_size, UINT_MAX, 0); + ret = habmm_socket_recv(handle, &rsp, &rsp_size, UINT_MAX, + HABMM_SOCKET_RECV_FLAGS_UNINTERRUPTIBLE); if (ret) { pr_err("%s: habmm socket receive failed (%d)\n", clk->dbg_name, ret); @@ -236,7 +238,8 @@ static int virtclk_front_reset(struct clk *clk, enum clk_reset_action action) goto err_out; } - ret = habmm_socket_recv(handle, &rsp, &rsp_size, UINT_MAX, 0); + ret = habmm_socket_recv(handle, &rsp, &rsp_size, UINT_MAX, + HABMM_SOCKET_RECV_FLAGS_UNINTERRUPTIBLE); if (ret) { pr_err("%s: habmm socket receive failed (%d)\n", clk->dbg_name, ret); @@ -290,7 +293,8 @@ static int virtclk_front_set_rate(struct clk *clk, unsigned long rate) goto err_out; } - ret = habmm_socket_recv(handle, &rsp, &rsp_size, UINT_MAX, 0); + ret = habmm_socket_recv(handle, &rsp, &rsp_size, UINT_MAX, + HABMM_SOCKET_RECV_FLAGS_UNINTERRUPTIBLE); if (ret) { pr_err("%s: habmm socket receive failed (%d)\n", clk->dbg_name, ret); @@ -362,7 +366,8 @@ static unsigned long virtclk_front_get_rate(struct clk *clk) goto err_out; } - ret = habmm_socket_recv(handle, &rsp, &rsp_size, UINT_MAX, 0); + ret = habmm_socket_recv(handle, &rsp, &rsp_size, UINT_MAX, + HABMM_SOCKET_RECV_FLAGS_UNINTERRUPTIBLE); if (ret) { ret = 0; pr_err("%s: habmm socket receive failed (%d)\n", clk->dbg_name,