summaryrefslogtreecommitdiff
path: root/drivers/tty/serial/imx.c
diff options
context:
space:
mode:
authorAndrey Zhizhikin <andrey.zhizhikin@leica-geosystems.com>2021-01-11 11:29:40 +0000
committerAndrey Zhizhikin <andrey.zhizhikin@leica-geosystems.com>2021-01-11 11:29:40 +0000
commit25100dfc5e6c59f35ca8d3f777c89dec040115b9 (patch)
treefbf9862c2a2bbb324d0c028aaacf69b4a626cb1a /drivers/tty/serial/imx.c
parent246719db080b1ee3fdd1ce582c9f3fed74e0f418 (diff)
parent9f4b26f3ea18cb2066c9e58a84ff202c71739a41 (diff)
Merge tag 'v5.4.80' into 5.4-2.3.x-imx
This is the 5.4.80 stable release Conflicts (manual resolve): - arch/arm64/boot/dts/freescale/imx8mn.dtsi: Fix minor merge conflict where commit [8381af1b684c] in stable tree removed one blank line. - drivers/net/can/flexcan.c: Fix merge fuzz during integration of stable commit [4c0a778fcf7b5]. Signed-off-by: Andrey Zhizhikin <andrey.zhizhikin@leica-geosystems.com>
Diffstat (limited to 'drivers/tty/serial/imx.c')
-rw-r--r--drivers/tty/serial/imx.c30
1 files changed, 11 insertions, 19 deletions
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
index 43c6d7142fdd..dd92afdee2d2 100644
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -886,8 +886,14 @@ static irqreturn_t imx_uart_int(int irq, void *dev_id)
struct imx_port *sport = dev_id;
unsigned int usr1, usr2, ucr1, ucr2, ucr3, ucr4;
irqreturn_t ret = IRQ_NONE;
+ unsigned long flags = 0;
- spin_lock(&sport->port.lock);
+ /*
+ * IRQs might not be disabled upon entering this interrupt handler,
+ * e.g. when interrupt handlers are forced to be threaded. To support
+ * this scenario as well, disable IRQs when acquiring the spinlock.
+ */
+ spin_lock_irqsave(&sport->port.lock, flags);
usr1 = imx_uart_readl(sport, USR1);
usr2 = imx_uart_readl(sport, USR2);
@@ -955,7 +961,7 @@ static irqreturn_t imx_uart_int(int irq, void *dev_id)
ret = IRQ_HANDLED;
}
- spin_unlock(&sport->port.lock);
+ spin_unlock_irqrestore(&sport->port.lock, flags);
return ret;
}
@@ -1960,16 +1966,6 @@ imx_uart_console_write(struct console *co, const char *s, unsigned int count)
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;
@@ -2005,9 +2001,6 @@ imx_uart_console_write(struct console *co, const char *s, unsigned int count)
if (locked)
spin_unlock_irqrestore(&sport->port.lock, flags);
-
- clk_disable(sport->clk_ipg);
- clk_disable(sport->clk_per);
}
/*
@@ -2108,15 +2101,14 @@ imx_uart_console_setup(struct console *co, char *options)
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;