drm-i915-force-full-modeset-if-the-connector-is-in-dpms-off-mode.patch
usb-serial-add-wait_until_sent-operation.patch
usb-serial-add-generic-wait_until_sent-implementation.patch
+usb-ftdi_sio-clean-up-get_modem_status.patch
+usb-ftdi_sio-fix-chars_in_buffer-overhead.patch
+usb-io_ti-fix-chars_in_buffer-overhead.patch
+usb-ti_usb_3410_5052-remove-lsr-from-port-data.patch
+usb-ti_usb_3410_5052-query-hardware-buffer-status-in-chars_in_buffer.patch
+usb-ti_usb_3410_5052-fix-chars_in_buffer-overhead.patch
--- /dev/null
+From c4133648bbce9e6b425a74cc890c8e4df51acaa9 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <jhovold@gmail.com>
+Date: Sun, 5 May 2013 20:32:29 +0200
+Subject: USB: ftdi_sio: clean up get_modem_status
+
+From: Johan Hovold <jhovold@gmail.com>
+
+commit c4133648bbce9e6b425a74cc890c8e4df51acaa9 upstream.
+
+Use usb-serial port rather than tty as argument to get_modem_status.
+
+Signed-off-by: Johan Hovold <jhovold@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/ftdi_sio.c | 9 ++++-----
+ 1 file changed, 4 insertions(+), 5 deletions(-)
+
+--- a/drivers/usb/serial/ftdi_sio.c
++++ b/drivers/usb/serial/ftdi_sio.c
+@@ -932,7 +932,7 @@ static int ftdi_ioctl(struct tty_struct
+ unsigned int cmd, unsigned long arg);
+ static void ftdi_break_ctl(struct tty_struct *tty, int break_state);
+ static int ftdi_chars_in_buffer(struct tty_struct *tty);
+-static int ftdi_get_modem_status(struct tty_struct *tty,
++static int ftdi_get_modem_status(struct usb_serial_port *port,
+ unsigned char status[2]);
+
+ static unsigned short int ftdi_232am_baud_base_to_divisor(int baud, int base);
+@@ -2104,7 +2104,7 @@ static int ftdi_chars_in_buffer(struct t
+ goto out;
+
+ /* Check if hardware buffer is empty. */
+- ret = ftdi_get_modem_status(tty, buf);
++ ret = ftdi_get_modem_status(port, buf);
+ if (ret == 2) {
+ if (!(buf[1] & FTDI_RS_TEMT))
+ chars = 1;
+@@ -2304,10 +2304,9 @@ no_c_cflag_changes:
+ * Returns the number of status bytes retrieved (device dependant), or
+ * negative error code.
+ */
+-static int ftdi_get_modem_status(struct tty_struct *tty,
++static int ftdi_get_modem_status(struct usb_serial_port *port,
+ unsigned char status[2])
+ {
+- struct usb_serial_port *port = tty->driver_data;
+ struct ftdi_private *priv = usb_get_serial_port_data(port);
+ unsigned char *buf;
+ int len;
+@@ -2372,7 +2371,7 @@ static int ftdi_tiocmget(struct tty_stru
+ unsigned char buf[2];
+ int ret;
+
+- ret = ftdi_get_modem_status(tty, buf);
++ ret = ftdi_get_modem_status(port, buf);
+ if (ret < 0)
+ return ret;
+
--- /dev/null
+From a37025b5c702aaf87191cd75fcc42c54454f16f5 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <jhovold@gmail.com>
+Date: Sun, 5 May 2013 20:32:30 +0200
+Subject: USB: ftdi_sio: fix chars_in_buffer overhead
+
+From: Johan Hovold <jhovold@gmail.com>
+
+commit a37025b5c702aaf87191cd75fcc42c54454f16f5 upstream.
+
+Use the new generic usb-serial wait_until_sent implementation to wait
+for hardware buffers to drain.
+
+This removes the need to check the hardware buffers in chars_in_buffer
+and thus removes the overhead introduced by commit 6f602912 ("usb:
+serial: ftdi_sio: Add missing chars_in_buffer function") without
+breaking tty_wait_until_sent (used by, for example, tcdrain, tcsendbreak
+and close).
+
+Reported-by: Stas Sergeev <stsp@list.ru>
+Signed-off-by: Johan Hovold <jhovold@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/ftdi_sio.c | 19 +++++--------------
+ 1 file changed, 5 insertions(+), 14 deletions(-)
+
+--- a/drivers/usb/serial/ftdi_sio.c
++++ b/drivers/usb/serial/ftdi_sio.c
+@@ -931,7 +931,7 @@ static int ftdi_get_icount(struct tty_st
+ static int ftdi_ioctl(struct tty_struct *tty,
+ unsigned int cmd, unsigned long arg);
+ static void ftdi_break_ctl(struct tty_struct *tty, int break_state);
+-static int ftdi_chars_in_buffer(struct tty_struct *tty);
++static bool ftdi_tx_empty(struct usb_serial_port *port);
+ static int ftdi_get_modem_status(struct usb_serial_port *port,
+ unsigned char status[2]);
+
+@@ -968,7 +968,7 @@ static struct usb_serial_driver ftdi_sio
+ .ioctl = ftdi_ioctl,
+ .set_termios = ftdi_set_termios,
+ .break_ctl = ftdi_break_ctl,
+- .chars_in_buffer = ftdi_chars_in_buffer,
++ .tx_empty = ftdi_tx_empty,
+ };
+
+ static struct usb_serial_driver * const serial_drivers[] = {
+@@ -2092,27 +2092,18 @@ static void ftdi_break_ctl(struct tty_st
+
+ }
+
+-static int ftdi_chars_in_buffer(struct tty_struct *tty)
++static bool ftdi_tx_empty(struct usb_serial_port *port)
+ {
+- struct usb_serial_port *port = tty->driver_data;
+- int chars;
+ unsigned char buf[2];
+ int ret;
+
+- chars = usb_serial_generic_chars_in_buffer(tty);
+- if (chars)
+- goto out;
+-
+- /* Check if hardware buffer is empty. */
+ ret = ftdi_get_modem_status(port, buf);
+ if (ret == 2) {
+ if (!(buf[1] & FTDI_RS_TEMT))
+- chars = 1;
++ return false;
+ }
+-out:
+- dev_dbg(&port->dev, "%s - %d\n", __func__, chars);
+
+- return chars;
++ return true;
+ }
+
+ /* old_termios contains the original termios settings and tty->termios contains
--- /dev/null
+From b16634adce951a7371be931487034f7365971ed0 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <jhovold@gmail.com>
+Date: Sun, 5 May 2013 20:32:31 +0200
+Subject: USB: io_ti: fix chars_in_buffer overhead
+
+From: Johan Hovold <jhovold@gmail.com>
+
+commit b16634adce951a7371be931487034f7365971ed0 upstream.
+
+Use the new generic usb-serial wait_until_sent implementation to wait
+for hardware buffers to drain.
+
+This removes the need to check the hardware buffers in chars_in_buffer
+and thus removes the overhead introduced by commit 263e1f9f ("USB:
+io_ti: query hardware-buffer status in chars_in_buffer") without
+breaking tty_wait_until_sent (used by, for example, tcdrain, tcsendbreak
+and close).
+
+Signed-off-by: Johan Hovold <jhovold@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/io_ti.c | 22 ++++++++++++++--------
+ 1 file changed, 14 insertions(+), 8 deletions(-)
+
+--- a/drivers/usb/serial/io_ti.c
++++ b/drivers/usb/serial/io_ti.c
+@@ -2033,8 +2033,6 @@ static int edge_chars_in_buffer(struct t
+ struct edgeport_port *edge_port = usb_get_serial_port_data(port);
+ int chars = 0;
+ unsigned long flags;
+- int ret;
+-
+ if (edge_port == NULL)
+ return 0;
+
+@@ -2042,16 +2040,22 @@ static int edge_chars_in_buffer(struct t
+ chars = kfifo_len(&edge_port->write_fifo);
+ spin_unlock_irqrestore(&edge_port->ep_lock, flags);
+
+- if (!chars) {
+- ret = tx_active(edge_port);
+- if (ret > 0)
+- chars = ret;
+- }
+-
+ dev_dbg(&port->dev, "%s - returns %d\n", __func__, chars);
+ return chars;
+ }
+
++static bool edge_tx_empty(struct usb_serial_port *port)
++{
++ struct edgeport_port *edge_port = usb_get_serial_port_data(port);
++ int ret;
++
++ ret = tx_active(edge_port);
++ if (ret > 0)
++ return false;
++
++ return true;
++}
++
+ static void edge_throttle(struct tty_struct *tty)
+ {
+ struct usb_serial_port *port = tty->driver_data;
+@@ -2622,6 +2626,7 @@ static struct usb_serial_driver edgeport
+ .write = edge_write,
+ .write_room = edge_write_room,
+ .chars_in_buffer = edge_chars_in_buffer,
++ .tx_empty = edge_tx_empty,
+ .break_ctl = edge_break,
+ .read_int_callback = edge_interrupt_callback,
+ .read_bulk_callback = edge_bulk_in_callback,
+@@ -2653,6 +2658,7 @@ static struct usb_serial_driver edgeport
+ .write = edge_write,
+ .write_room = edge_write_room,
+ .chars_in_buffer = edge_chars_in_buffer,
++ .tx_empty = edge_tx_empty,
+ .break_ctl = edge_break,
+ .read_int_callback = edge_interrupt_callback,
+ .read_bulk_callback = edge_bulk_in_callback,
--- /dev/null
+From ff93b19eed0d5c124ee7168650a8e2e120ac8ea4 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <jhovold@gmail.com>
+Date: Sun, 5 May 2013 20:32:32 +0200
+Subject: USB: ti_usb_3410_5052: fix chars_in_buffer overhead
+
+From: Johan Hovold <jhovold@gmail.com>
+
+commit ff93b19eed0d5c124ee7168650a8e2e120ac8ea4 upstream.
+
+Use the new generic usb-serial wait_until_sent implementation to wait
+for hardware buffers to drain.
+
+This removes the need to check the hardware buffers in chars_in_buffer
+and thus removes the overhead introduced by commit 2c992cd73 ("USB:
+ti_usb_3410_5052: query hardware-buffer status in chars_in_buffer")
+without breaking tty_wait_until_sent (used by, for example, tcdrain,
+tcsendbreak and close).
+
+Signed-off-by: Johan Hovold <jhovold@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/ti_usb_3410_5052.c | 23 +++++++++++++++--------
+ 1 file changed, 15 insertions(+), 8 deletions(-)
+
+--- a/drivers/usb/serial/ti_usb_3410_5052.c
++++ b/drivers/usb/serial/ti_usb_3410_5052.c
+@@ -103,6 +103,7 @@ static int ti_write(struct tty_struct *t
+ const unsigned char *data, int count);
+ static int ti_write_room(struct tty_struct *tty);
+ static int ti_chars_in_buffer(struct tty_struct *tty);
++static bool ti_tx_empty(struct usb_serial_port *port);
+ static void ti_throttle(struct tty_struct *tty);
+ static void ti_unthrottle(struct tty_struct *tty);
+ static int ti_ioctl(struct tty_struct *tty,
+@@ -228,6 +229,7 @@ static struct usb_serial_driver ti_1port
+ .write = ti_write,
+ .write_room = ti_write_room,
+ .chars_in_buffer = ti_chars_in_buffer,
++ .tx_empty = ti_tx_empty,
+ .throttle = ti_throttle,
+ .unthrottle = ti_unthrottle,
+ .ioctl = ti_ioctl,
+@@ -258,6 +260,7 @@ static struct usb_serial_driver ti_2port
+ .write = ti_write,
+ .write_room = ti_write_room,
+ .chars_in_buffer = ti_chars_in_buffer,
++ .tx_empty = ti_tx_empty,
+ .throttle = ti_throttle,
+ .unthrottle = ti_unthrottle,
+ .ioctl = ti_ioctl,
+@@ -686,8 +689,6 @@ static int ti_chars_in_buffer(struct tty
+ struct ti_port *tport = usb_get_serial_port_data(port);
+ int chars = 0;
+ unsigned long flags;
+- int ret;
+- u8 lsr;
+
+ if (tport == NULL)
+ return 0;
+@@ -696,16 +697,22 @@ static int ti_chars_in_buffer(struct tty
+ chars = kfifo_len(&tport->write_fifo);
+ spin_unlock_irqrestore(&tport->tp_lock, flags);
+
+- if (!chars) {
+- ret = ti_get_lsr(tport, &lsr);
+- if (!ret && !(lsr & TI_LSR_TX_EMPTY))
+- chars = 1;
+- }
+-
+ dev_dbg(&port->dev, "%s - returns %d\n", __func__, chars);
+ return chars;
+ }
+
++static bool ti_tx_empty(struct usb_serial_port *port)
++{
++ struct ti_port *tport = usb_get_serial_port_data(port);
++ int ret;
++ u8 lsr;
++
++ ret = ti_get_lsr(tport, &lsr);
++ if (!ret && !(lsr & TI_LSR_TX_EMPTY))
++ return false;
++
++ return true;
++}
+
+ static void ti_throttle(struct tty_struct *tty)
+ {
--- /dev/null
+From 2c992cd73772bd0ef107536e8e3399d28493caa8 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <jhovold@gmail.com>
+Date: Thu, 18 Apr 2013 17:33:21 +0200
+Subject: USB: ti_usb_3410_5052: query hardware-buffer status in chars_in_buffer
+
+From: Johan Hovold <jhovold@gmail.com>
+
+commit 2c992cd73772bd0ef107536e8e3399d28493caa8 upstream.
+
+Query hardware-buffer status in chars_in_buffer should the write fifo be
+empty.
+
+This is needed to make the tty layer wait for hardware buffers to drain
+on close.
+
+Signed-off-by: Johan Hovold <jhovold@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/ti_usb_3410_5052.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/drivers/usb/serial/ti_usb_3410_5052.c
++++ b/drivers/usb/serial/ti_usb_3410_5052.c
+@@ -686,6 +686,8 @@ static int ti_chars_in_buffer(struct tty
+ struct ti_port *tport = usb_get_serial_port_data(port);
+ int chars = 0;
+ unsigned long flags;
++ int ret;
++ u8 lsr;
+
+ if (tport == NULL)
+ return 0;
+@@ -694,6 +696,12 @@ static int ti_chars_in_buffer(struct tty
+ chars = kfifo_len(&tport->write_fifo);
+ spin_unlock_irqrestore(&tport->tp_lock, flags);
+
++ if (!chars) {
++ ret = ti_get_lsr(tport, &lsr);
++ if (!ret && !(lsr & TI_LSR_TX_EMPTY))
++ chars = 1;
++ }
++
+ dev_dbg(&port->dev, "%s - returns %d\n", __func__, chars);
+ return chars;
+ }
--- /dev/null
+From b5784f7d8528926d69c5868f1ddb2af99f85e799 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <jhovold@gmail.com>
+Date: Thu, 18 Apr 2013 17:33:20 +0200
+Subject: USB: ti_usb_3410_5052: remove lsr from port data
+
+From: Johan Hovold <jhovold@gmail.com>
+
+commit b5784f7d8528926d69c5868f1ddb2af99f85e799 upstream.
+
+The line status register is only polled so let's not keep a possibly
+outdated value in the port data.
+
+Signed-off-by: Johan Hovold <jhovold@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/serial/ti_usb_3410_5052.c | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+--- a/drivers/usb/serial/ti_usb_3410_5052.c
++++ b/drivers/usb/serial/ti_usb_3410_5052.c
+@@ -67,7 +67,6 @@
+ struct ti_port {
+ int tp_is_open;
+ __u8 tp_msr;
+- __u8 tp_lsr;
+ __u8 tp_shadow_mcr;
+ __u8 tp_uart_mode; /* 232 or 485 modes */
+ unsigned int tp_uart_base_addr;
+@@ -124,7 +123,7 @@ static void ti_recv(struct usb_serial_po
+ int length);
+ static void ti_send(struct ti_port *tport);
+ static int ti_set_mcr(struct ti_port *tport, unsigned int mcr);
+-static int ti_get_lsr(struct ti_port *tport);
++static int ti_get_lsr(struct ti_port *tport, u8 *lsr);
+ static int ti_get_serial_info(struct ti_port *tport,
+ struct serial_struct __user *ret_arg);
+ static int ti_set_serial_info(struct tty_struct *tty, struct ti_port *tport,
+@@ -1300,7 +1299,7 @@ static int ti_set_mcr(struct ti_port *tp
+ }
+
+
+-static int ti_get_lsr(struct ti_port *tport)
++static int ti_get_lsr(struct ti_port *tport, u8 *lsr)
+ {
+ int size, status;
+ struct ti_device *tdev = tport->tp_tdev;
+@@ -1326,7 +1325,7 @@ static int ti_get_lsr(struct ti_port *tp
+
+ dev_dbg(&port->dev, "%s - lsr 0x%02X\n", __func__, data->bLSR);
+
+- tport->tp_lsr = data->bLSR;
++ *lsr = data->bLSR;
+
+ free_data:
+ kfree(data);
+@@ -1419,6 +1418,7 @@ static void ti_drain(struct ti_port *tpo
+ struct ti_device *tdev = tport->tp_tdev;
+ struct usb_serial_port *port = tport->tp_port;
+ wait_queue_t wait;
++ u8 lsr;
+
+ spin_lock_irq(&tport->tp_lock);
+
+@@ -1450,11 +1450,11 @@ static void ti_drain(struct ti_port *tpo
+ /* wait for data to drain from the device */
+ /* wait for empty tx register, plus 20 ms */
+ timeout += jiffies;
+- tport->tp_lsr &= ~TI_LSR_TX_EMPTY;
++ lsr = 0;
+ while ((long)(jiffies - timeout) < 0 && !signal_pending(current)
+- && !(tport->tp_lsr&TI_LSR_TX_EMPTY) && !tdev->td_urb_error
++ && !(lsr & TI_LSR_TX_EMPTY) && !tdev->td_urb_error
+ && !port->serial->disconnected) {
+- if (ti_get_lsr(tport))
++ if (ti_get_lsr(tport, &lsr))
+ break;
+ mutex_unlock(&port->serial->disc_mutex);
+ msleep_interruptible(20);