Skip to content

Commit

Permalink
serial: imx: reset the uart port all the time
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Huang Shijie authored and Greg Kroah-Hartman committed May 28, 2014
1 parent 0c6d774 commit 772f899
Showing 1 changed file with 10 additions and 12 deletions.
22 changes: 10 additions & 12 deletions drivers/tty/serial/imx.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 772f899

Please sign in to comment.