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, 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);