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

Commit 2db8f1c8 authored by Deepak Kumar Singh's avatar Deepak Kumar Singh Committed by Gerrit - the friendly Code Review server
Browse files

drivers: char: reset signal support for smd channels



Some user space client may be intersted in reset signals
when channel open or close happen due to ssr of remote
subsystem.

Adding support for reset signal for channel state changes.

Change-Id: Ice99c66b33f87ff94c870b4ee46cbd0d4f5023ee
Signed-off-by: default avatarDeepak Kumar Singh <deesin@codeaurora.org>
parent 85f2a837
Loading
Loading
Loading
Loading
+24 −2
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@
 * @queue:      incoming message queue
 * @readq:      wait object for incoming queue
 * @sig_change: flag to indicate serial signal change
 * @notify_state_update: notify channel state
 * @fragmented_read: set from dt node for partial read
 * @dev_name:   /dev/@dev_name for smd_pkt device
 * @ch_name:    smd channel to match to
@@ -69,6 +70,7 @@ struct smd_pkt_dev {
	struct sk_buff_head queue;
	wait_queue_head_t readq;
	int sig_change;
	bool notify_state_update;
	bool fragmented_read;
	const char *dev_name;
	const char *ch_name;
@@ -164,6 +166,7 @@ static int smd_pkt_rpdev_probe(struct rpmsg_device *rpdev)

	mutex_lock(&smd_pkt_devp->lock);
	smd_pkt_devp->rpdev = rpdev;
	smd_pkt_devp->notify_state_update = true;
	mutex_unlock(&smd_pkt_devp->lock);
	dev_set_drvdata(&rpdev->dev, smd_pkt_devp);
	complete_all(&smd_pkt_devp->ch_open);
@@ -273,7 +276,7 @@ static long smd_pkt_ioctl(struct file *file, unsigned int cmd,
{
	struct smd_pkt_dev *smd_pkt_devp;
	unsigned long flags;
	u32 lsigs, rsigs;
	u32 lsigs, rsigs, resetsigs;
	int ret;

	smd_pkt_devp = file->private_data;
@@ -288,19 +291,37 @@ static long smd_pkt_ioctl(struct file *file, unsigned int cmd,

	if (!completion_done(&smd_pkt_devp->ch_open)) {
		SMD_PKT_ERR("%s channel in reset\n", smd_pkt_devp->ch_name);
		if ((cmd == TIOCMGET) && (smd_pkt_devp->notify_state_update)) {
			resetsigs = TIOCM_OUT1 | TIOCM_OUT2;
			smd_pkt_devp->notify_state_update = false;
			mutex_unlock(&smd_pkt_devp->lock);

			SMD_PKT_ERR("%s: reset notified resetsigs=%d\n",
					smd_pkt_devp->ch_name, resetsigs);
			ret = put_user(resetsigs, (uint32_t __user *)arg);
			return ret;
		}
		mutex_unlock(&smd_pkt_devp->lock);
		return -ENETRESET;
	}

	switch (cmd) {
	case TIOCMGET:
		resetsigs = 0;
		spin_lock_irqsave(&smd_pkt_devp->queue_lock, flags);
		smd_pkt_devp->sig_change = false;
		if (smd_pkt_devp->notify_state_update) {
			resetsigs = TIOCM_OUT2;
			smd_pkt_devp->notify_state_update = false;
			SMD_PKT_ERR("%s: reset notified resetsigs=%d\n",
					smd_pkt_devp->ch_name, resetsigs);
		}
		spin_unlock_irqrestore(&smd_pkt_devp->queue_lock, flags);

		ret = rpmsg_get_sigs(smd_pkt_devp->rpdev->ept, &lsigs, &rsigs);
		if (!ret)
			ret = put_user(rsigs, (uint32_t *)arg);
			ret = put_user(rsigs | resetsigs,
				       (uint32_t __user *)arg);
		break;
	case TIOCMSET:
	case TIOCMBIS:
@@ -552,6 +573,7 @@ static void smd_pkt_rpdev_remove(struct rpmsg_device *rpdev)

	mutex_lock(&smd_pkt_devp->lock);
	smd_pkt_devp->rpdev = NULL;
	smd_pkt_devp->notify_state_update = true;
	mutex_unlock(&smd_pkt_devp->lock);

	dev_set_drvdata(&rpdev->dev, NULL);