aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2019-10-29 18:09:25 -0700
committerGerrit - the friendly Code Review server <code-review@localhost>2019-10-29 18:09:27 -0700
commit41f6188ee4fbf767040069e757280dfc3a51b909 (patch)
treeba71683782f39378e9f1ffc80042111cae55130e
parent6eb16427aa90f67ccaae5ff72fff6ebcbf88d0cb (diff)
parent07c2b1599d5b614f21cd31966ac6f0b063a97858 (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.c45
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,