diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-12-12 12:51:05 +0100 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-12-12 12:51:05 +0100 |
commit | c1ed47355467d03639b750570b4324f7c1eed68c (patch) | |
tree | ad1994abec3acf822ccd4b74b1121599e5b1c148 /drivers/tty/serdev/serdev-ttyport.c | |
parent | 72b663a99c074a8d073e7ecdae446cfb024ef551 (diff) | |
parent | 9dbe416b656bb015fc49fc17961000ffa418838a (diff) | |
download | linux-c1ed47355467d03639b750570b4324f7c1eed68c.tar.bz2 |
Merge tag 'fixes-for-v4.15-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb into usb-linus
Felipe writes:
usb: fixes for v4.15-rc4
We have a few fixes on dwc3:
- one fix which only happens with some implementations where we need to
wait longer for some commands to finish.
- Another fix for high-bandwidth isochronous endpoint programming making
sure that we send the correct DATA tokens in the correct sequence
- A couple PM fixes on dwc3-of-simple
The other synopsys controller driver (dwc2) got a fix for FIFO size
programming.
Other than these, we have a couple Kconfig fixes making sure that
dependencies are properly setup.
Diffstat (limited to 'drivers/tty/serdev/serdev-ttyport.c')
-rw-r--r-- | drivers/tty/serdev/serdev-ttyport.c | 26 |
1 files changed, 23 insertions, 3 deletions
diff --git a/drivers/tty/serdev/serdev-ttyport.c b/drivers/tty/serdev/serdev-ttyport.c index ce7ad0acee7a..247788a16f0b 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 = { @@ -136,8 +154,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); } |