diff options
author | Fugang Duan <b38611@freescale.com> | 2014-07-03 02:03:27 -0400 |
---|---|---|
committer | Fugang Duan <b38611@freescale.com> | 2014-07-04 00:59:43 -0400 |
commit | 982f8797664030b41e0bb0ad39f138767ab89c7c (patch) | |
tree | bd2efa76d5704e514516ae32c9b69b9cfb19a4b2 | |
parent | 2d7ed778613773fa7d8bfec33ffb9b6952f7bb9b (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.c | 20 |
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; |