Revert "serial: imx: always wake up the processes in the TX callback"
authorJiada Wang <jiada_wang@mentor.com>
Tue, 9 Dec 2014 09:11:29 +0000 (18:11 +0900)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 9 Jan 2015 22:23:07 +0000 (14:23 -0800)
This reverts commit 2ad28e3efee21a5bbf940c83d1f0395b76bd3efb.

Instead of always wake up write_wait process in TX callback,
TX callback should call imx_dma_tx() again, and let imx_dma_tx
transfer the remaining data in circle buffer.

The issue with commit 2ad28e3 is, in case there is remaining
data in circle buffer, but no process is waiting on write_wait
queue, then as no following uart_write() will be called after
uart_write_wakeup(), thus cause data loss.

Moreover according to Documentation/serial/driver, uart_write_wakeup()
should be called in case the transmit buffer have dropped below
a threshold.

Signed-off-by: Jiada Wang <jiada_wang@mentor.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/tty/serial/imx.c

index 1c4f367b6fb6f458987d505e0bfd8a95ce347c6c..73158d96822a0269a5a2d523f369783e3c8edfd7 100644 (file)
@@ -516,7 +516,8 @@ static void dma_tx_callback(void *data)
 
        spin_unlock_irqrestore(&sport->port.lock, flags);
 
-       uart_write_wakeup(&sport->port);
+       if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+               uart_write_wakeup(&sport->port);
 
        if (waitqueue_active(&sport->dma_wait)) {
                wake_up(&sport->dma_wait);