]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
MLK-9893 tty: serial: imx: sync the completed and cur index
authorFugang Duan <b38611@freescale.com>
Thu, 20 Nov 2014 09:50:41 +0000 (17:50 +0800)
committerNitin Garg <nitin.garg@freescale.com>
Fri, 16 Jan 2015 03:18:37 +0000 (21:18 -0600)
The current logic has one potential issue cause data buffer lost in
busy system. When sdma copy data buffer count is zero, completed index
also increase, which cause data buffer lost. The patch fix the issue.

(cherry-picked from commit: f7b01c9263ea73b9150e8a7fa48812c1d47d0493)

Signed-off-by: Fugang Duan <B38611@freescale.com>
drivers/tty/serial/imx.c

index 62c0e4ce2992085085c48b15a2e02ea525be7eae..94aba1dae198306fdd52ca4c15010f093932eb4a 100644 (file)
@@ -918,16 +918,16 @@ static void dma_rx_work(struct work_struct *w)
 {
        struct imx_port *sport = container_of(w, struct imx_port, tsk_dma_rx);
        struct tty_struct *tty = sport->port.state->port.tty;
+       unsigned int cur_idx = sport->rx_buf.cur_idx;
 
-       if (sport->rx_buf.last_completed_idx < sport->rx_buf.cur_idx) {
-               dma_rx_push_data(sport, tty, sport->rx_buf.last_completed_idx + 1,
-                                       sport->rx_buf.cur_idx);
+       if (sport->rx_buf.last_completed_idx < cur_idx) {
+               dma_rx_push_data(sport, tty, sport->rx_buf.last_completed_idx + 1, cur_idx);
        } else if (sport->rx_buf.last_completed_idx == (IMX_RXBD_NUM - 1)) {
-               dma_rx_push_data(sport, tty, 0, sport->rx_buf.cur_idx);
+               dma_rx_push_data(sport, tty, 0, cur_idx);
        } else {
                dma_rx_push_data(sport, tty, sport->rx_buf.last_completed_idx + 1,
                                        IMX_RXBD_NUM);
-               dma_rx_push_data(sport, tty, 0, sport->rx_buf.cur_idx);
+               dma_rx_push_data(sport, tty, 0, cur_idx);
        }
 }
 
@@ -976,12 +976,8 @@ static void dma_rx_callback(void *data)
        if (sport->rx_buf.cur_idx == sport->rx_buf.last_completed_idx)
                dev_err(sport->port.dev, "overwrite!\n");
 
-       if (count) {
+       if (count)
                schedule_work(&sport->tsk_dma_rx);
-       } else {
-               sport->rx_buf.last_completed_idx++;
-               sport->rx_buf.last_completed_idx %= IMX_RXBD_NUM;
-       }
 }
 
 static int start_rx_dma(struct imx_port *sport)