summaryrefslogtreecommitdiff
path: root/drivers/tty
diff options
context:
space:
mode:
authorChristoph Niedermaier <cniedermaier@dh-electronics.com>2023-12-26 14:36:47 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2024-01-26 02:35:43 +0300
commit45d709f3970effe7b1329e5e369301756f97b34e (patch)
treedc635a4bd627250feacd17c20c4a7b31e3fb46fc /drivers/tty
parent67043c0a6ed51ab31b34e43cf406b1c9f9895108 (diff)
downloadlinux-45d709f3970effe7b1329e5e369301756f97b34e.tar.xz
serial: imx: Ensure that imx_uart_rs485_config() is called with enabled clock
commit 7c45eaa813476bd195ac1227a64b52f9cf2e2030 upstream. There are register accesses in the function imx_uart_rs485_config(). The clock must be enabled for these accesses. This was ensured by calling it via the function uart_rs485_config() in the probe() function within the range where the clock is enabled. With the commit 7c7f9bc986e6 ("serial: Deassert Transmit Enable on probe in driver-specific way") it was removed from the probe() function and is now only called through the function uart_add_one_port() which is located at the end of the probe() function. But the clock is already switched off in this area. To ensure that the clock is enabled during register access, move the disabling of the clock to the very end of the probe() function. To avoid leaking enabled clocks on error also add an error path for exiting with disabling the clock. Fixes: 7c7f9bc986e6 ("serial: Deassert Transmit Enable on probe in driver-specific way") Cc: stable <stable@kernel.org> Signed-off-by: Christoph Niedermaier <cniedermaier@dh-electronics.com> Reviewed-by: Lukas Wunner <lukas@wunner.de> Link: https://lore.kernel.org/r/20231226113647.39376-1-cniedermaier@dh-electronics.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty')
-rw-r--r--drivers/tty/serial/imx.c23
1 files changed, 12 insertions, 11 deletions
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
index 230660c8b667..2e85c77e7c0d 100644
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -2328,10 +2328,8 @@ static int imx_uart_probe(struct platform_device *pdev)
}
ret = uart_get_rs485_mode(&sport->port);
- if (ret) {
- clk_disable_unprepare(sport->clk_ipg);
- return ret;
- }
+ if (ret)
+ goto err_clk;
/*
* If using the i.MX UART RTS/CTS control then the RTS (CTS_B)
@@ -2411,8 +2409,6 @@ static int imx_uart_probe(struct platform_device *pdev)
imx_uart_writel(sport, ucr3, UCR3);
}
- clk_disable_unprepare(sport->clk_ipg);
-
hrtimer_init(&sport->trigger_start_tx, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
hrtimer_init(&sport->trigger_stop_tx, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
sport->trigger_start_tx.function = imx_trigger_start_tx;
@@ -2428,7 +2424,7 @@ static int imx_uart_probe(struct platform_device *pdev)
if (ret) {
dev_err(&pdev->dev, "failed to request rx irq: %d\n",
ret);
- return ret;
+ goto err_clk;
}
ret = devm_request_irq(&pdev->dev, txirq, imx_uart_txint, 0,
@@ -2436,7 +2432,7 @@ static int imx_uart_probe(struct platform_device *pdev)
if (ret) {
dev_err(&pdev->dev, "failed to request tx irq: %d\n",
ret);
- return ret;
+ goto err_clk;
}
ret = devm_request_irq(&pdev->dev, rtsirq, imx_uart_rtsint, 0,
@@ -2444,14 +2440,14 @@ static int imx_uart_probe(struct platform_device *pdev)
if (ret) {
dev_err(&pdev->dev, "failed to request rts irq: %d\n",
ret);
- return ret;
+ goto err_clk;
}
} else {
ret = devm_request_irq(&pdev->dev, rxirq, imx_uart_int, 0,
dev_name(&pdev->dev), sport);
if (ret) {
dev_err(&pdev->dev, "failed to request irq: %d\n", ret);
- return ret;
+ goto err_clk;
}
}
@@ -2459,7 +2455,12 @@ static int imx_uart_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, sport);
- return uart_add_one_port(&imx_uart_uart_driver, &sport->port);
+ ret = uart_add_one_port(&imx_uart_uart_driver, &sport->port);
+
+err_clk:
+ clk_disable_unprepare(sport->clk_ipg);
+
+ return ret;
}
static int imx_uart_remove(struct platform_device *pdev)