Commit e95044ba authored by David Jander's avatar David Jander Committed by Greg Kroah-Hartman

tty: serial: imx.c: Reset UART before activating interrupts

If the UART has been in use before this driver was loaded, IRQs might be
active and get fired as soon as we set the handler, which will crash
in the spin_lock_irqsave(&sport->port.lock, flags) because port.lock is
not initialized until the port is added at the end of probe.
Signed-off-by: default avatarDavid Jander <david@protonic.nl>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent e9b5a982
...@@ -1098,10 +1098,23 @@ static void imx_disable_dma(struct imx_port *sport) ...@@ -1098,10 +1098,23 @@ static void imx_disable_dma(struct imx_port *sport)
/* half the RX buffer size */ /* half the RX buffer size */
#define CTSTL 16 #define CTSTL 16
static inline void imx_reset(struct imx_port *sport)
{
int i = 100;
unsigned long temp;
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);
}
static int imx_startup(struct uart_port *port) static int imx_startup(struct uart_port *port)
{ {
struct imx_port *sport = (struct imx_port *)port; struct imx_port *sport = (struct imx_port *)port;
int retval, i; int retval;
unsigned long flags, temp; unsigned long flags, temp;
retval = clk_prepare_enable(sport->clk_per); retval = clk_prepare_enable(sport->clk_per);
...@@ -1133,14 +1146,7 @@ static int imx_startup(struct uart_port *port) ...@@ -1133,14 +1146,7 @@ static int imx_startup(struct uart_port *port)
spin_lock_irqsave(&sport->port.lock, flags); spin_lock_irqsave(&sport->port.lock, flags);
/* Reset fifo's and state machines */ /* Reset fifo's and state machines */
i = 100; imx_reset(sport);
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);
/* /*
* Finally, clear and enable interrupts * Finally, clear and enable interrupts
...@@ -1975,6 +1981,14 @@ static int serial_imx_probe(struct platform_device *pdev) ...@@ -1975,6 +1981,14 @@ static int serial_imx_probe(struct platform_device *pdev)
clk_disable_unprepare(sport->clk_ipg); clk_disable_unprepare(sport->clk_ipg);
/*
* Perform a complete reset of the UART device. Needed if we don't
* come straight out of reset.
*/
writel(0, sport->port.membase + UCR2);
writel(0, sport->port.membase + UCR1);
imx_reset(sport);
/* /*
* Allocate the IRQ(s) i.MX1 has three interrupts whereas later * Allocate the IRQ(s) i.MX1 has three interrupts whereas later
* chips only have one interrupt. * chips only have one interrupt.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment