summaryrefslogtreecommitdiffstats
path: root/drivers/tty/serdev
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-12-11 08:41:08 +0100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-12-11 08:41:08 +0100
commit42e64571d516ef761d9f330c80493637cbf3bdda (patch)
tree5f3df1c06c2d571efa5fd72d0c8022a80140eec2 /drivers/tty/serdev
parentserial: imx: Support common rs485 binding for RTS polarity (diff)
parentLinux 4.15-rc3 (diff)
downloadlinux-42e64571d516ef761d9f330c80493637cbf3bdda.tar.xz
linux-42e64571d516ef761d9f330c80493637cbf3bdda.zip
Merge 4.15-rc3 into tty-next
We want the serial/tty fixes in here as well. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty/serdev')
-rw-r--r--drivers/tty/serdev/serdev-ttyport.c26
1 files changed, 23 insertions, 3 deletions
diff --git a/drivers/tty/serdev/serdev-ttyport.c b/drivers/tty/serdev/serdev-ttyport.c
index 75f312ed96e8..c2629ab1bbcf 100644
--- a/drivers/tty/serdev/serdev-ttyport.c
+++ b/drivers/tty/serdev/serdev-ttyport.c
@@ -27,23 +27,41 @@ static int ttyport_receive_buf(struct tty_port *port, const unsigned char *cp,
{
struct serdev_controller *ctrl = port->client_data;
struct serport *serport = serdev_controller_get_drvdata(ctrl);
+ int ret;
if (!test_bit(SERPORT_ACTIVE, &serport->flags))
return 0;
- return serdev_controller_receive_buf(ctrl, cp, count);
+ ret = serdev_controller_receive_buf(ctrl, cp, count);
+
+ dev_WARN_ONCE(&ctrl->dev, ret < 0 || ret > count,
+ "receive_buf returns %d (count = %zu)\n",
+ ret, count);
+ if (ret < 0)
+ return 0;
+ else if (ret > count)
+ return count;
+
+ return ret;
}
static void ttyport_write_wakeup(struct tty_port *port)
{
struct serdev_controller *ctrl = port->client_data;
struct serport *serport = serdev_controller_get_drvdata(ctrl);
+ struct tty_struct *tty;
+
+ tty = tty_port_tty_get(port);
+ if (!tty)
+ return;
- if (test_and_clear_bit(TTY_DO_WRITE_WAKEUP, &port->tty->flags) &&
+ if (test_and_clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags) &&
test_bit(SERPORT_ACTIVE, &serport->flags))
serdev_controller_write_wakeup(ctrl);
- wake_up_interruptible_poll(&port->tty->write_wait, POLLOUT);
+ wake_up_interruptible_poll(&tty->write_wait, POLLOUT);
+
+ tty_kref_put(tty);
}
static const struct tty_port_client_operations client_ops = {
@@ -139,8 +157,10 @@ static void ttyport_close(struct serdev_controller *ctrl)
clear_bit(SERPORT_ACTIVE, &serport->flags);
+ tty_lock(tty);
if (tty->ops->close)
tty->ops->close(tty, NULL);
+ tty_unlock(tty);
tty_release_struct(tty, serport->tty_idx);
}