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

Commit b120190d authored by Santhosh Kumar M's avatar Santhosh Kumar M Committed by Sarannya S
Browse files

rpmsg: qcom_smd: Add GET/SET signal support



Add support to GET and SET the transport signals by the clients.

Change-Id: Iba3ba8653d777187f11c3cbfe29b587cbc64d213
Signed-off-by: default avatarSanthosh Kumar M <santhoshm@codeaurora.org>
Signed-off-by: default avatarSivasri Kumar Vanka <sivasri@codeaurora.org>
parent 196e95c0
Loading
Loading
Loading
Loading
+55 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
#include <linux/sizes.h>
#include <linux/slab.h>
#include <linux/soc/qcom/smem.h>
#include <linux/termios.h>
#include <linux/wait.h>
#include <linux/rpmsg.h>
#include <linux/rpmsg/qcom_smd.h>
@@ -226,6 +227,7 @@ struct qcom_smd_channel {
	void *drvdata;

	struct list_head list;
	u32 rsigs;
};

/*
@@ -288,6 +290,14 @@ struct smd_channel_info_word_pair {
			channel->info->rx.param);			      \
	})

#define GET_RX_CHANNEL_SIGNAL(channel)					      \
	({								      \
		(GET_RX_CHANNEL_FLAG(channel, fDSR) ? TIOCM_DSR : 0) |	      \
		(GET_RX_CHANNEL_FLAG(channel, fCTS) ? TIOCM_CTS : 0) |	      \
		(GET_RX_CHANNEL_FLAG(channel, fCD) ? TIOCM_CD : 0) |	      \
		(GET_RX_CHANNEL_FLAG(channel, fRI) ? TIOCM_RI : 0);	      \
	})

#define SET_RX_CHANNEL_FLAG(channel, param, value)			     \
	({								     \
		BUILD_BUG_ON(sizeof(channel->info->rx.param) != sizeof(u8)); \
@@ -575,9 +585,11 @@ static int qcom_smd_channel_recv_single(struct qcom_smd_channel *channel)
 */
static bool qcom_smd_channel_intr(struct qcom_smd_channel *channel)
{
	struct rpmsg_endpoint *ept = &channel->qsept->ept;
	bool need_state_scan = false;
	int remote_state;
	__le32 pktlen;
	u32 rsig = 0;
	int avail;
	int ret;

@@ -600,6 +612,14 @@ static bool qcom_smd_channel_intr(struct qcom_smd_channel *channel)
	if (channel->state != SMD_CHANNEL_OPENED)
		goto out;

	/* Check if any signal updated */
	rsig = GET_RX_CHANNEL_SIGNAL(channel);

	if ((ept->sig_cb) && (channel->rsigs != rsig)) {
		ept->sig_cb(ept->rpdev, channel->rsigs, rsig);
		channel->rsigs = rsig;
	}

	/* Indicate that we've seen the new data */
	SET_RX_CHANNEL_FLAG(channel, fHEAD, 0);

@@ -989,6 +1009,39 @@ static __poll_t qcom_smd_poll(struct rpmsg_endpoint *ept,
	return mask;
}

static int qcom_smd_get_sigs(struct rpmsg_endpoint *ept,
				u32 *lsigs, u32 *rsigs)
{
	struct qcom_smd_endpoint *qsept = to_smd_endpoint(ept);
	struct qcom_smd_channel *channel = qsept->qsch;

	*lsigs = 0;
	*rsigs = 0;
	*rsigs = GET_RX_CHANNEL_SIGNAL(channel);
	return 0;
}

static int qcom_smd_set_sigs(struct rpmsg_endpoint *ept, u32 sigs)
{
	struct qcom_smd_endpoint *qsept = to_smd_endpoint(ept);
	struct qcom_smd_channel *channel = qsept->qsch;

	if (sigs & TIOCM_DTR)
		SET_TX_CHANNEL_FLAG(channel, fDSR, 1);
	else
		SET_TX_CHANNEL_FLAG(channel, fDSR, 0);

	if (sigs & TIOCM_RTS)
		SET_TX_CHANNEL_FLAG(channel, fCTS, 1);
	else
		SET_TX_CHANNEL_FLAG(channel, fDSR, 0);

	SET_TX_CHANNEL_FLAG(channel, fSTATE, 1);
	qcom_smd_signal_channel(channel);

	return 0;
}

/*
 * Finds the device_node for the smd child interested in this channel.
 */
@@ -1040,6 +1093,8 @@ static const struct rpmsg_endpoint_ops qcom_smd_endpoint_ops = {
	.send = qcom_smd_send,
	.trysend = qcom_smd_trysend,
	.poll = qcom_smd_poll,
	.get_sigs = qcom_smd_get_sigs,
	.set_sigs = qcom_smd_set_sigs,
};

static void qcom_smd_release_device(struct device *dev)