aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHuang Shijie <b32955@freescale.com>2014-05-20 20:56:28 -0400
committerHuang Shijie <b32955@freescale.com>2014-06-03 00:46:56 -0400
commit985fcdf2af051981b66fde64d32f51cf514dc808 (patch)
treefc08233fc42c8c34ef5c786c2818633b4fa21860
parent7be82a194bc96e8f1d3189e0c0cae50ac2f07d97 (diff)
serial: imx: reset the uart port all the time
Current code resets the uart port only when it supports the irda mode. In actually, we also need to reset the uart port in the non-irda mode. A hang was caught in the following case: UART A transmits data to the other end. But the transmission maybe terminated. In some corner case, the TX FIFO maybe not empty. The kernel will hang at the imx_set_termios(): ............................................................ while (!(readl(sport->port.membase + USR2) & USR2_TXDC)) barrier(); ............................................................ This patch resets the uart port all the time in the imx_startup(). And fix the hang. Signed-off-by: Huang Shijie <b32955@freescale.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/tty/serial/imx.c22
1 files changed, 10 insertions, 12 deletions
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
index 392154d13614..060ae9753923 100644
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -1070,7 +1070,7 @@ static void imx_disable_dma(struct imx_port *sport)
1070static int imx_startup(struct uart_port *port) 1070static int imx_startup(struct uart_port *port)
1071{ 1071{
1072 struct imx_port *sport = (struct imx_port *)port; 1072 struct imx_port *sport = (struct imx_port *)port;
1073 int retval; 1073 int retval, i;
1074 unsigned long flags, temp; 1074 unsigned long flags, temp;
1075 1075
1076 retval = clk_prepare_enable(sport->clk_per); 1076 retval = clk_prepare_enable(sport->clk_per);
@@ -1098,17 +1098,15 @@ static int imx_startup(struct uart_port *port)
1098 1098
1099 writel(temp & ~UCR4_DREN, sport->port.membase + UCR4); 1099 writel(temp & ~UCR4_DREN, sport->port.membase + UCR4);
1100 1100
1101 if (USE_IRDA(sport)) { 1101 /* Reset fifo's and state machines */
1102 /* reset fifo's and state machines */ 1102 i = 100;
1103 int i = 100; 1103
1104 temp = readl(sport->port.membase + UCR2); 1104 temp = readl(sport->port.membase + UCR2);
1105 temp &= ~UCR2_SRST; 1105 temp &= ~UCR2_SRST;
1106 writel(temp, sport->port.membase + UCR2); 1106 writel(temp, sport->port.membase + UCR2);
1107 while (!(readl(sport->port.membase + UCR2) & UCR2_SRST) && 1107
1108 (--i > 0)) { 1108 while (!(readl(sport->port.membase + UCR2) & UCR2_SRST) && (--i > 0))
1109 udelay(1); 1109 udelay(1);
1110 }
1111 }
1112 1110
1113 /* 1111 /*
1114 * Allocate the IRQ(s) i.MX1 has three interrupts whereas later 1112 * Allocate the IRQ(s) i.MX1 has three interrupts whereas later