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

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

Merge "drivers: char: reset signal support for smd channels"

parents 39fbb9de 2db8f1c8
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);