summary refs log tree commit diff
path: root/drivers/tty
diff options
context:
space:
mode:
authorHuang Shijie <b32955@freescale.com>2013-10-11 18:30:58 +0800
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-10-16 13:19:54 -0700
commiteb56b7edae6ba2bfd3a07e59ea82195e2c1c28ec (patch)
tree5fdaab8e8a4e33e2f4b63f6d82629e02a6a0a163 /drivers/tty
parentfa2b5ea09e48186041f68649ab8192447b31bffc (diff)
downloadlinux-eb56b7edae6ba2bfd3a07e59ea82195e2c1c28ec.tar.gz
serial: imx: implement the flush_buffer hook
The current driver does not implement the flush_buffer hook for
uart_ops. When we enable the DMA for the driver, and test it with Bluetooth,
we may meet the following bug for TX:

    [1] User application may call the flush operation at any time.
        The uart_flush_buffer() calls the uart_circ_clear() to set
        the xmit->head and xmit->tail with 0.

    [2] The TX DMA callback can be called at any time too.
        The dma_tx_call() will update the xmit->tail.

    If [2] occurs just after the [1], we will get the wrong xmit->tail.

This patch implements the flush_buffer hook to fix this issue.

Signed-off-by: Huang Shijie <b32955@freescale.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty')
-rw-r--r--drivers/tty/serial/imx.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
index c07d9bb39695..708ba899258d 100644
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -1303,6 +1303,16 @@ static void imx_shutdown(struct uart_port *port)
 	clk_disable_unprepare(sport->clk_ipg);
 }
 
+static void imx_flush_buffer(struct uart_port *port)
+{
+	struct imx_port *sport = (struct imx_port *)port;
+
+	if (sport->dma_is_enabled) {
+		sport->tx_bytes = 0;
+		dmaengine_terminate_all(sport->dma_chan_tx);
+	}
+}
+
 static void
 imx_set_termios(struct uart_port *port, struct ktermios *termios,
 		   struct ktermios *old)
@@ -1623,6 +1633,7 @@ static struct uart_ops imx_pops = {
 	.break_ctl	= imx_break_ctl,
 	.startup	= imx_startup,
 	.shutdown	= imx_shutdown,
+	.flush_buffer	= imx_flush_buffer,
 	.set_termios	= imx_set_termios,
 	.type		= imx_type,
 	.release_port	= imx_release_port,