diff options
author | Linux Build Service Account <lnxbuild@localhost> | 2019-10-29 18:09:25 -0700 |
---|---|---|
committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2019-10-29 18:09:27 -0700 |
commit | 41f6188ee4fbf767040069e757280dfc3a51b909 (patch) | |
tree | ba71683782f39378e9f1ffc80042111cae55130e | |
parent | 6eb16427aa90f67ccaae5ff72fff6ebcbf88d0cb (diff) | |
parent | 07c2b1599d5b614f21cd31966ac6f0b063a97858 (diff) |
Merge changes I5c1dd186,If7e67b7b into kernel.lnx.4.14.r4-relLA.UM.8.1.r1-10700-sm8150.0
* changes:
mhi: dev: uci: Handle TIOCMSET ioctl properly
mhi: dev: uci: add support for POLLPRI signal for line state changes
-rw-r--r-- | drivers/bus/mhi/devices/mhi_uci.c | 45 |
1 files changed, 41 insertions, 4 deletions
diff --git a/drivers/bus/mhi/devices/mhi_uci.c b/drivers/bus/mhi/devices/mhi_uci.c index 648ae65e3597..f5e0759be95e 100644 --- a/drivers/bus/mhi/devices/mhi_uci.c +++ b/drivers/bus/mhi/devices/mhi_uci.c @@ -21,6 +21,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> @@ -56,6 +57,7 @@ struct uci_dev { size_t actual_mtu; /* maximum size of incoming buffer */ int ref_count; bool enabled; + u32 tiocm; void *ipc_log; }; @@ -157,11 +159,24 @@ 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; + spin_unlock_bh(&uci_chan->lock); + } else if (uci_dev->enabled) { ret = mhi_ioctl(mhi_dev, cmd, arg); + if (!ret) { + spin_lock_bh(&uci_chan->lock); + uci_dev->tiocm = mhi_dev->tiocm; + spin_unlock_bh(&uci_chan->lock); + } + } + mutex_unlock(&uci_dev->mutex); return ret; @@ -224,9 +239,16 @@ 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) { - MSG_VERB("Client can read from node\n"); - mask |= POLLIN | POLLRDNORM; + } 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); @@ -659,6 +681,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 }, @@ -677,6 +713,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, |