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

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

Merge "mhi: dev: uci: add support for POLLPRI signal for line state changes"

parents c9dce58a ec9632f2
Loading
Loading
Loading
Loading
+37 −4
Original line number Diff line number Diff line
@@ -12,6 +12,7 @@
#include <linux/of_device.h>
#include <linux/poll.h>
#include <linux/slab.h>
#include <linux/termios.h>
#include <linux/types.h>
#include <linux/wait.h>
#include <linux/uaccess.h>
@@ -46,6 +47,7 @@ struct uci_dev {
	size_t mtu;
	int ref_count;
	bool enabled;
	u32 tiocm;
	void *ipc_log;
};

@@ -145,11 +147,20 @@ static long mhi_uci_ioctl(struct file *file,
{
	struct uci_dev *uci_dev = file->private_data;
	struct mhi_device *mhi_dev = uci_dev->mhi_dev;
	struct uci_chan *uci_chan = &uci_dev->dl_chan;
	long ret = -ERESTARTSYS;

	mutex_lock(&uci_dev->mutex);
	if (uci_dev->enabled)

	if (cmd == TIOCMGET) {
		spin_lock_bh(&uci_chan->lock);
		ret = uci_dev->tiocm;
		uci_dev->tiocm = 0;
		spin_unlock_bh(&uci_chan->lock);
	} else if (uci_dev->enabled) {
		ret = mhi_ioctl(mhi_dev, cmd, arg);
	}

	mutex_unlock(&uci_dev->mutex);

	return ret;
@@ -212,10 +223,17 @@ static unsigned int mhi_uci_poll(struct file *file, poll_table *wait)
	spin_lock_bh(&uci_chan->lock);
	if (!uci_dev->enabled) {
		mask = POLLERR;
	} else if (!list_empty(&uci_chan->pending) || uci_chan->cur_buf) {
	} else {
		if (!list_empty(&uci_chan->pending) || uci_chan->cur_buf) {
			MSG_VERB("Client can read from node\n");
			mask |= POLLIN | POLLRDNORM;
		}

		if (uci_dev->tiocm) {
			MSG_VERB("Line status changed\n");
			mask |= POLLPRI;
		}
	}
	spin_unlock_bh(&uci_chan->lock);

	uci_chan = &uci_dev->ul_chan;
@@ -646,6 +664,20 @@ static void mhi_dl_xfer_cb(struct mhi_device *mhi_dev,
	wake_up(&uci_chan->wq);
}

static void mhi_status_cb(struct mhi_device *mhi_dev, enum MHI_CB reason)
{
	struct uci_dev *uci_dev = mhi_device_get_devdata(mhi_dev);
	struct uci_chan *uci_chan = &uci_dev->dl_chan;
	unsigned long flags;

	if (reason == MHI_CB_DTR_SIGNAL) {
		spin_lock_irqsave(&uci_chan->lock, flags);
		uci_dev->tiocm = mhi_dev->tiocm;
		spin_unlock_irqrestore(&uci_chan->lock, flags);
		wake_up(&uci_chan->wq);
	}
}

/* .driver_data stores max mtu */
static const struct mhi_device_id mhi_uci_match_table[] = {
	{ .chan = "LOOPBACK", .driver_data = 0x1000 },
@@ -664,6 +696,7 @@ static struct mhi_driver mhi_uci_driver = {
	.probe = mhi_uci_probe,
	.ul_xfer_cb = mhi_ul_xfer_cb,
	.dl_xfer_cb = mhi_dl_xfer_cb,
	.status_cb = mhi_status_cb,
	.driver = {
		.name = MHI_UCI_DRIVER_NAME,
		.owner = THIS_MODULE,