The patch below does not apply to the 5.10-stable tree. If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to stable@vger.kernel.org.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-5.10.y git checkout FETCH_HEAD git cherry-pick -x daeb4037adf7d3349b4a1fb792f4bc9824686a4b # <resolve conflicts, build, test, etc.> git commit -s git send-email --to 'stable@vger.kernel.org' --in-reply-to '2025102700-sleep-robotics-c9e3@gregkh' --subject-prefix 'PATCH 5.10.y' HEAD^..
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From daeb4037adf7d3349b4a1fb792f4bc9824686a4b Mon Sep 17 00:00:00 2001 From: Artem Shimko a.shimko.dev@gmail.com Date: Sun, 19 Oct 2025 12:51:31 +0300 Subject: [PATCH] serial: 8250_dw: handle reset control deassert error
Check the return value of reset_control_deassert() in the probe function to prevent continuing probe when reset deassertion fails.
Previously, reset_control_deassert() was called without checking its return value, which could lead to probe continuing even when the device reset wasn't properly deasserted.
The fix checks the return value and returns an error with dev_err_probe() if reset deassertion fails, providing better error handling and diagnostics.
Fixes: acbdad8dd1ab ("serial: 8250_dw: simplify optional reset handling") Cc: stable stable@kernel.org Signed-off-by: Artem Shimko a.shimko.dev@gmail.com Link: https://patch.msgid.link/20251019095131.252848-1-a.shimko.dev@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org
diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c index a53ba04d9770..710ae4d40aec 100644 --- a/drivers/tty/serial/8250/8250_dw.c +++ b/drivers/tty/serial/8250/8250_dw.c @@ -635,7 +635,9 @@ static int dw8250_probe(struct platform_device *pdev) if (IS_ERR(data->rst)) return PTR_ERR(data->rst);
- reset_control_deassert(data->rst); + err = reset_control_deassert(data->rst); + if (err) + return dev_err_probe(dev, err, "failed to deassert resets\n");
err = devm_add_action_or_reset(dev, dw8250_reset_control_assert, data->rst); if (err)
From: Andy Shevchenko andriy.shevchenko@linux.intel.com
[ Upstream commit 295b09128d12fb1a7a67f771cc0ae0df869eafaf ]
Slightly simplify ->probe() and drop a few goto labels by using devm_add_action_or_reset() for clock and reset cleanup.
Signed-off-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Link: https://lore.kernel.org/r/20220509172129.37770-1-andriy.shevchenko@linux.int... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Stable-dep-of: daeb4037adf7 ("serial: 8250_dw: handle reset control deassert error") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/serial/8250/8250_dw.c | 63 +++++++++++++++---------------- 1 file changed, 31 insertions(+), 32 deletions(-)
diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c index ace221afeb039..6abdebb63ecbe 100644 --- a/drivers/tty/serial/8250/8250_dw.c +++ b/drivers/tty/serial/8250/8250_dw.c @@ -438,6 +438,16 @@ static void dw8250_quirks(struct uart_port *p, struct dw8250_data *data) } }
+static void dw8250_clk_disable_unprepare(void *data) +{ + clk_disable_unprepare(data); +} + +static void dw8250_reset_control_assert(void *data) +{ + reset_control_assert(data); +} + static int dw8250_probe(struct platform_device *pdev) { struct uart_8250_port uart = {}, *up = &uart; @@ -539,35 +549,43 @@ static int dw8250_probe(struct platform_device *pdev) if (err) dev_warn(dev, "could not enable optional baudclk: %d\n", err);
+ err = devm_add_action_or_reset(dev, dw8250_clk_disable_unprepare, data->clk); + if (err) + return err; + if (data->clk) p->uartclk = clk_get_rate(data->clk);
/* If no clock rate is defined, fail. */ if (!p->uartclk) { dev_err(dev, "clock rate not defined\n"); - err = -EINVAL; - goto err_clk; + return -EINVAL; }
data->pclk = devm_clk_get_optional(dev, "apb_pclk"); - if (IS_ERR(data->pclk)) { - err = PTR_ERR(data->pclk); - goto err_clk; - } + if (IS_ERR(data->pclk)) + return PTR_ERR(data->pclk);
err = clk_prepare_enable(data->pclk); if (err) { dev_err(dev, "could not enable apb_pclk\n"); - goto err_clk; + return err; }
+ err = devm_add_action_or_reset(dev, dw8250_clk_disable_unprepare, data->pclk); + if (err) + return err; + data->rst = devm_reset_control_get_optional_exclusive(dev, NULL); - if (IS_ERR(data->rst)) { - err = PTR_ERR(data->rst); - goto err_pclk; - } + if (IS_ERR(data->rst)) + return PTR_ERR(data->rst); + reset_control_deassert(data->rst);
+ err = devm_add_action_or_reset(dev, dw8250_reset_control_assert, data->rst); + if (err) + return err; + dw8250_quirks(p, data);
/* If the Busy Functionality is not implemented, don't handle it */ @@ -585,10 +603,8 @@ static int dw8250_probe(struct platform_device *pdev) }
data->data.line = serial8250_register_8250_port(up); - if (data->data.line < 0) { - err = data->data.line; - goto err_reset; - } + if (data->data.line < 0) + return data->data.line;
/* * Some platforms may provide a reference clock shared between several @@ -609,17 +625,6 @@ static int dw8250_probe(struct platform_device *pdev) pm_runtime_enable(dev);
return 0; - -err_reset: - reset_control_assert(data->rst); - -err_pclk: - clk_disable_unprepare(data->pclk); - -err_clk: - clk_disable_unprepare(data->clk); - - return err; }
static int dw8250_remove(struct platform_device *pdev) @@ -637,12 +642,6 @@ static int dw8250_remove(struct platform_device *pdev)
serial8250_unregister_port(data->data.line);
- reset_control_assert(data->rst); - - clk_disable_unprepare(data->pclk); - - clk_disable_unprepare(data->clk); - pm_runtime_disable(dev); pm_runtime_put_noidle(dev);
From: Artem Shimko a.shimko.dev@gmail.com
[ Upstream commit daeb4037adf7d3349b4a1fb792f4bc9824686a4b ]
Check the return value of reset_control_deassert() in the probe function to prevent continuing probe when reset deassertion fails.
Previously, reset_control_deassert() was called without checking its return value, which could lead to probe continuing even when the device reset wasn't properly deasserted.
The fix checks the return value and returns an error with dev_err_probe() if reset deassertion fails, providing better error handling and diagnostics.
Fixes: acbdad8dd1ab ("serial: 8250_dw: simplify optional reset handling") Cc: stable stable@kernel.org Signed-off-by: Artem Shimko a.shimko.dev@gmail.com Link: https://patch.msgid.link/20251019095131.252848-1-a.shimko.dev@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/serial/8250/8250_dw.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c index 6abdebb63ecbe..bcf770f344dac 100644 --- a/drivers/tty/serial/8250/8250_dw.c +++ b/drivers/tty/serial/8250/8250_dw.c @@ -580,7 +580,9 @@ static int dw8250_probe(struct platform_device *pdev) if (IS_ERR(data->rst)) return PTR_ERR(data->rst);
- reset_control_deassert(data->rst); + err = reset_control_deassert(data->rst); + if (err) + return dev_err_probe(dev, err, "failed to deassert resets\n");
err = devm_add_action_or_reset(dev, dw8250_reset_control_assert, data->rst); if (err)
linux-stable-mirror@lists.linaro.org