summaryrefslogtreecommitdiff
path: root/drivers/tty/serdev/serdev-ttyport.c
diff options
context:
space:
mode:
authorSean Paul <seanpaul@chromium.org>2017-05-18 09:24:30 -0400
committerSean Paul <seanpaul@chromium.org>2017-05-18 09:24:30 -0400
commit6b7781b42dc9bc9bcd1523b6c24b876cdda0bef3 (patch)
treeee55c67e4ea30b9eb44f301ba0bde2e631a26162 /drivers/tty/serdev/serdev-ttyport.c
parent52d9d38c183bf0e09601d875ea31bb53c05dd8cf (diff)
parente98c58e55f68f8785aebfab1f8c9a03d8de0afe1 (diff)
Merge remote-tracking branch 'airlied/drm-next' into drm-misc-next
Picking up drm-next @ 4.12-rc1 in order to apply Michal Hocko's vmalloc patch set Signed-off-by: Sean Paul <seanpaul@chromium.org>
Diffstat (limited to 'drivers/tty/serdev/serdev-ttyport.c')
-rw-r--r--drivers/tty/serdev/serdev-ttyport.c42
1 files changed, 38 insertions, 4 deletions
diff --git a/drivers/tty/serdev/serdev-ttyport.c b/drivers/tty/serdev/serdev-ttyport.c
index d05393594f15..487c88f6aa0e 100644
--- a/drivers/tty/serdev/serdev-ttyport.c
+++ b/drivers/tty/serdev/serdev-ttyport.c
@@ -14,6 +14,7 @@
#include <linux/serdev.h>
#include <linux/tty.h>
#include <linux/tty_driver.h>
+#include <linux/poll.h>
#define SERPORT_ACTIVE 1
@@ -46,11 +47,11 @@ static void ttyport_write_wakeup(struct tty_port *port)
struct serdev_controller *ctrl = port->client_data;
struct serport *serport = serdev_controller_get_drvdata(ctrl);
- if (!test_and_clear_bit(TTY_DO_WRITE_WAKEUP, &port->tty->flags))
- return;
-
- if (test_bit(SERPORT_ACTIVE, &serport->flags))
+ if (test_and_clear_bit(TTY_DO_WRITE_WAKEUP, &port->tty->flags) &&
+ test_bit(SERPORT_ACTIVE, &serport->flags))
serdev_controller_write_wakeup(ctrl);
+
+ wake_up_interruptible_poll(&port->tty->write_wait, POLLOUT);
}
static const struct tty_port_client_operations client_ops = {
@@ -167,6 +168,36 @@ static void ttyport_set_flow_control(struct serdev_controller *ctrl, bool enable
tty_set_termios(tty, &ktermios);
}
+static void ttyport_wait_until_sent(struct serdev_controller *ctrl, long timeout)
+{
+ struct serport *serport = serdev_controller_get_drvdata(ctrl);
+ struct tty_struct *tty = serport->tty;
+
+ tty_wait_until_sent(tty, timeout);
+}
+
+static int ttyport_get_tiocm(struct serdev_controller *ctrl)
+{
+ struct serport *serport = serdev_controller_get_drvdata(ctrl);
+ struct tty_struct *tty = serport->tty;
+
+ if (!tty->ops->tiocmget)
+ return -ENOTSUPP;
+
+ return tty->driver->ops->tiocmget(tty);
+}
+
+static int ttyport_set_tiocm(struct serdev_controller *ctrl, unsigned int set, unsigned int clear)
+{
+ struct serport *serport = serdev_controller_get_drvdata(ctrl);
+ struct tty_struct *tty = serport->tty;
+
+ if (!tty->ops->tiocmset)
+ return -ENOTSUPP;
+
+ return tty->driver->ops->tiocmset(tty, set, clear);
+}
+
static const struct serdev_controller_ops ctrl_ops = {
.write_buf = ttyport_write_buf,
.write_flush = ttyport_write_flush,
@@ -175,6 +206,9 @@ static const struct serdev_controller_ops ctrl_ops = {
.close = ttyport_close,
.set_flow_control = ttyport_set_flow_control,
.set_baudrate = ttyport_set_baudrate,
+ .wait_until_sent = ttyport_wait_until_sent,
+ .get_tiocm = ttyport_get_tiocm,
+ .set_tiocm = ttyport_set_tiocm,
};
struct device *serdev_tty_port_register(struct tty_port *port,