summaryrefslogtreecommitdiffstats
path: root/drivers/tty
diff options
context:
space:
mode:
authorHuang Shijie <b32955@freescale.com>2014-05-21 02:56:28 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-05-28 21:39:46 +0200
commit772f89910a8a1d1dd9dade2eec3125f283a9db63 (patch)
tree97db2ad68cbe8543a12928812c7e8f94a95d09cc /drivers/tty
parentserial: Add support for Advantech PCM-3614I/PCM-3618I serial expansion cards (diff)
downloadlinux-772f89910a8a1d1dd9dade2eec3125f283a9db63.tar.xz
linux-772f89910a8a1d1dd9dade2eec3125f283a9db63.zip
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>
Diffstat (limited to 'drivers/tty')
-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)
static int imx_startup(struct uart_port *port)
{
struct imx_port *sport = (struct imx_port *)port;
- int retval;
+ int retval, i;
unsigned long flags, temp;
retval = clk_prepare_enable(sport->clk_per);
@@ -1098,17 +1098,15 @@ static int imx_startup(struct uart_port *port)
writel(temp & ~UCR4_DREN, sport->port.membase + UCR4);
- if (USE_IRDA(sport)) {
- /* reset fifo's and state machines */
- int i = 100;
- temp = readl(sport->port.membase + UCR2);
- temp &= ~UCR2_SRST;
- writel(temp, sport->port.membase + UCR2);
- while (!(readl(sport->port.membase + UCR2) & UCR2_SRST) &&
- (--i > 0)) {
- udelay(1);
- }
- }
+ /* Reset fifo's and state machines */
+ i = 100;
+
+ temp = readl(sport->port.membase + UCR2);
+ temp &= ~UCR2_SRST;
+ writel(temp, sport->port.membase + UCR2);
+
+ while (!(readl(sport->port.membase + UCR2) & UCR2_SRST) && (--i > 0))
+ udelay(1);
/*
* Allocate the IRQ(s) i.MX1 has three interrupts whereas later