lkml.org 
[lkml]   [2020]   [Nov]   [23]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.19 72/91] tty: serial: imx: keep console clocks always on
    Date
    From: Fugang Duan <fugang.duan@nxp.com>

    commit e67c139c488e84e7eae6c333231e791f0e89b3fb upstream.

    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: 1cf93e0d5488 ("serial: imx: remove the uart_console() check")
    Acked-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
    Signed-off-by: Fugang 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: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    drivers/tty/serial/imx.c | 20 +++-----------------
    1 file changed, 3 insertions(+), 17 deletions(-)

    --- a/drivers/tty/serial/imx.c
    +++ b/drivers/tty/serial/imx.c
    @@ -1915,16 +1915,6 @@ imx_uart_console_write(struct console *c
    unsigned int ucr1;
    unsigned long flags = 0;
    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)
    locked = 0;
    @@ -1960,9 +1950,6 @@ imx_uart_console_write(struct console *c

    if (locked)
    spin_unlock_irqrestore(&sport->port.lock, flags);
    -
    - clk_disable(sport->clk_ipg);
    - clk_disable(sport->clk_per);
    }

    /*
    @@ -2063,15 +2050,14 @@ imx_uart_console_setup(struct console *c

    retval = uart_set_options(&sport->port, co, baud, parity, bits, flow);

    - clk_disable(sport->clk_ipg);
    if (retval) {
    - clk_unprepare(sport->clk_ipg);
    + clk_disable_unprepare(sport->clk_ipg);
    goto error_console;
    }

    - retval = clk_prepare(sport->clk_per);
    + retval = clk_prepare_enable(sport->clk_per);
    if (retval)
    - clk_unprepare(sport->clk_ipg);
    + clk_disable_unprepare(sport->clk_ipg);

    error_console:
    return retval;

    \
     
     \ /
      Last update: 2020-11-23 14:41    [W:4.153 / U:0.132 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site