Commit e67c139c authored by Fugang Duan's avatar Fugang Duan Committed by Greg Kroah-Hartman

tty: serial: imx: keep console clocks always on

For below code, there has chance to cause deadlock in SMP system:
Thread 1:
clk_enable_lock();
pr_info("debug message");
clk_enable_unlock();

Thread 2:
imx_uart_console_write()
	clk_enable()
		clk_enable_lock();

Thread 1:
Acuired clk enable_lock -> printk -> console_trylock_spinning
Thread 2:
console_unlock() -> imx_uart_console_write -> clk_disable -> Acquite clk enable_lock

So the patch is to keep console port clocks always on like
other console drivers.

Fixes: 1cf93e0d ("serial: imx: remove the uart_console() check")
Acked-by: default avatarUwe Kleine-König <u.kleine-koenig@pengutronix.de>
Signed-off-by: default avatarFugang Duan <fugang.duan@nxp.com>
Link: https://lore.kernel.org/r/20201111025136.29818-1-fugang.duan@nxp.com
Cc: stable <stable@vger.kernel.org>
[fix up build warning - gregkh]
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent d4122754
...@@ -2008,16 +2008,6 @@ imx_uart_console_write(struct console *co, const char *s, unsigned int count) ...@@ -2008,16 +2008,6 @@ imx_uart_console_write(struct console *co, const char *s, unsigned int count)
unsigned int ucr1; unsigned int ucr1;
unsigned long flags = 0; unsigned long flags = 0;
int locked = 1; int locked = 1;
int retval;
retval = clk_enable(sport->clk_per);
if (retval)
return;
retval = clk_enable(sport->clk_ipg);
if (retval) {
clk_disable(sport->clk_per);
return;
}
if (sport->port.sysrq) if (sport->port.sysrq)
locked = 0; locked = 0;
...@@ -2053,9 +2043,6 @@ imx_uart_console_write(struct console *co, const char *s, unsigned int count) ...@@ -2053,9 +2043,6 @@ imx_uart_console_write(struct console *co, const char *s, unsigned int count)
if (locked) if (locked)
spin_unlock_irqrestore(&sport->port.lock, flags); spin_unlock_irqrestore(&sport->port.lock, flags);
clk_disable(sport->clk_ipg);
clk_disable(sport->clk_per);
} }
/* /*
...@@ -2156,15 +2143,14 @@ imx_uart_console_setup(struct console *co, char *options) ...@@ -2156,15 +2143,14 @@ imx_uart_console_setup(struct console *co, char *options)
retval = uart_set_options(&sport->port, co, baud, parity, bits, flow); retval = uart_set_options(&sport->port, co, baud, parity, bits, flow);
clk_disable(sport->clk_ipg);
if (retval) { if (retval) {
clk_unprepare(sport->clk_ipg); clk_disable_unprepare(sport->clk_ipg);
goto error_console; goto error_console;
} }
retval = clk_prepare(sport->clk_per); retval = clk_prepare_enable(sport->clk_per);
if (retval) if (retval)
clk_unprepare(sport->clk_ipg); clk_disable_unprepare(sport->clk_ipg);
error_console: error_console:
return retval; return retval;
......
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