aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFugang Duan <b38611@freescale.com>2014-07-03 02:03:27 -0400
committerFugang Duan <b38611@freescale.com>2014-07-04 00:59:43 -0400
commit982f8797664030b41e0bb0ad39f138767ab89c7c (patch)
treebd2efa76d5704e514516ae32c9b69b9cfb19a4b2
parent2d7ed778613773fa7d8bfec33ffb9b6952f7bb9b (diff)
ENGR00321246 tty: serial: imx: fix wakeup fail after suspend for more than 30s
Before DMA finish, we have to disable flow control, otherwise there have one corner issue like: Flow control enable, RTS always is high while there have no uart terminal connect to imx uart, and then user transmit data by the uart, after some time, TX FIFO is _FULL_, SDMA still don't complete the current transcation, so hold on. There no SDMA interrupt generate, the "dma_wait" event cannot be waked up. Signed-off-by: Fugang Duan <B38611@freescale.com>
-rw-r--r--drivers/tty/serial/imx.c20
1 files changed, 18 insertions, 2 deletions
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
index fc82b6efb0ef..a8f2215dffbc 100644
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -1227,9 +1227,25 @@ static void imx_shutdown(struct uart_port *port)
1227 if (sport->dma_is_enabled) { 1227 if (sport->dma_is_enabled) {
1228 int ret; 1228 int ret;
1229 1229
1230 /*
1231 * Before DMA finish, we have to disable flow control, otherwise
1232 * there have one corner issue like:
1233 * Flow control enable, RTS always is high while there have no uart
1234 * terminal connect to imx uart, and then user transmit data by the
1235 * uart, after some time, TX FIFO is _FULL_, SDMA still don't complete
1236 * the current transcation, so hold on. There no SDMA interrupt generate,
1237 * the "dma_wait" event cannot be waked up.
1238 */
1239 if (sport->have_rtscts) {
1240 temp = readl(sport->port.membase + UCR2) & ~UCR2_CTSC;
1241 temp |= UCR2_CTS;
1242 writel(temp, sport->port.membase + UCR2);
1243 }
1244
1230 /* We have to wait for the DMA to finish. */ 1245 /* We have to wait for the DMA to finish. */
1231 ret = wait_event_interruptible(sport->dma_wait, 1246 ret = wait_event_interruptible_timeout(sport->dma_wait,
1232 !sport->dma_is_rxing && !sport->dma_is_txing); 1247 !sport->dma_is_rxing && !sport->dma_is_txing,
1248 msecs_to_jiffies(1));
1233 if (ret != 0) { 1249 if (ret != 0) {
1234 sport->dma_is_rxing = 0; 1250 sport->dma_is_rxing = 0;
1235 sport->dma_is_txing = 0; 1251 sport->dma_is_txing = 0;