Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 06cd87a6 authored by Vivek Golani's avatar Vivek Golani
Browse files

rpmsg: qcom_smd: Add check for remote state in send api



Add support to check channel remote state while doing
a send. Added a wake_up_interruptible call to
unblock send api and release the mutex lock so that
channel close and reopen can happen gracefully.

Change-Id: Ifcf0dad1d9f9f4d4404d62920f1b9d2f1d45ba16
Signed-off-by: default avatarVivek Golani <vgolani@codeaurora.org>
parent a495cc04
Loading
Loading
Loading
Loading
+8 −3
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (c) 2015, Sony Mobile Communications AB.
 * Copyright (c) 2012-2013, 2020 The Linux Foundation. All rights reserved.
 * Copyright (c) 2012-2013, 2021 The Linux Foundation. All rights reserved.
 */

#include <linux/interrupt.h>
@@ -897,7 +897,8 @@ static int __qcom_smd_send(struct qcom_smd_channel *channel, const void *data,
	spin_lock_irqsave(&channel->tx_lock, flags);

	while (qcom_smd_get_tx_avail(channel) < tlen &&
	       channel->state == SMD_CHANNEL_OPENED) {
	       channel->state == SMD_CHANNEL_OPENED &&
		channel->remote_state == SMD_CHANNEL_OPENED) {
		if (!wait) {
			ret = -EAGAIN;
			goto out_unlock;
@@ -910,7 +911,8 @@ static int __qcom_smd_send(struct qcom_smd_channel *channel, const void *data,

		ret = wait_event_interruptible(channel->fblockread_event,
				       qcom_smd_get_tx_avail(channel) >= tlen ||
				       channel->state != SMD_CHANNEL_OPENED);
				       channel->state != SMD_CHANNEL_OPENED ||
				channel->remote_state != SMD_CHANNEL_OPENED);
		if (ret)
			return ret;

@@ -1486,6 +1488,9 @@ static void qcom_channel_state_worker(struct work_struct *work)
		chinfo.dst = RPMSG_ADDR_ANY;
		smd_ipc(channel->edge->ipc, false, NULL,
			"%s: unregistering ch %s\n", __func__, channel->name);

		wake_up_interruptible_all(&channel->fblockread_event);

		rpmsg_unregister_device(&edge->dev, &chinfo);
		channel->registered = false;
		spin_lock_irqsave(&edge->channels_lock, flags);