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

Commit 112597fd authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "rpmsg: smd: Signal the TX channel that smd driver read data"

parents d8975316 2fc20789
Loading
Loading
Loading
Loading
+59 −4
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);

@@ -621,7 +641,7 @@ static bool qcom_smd_channel_intr(struct qcom_smd_channel *channel)
	}

	/* Indicate that we have seen and updated tail */
	SET_RX_CHANNEL_FLAG(channel, fTAIL, 1);
	SET_TX_CHANNEL_FLAG(channel, fTAIL, 1);

	/* Signal the remote that we've consumed the data (if requested) */
	if (!GET_RX_CHANNEL_FLAG(channel, fBLOCKREADINTR)) {
@@ -820,9 +840,9 @@ static int qcom_smd_channel_open(struct qcom_smd_channel *channel,
	int ret;

	/*
	 * Packets are maximum 4k, but reduce if the fifo is smaller
	 * Packets are maximum 8k, but reduce if the fifo is smaller
	 */
	bb_size = min(channel->fifo_size, SZ_4K);
	bb_size = min(channel->fifo_size, SZ_8K);
	channel->bounce_buffer = kmalloc(bb_size, GFP_KERNEL);
	if (!channel->bounce_buffer)
		return -ENOMEM;
@@ -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)
@@ -1590,7 +1645,7 @@ static int __init qcom_smd_init(void)
{
	return platform_driver_register(&qcom_smd_driver);
}
subsys_initcall(qcom_smd_init);
postcore_initcall(qcom_smd_init);

static void __exit qcom_smd_exit(void)
{