FAILED: patch "[PATCH] serial: 8250_dw: handle reset control deassert error" failed to apply to 5.4-stable tree
Subsystems (4)
[email protected]
maintainerThe patch below does not apply to the 5.4-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 <[email protected]>.
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.4.y
git checkout FETCH_HEAD
git cherry-pick -x daeb4037adf7d3349b4a1fb792f4bc9824686a4b
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2025102701-scabby-entrust-a162@gregkh' --subject-prefix 'PATCH 5.4.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 <[email protected]>
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.
drivers/tty/serial/8250/8250_dw.c +3 -1
@@ -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)
Sasha Levin
maintainerPATCH 1/3 serial: 8250_dw: Use devm_clk_get_optional() to get the input clock
From: Andy Shevchenko <[email protected]>
[ Upstream commit a8afc193558a42d5df724c84436ae3b2446d8a30 ]
Simplify the code which fetches the input clock by using devm_clk_get_optional(). This comes with a small functional change: previously all errors were ignored except deferred probe. Now all errors are treated as errors. If no input clock is present devm_clk_get_optional() will return NULL instead of an error which matches the behavior of the old code.
Stable-dep-of: daeb4037adf7 ("serial: 8250_dw: handle reset control deassert error")
--- drivers/tty/serial/8250/8250_dw.c | 75 +++++++++++++------------------ 1 file changed, 32 insertions(+), 43 deletions(-)
drivers/tty/serial/8250/8250_dw.c +32 -43
@@ -283,9 +283,6 @@ static void dw8250_set_termios(struct uart_port *p, struct ktermios *termios,long rate;int ret; -if (IS_ERR (d->clk)) - goto out; -clk_disable_unprepare (d->clk); rate =clk_round_rate (d->clk, baud *16 );if (rate <0 )
@@ -296,8 +293,10 @@ static void dw8250_set_termios(struct uart_port *p, struct ktermios *termios, ret =clk_set_rate (d->clk, rate);clk_prepare_enable (d->clk); -if (!ret) - p->uartclk = rate; +if (ret) + goto out; + + p->uartclk = rate; out: p->status &= ~UPSTAT_AUTOCTS ;
@@ -473,19 +472,18 @@ static int dw8250_probe(struct platform_device *pdev)device_property_read_u32 (dev,"clock-frequency" , &p->uartclk);/* If there is separate baudclk, get the rate from it. */ - data->clk =devm_clk_get (dev,"baudclk" ); -if (IS_ERR (data->clk) &&PTR_ERR (data->clk) != -EPROBE_DEFER ) - data->clk =devm_clk_get (dev,NULL ); -if (IS_ERR (data->clk) &&PTR_ERR (data->clk) == -EPROBE_DEFER ) -return -EPROBE_DEFER ; -if (!IS_ERR_OR_NULL (data->clk)) { - err =clk_prepare_enable (data->clk); -if (err) -dev_warn (dev,"could not enable optional baudclk: %d\n" , - err); -else - p->uartclk =clk_get_rate (data->clk); - } + data->clk =devm_clk_get_optional (dev,"baudclk" ); +if (data->clk ==NULL ) + data->clk =devm_clk_get_optional (dev,NULL ); +if (IS_ERR (data->clk)) +return PTR_ERR (data->clk); + + err =clk_prepare_enable (data->clk); +if (err) +dev_warn (dev,"could not enable optional baudclk: %d\n" , err); + +if (data->clk) + p->uartclk =clk_get_rate (data->clk);/* If no clock rate is defined, fail. */ if (!p->uartclk) {
@@ -494,17 +492,16 @@ static int dw8250_probe(struct platform_device *pdev) goto err_clk; } - data->pclk =devm_clk_get (dev,"apb_pclk" ); -if (IS_ERR (data->pclk) &&PTR_ERR (data->pclk) == -EPROBE_DEFER ) { - err = -EPROBE_DEFER ; + 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)) { - err =clk_prepare_enable (data->pclk); -if (err) { -dev_err (dev,"could not enable apb_pclk\n" ); - goto err_clk; - } + + err =clk_prepare_enable (data->pclk); +if (err) { +dev_err (dev,"could not enable apb_pclk\n" ); + goto err_clk; } data->rst =devm_reset_control_get_optional_exclusive (dev,NULL );
@@ -547,12 +544,10 @@ static int dw8250_probe(struct platform_device *pdev)reset_control_assert (data->rst); err_pclk: -if (!IS_ERR (data->pclk)) -clk_disable_unprepare (data->pclk); +clk_disable_unprepare (data->pclk); err_clk: -if (!IS_ERR (data->clk)) -clk_disable_unprepare (data->clk); +clk_disable_unprepare (data->clk);return err; }
@@ -568,11 +563,9 @@ static int dw8250_remove(struct platform_device *pdev)reset_control_assert (data->rst); -if (!IS_ERR (data->pclk)) -clk_disable_unprepare (data->pclk); +clk_disable_unprepare (data->pclk); -if (!IS_ERR (data->clk)) -clk_disable_unprepare (data->clk); +clk_disable_unprepare (data->clk);pm_runtime_disable (dev);pm_runtime_put_noidle (dev);
@@ -605,11 +598,9 @@ static int dw8250_runtime_suspend(struct device *dev) {struct dw8250_data *data =dev_get_drvdata (dev); -if (!IS_ERR (data->clk)) -clk_disable_unprepare (data->clk); +clk_disable_unprepare (data->clk); -if (!IS_ERR (data->pclk)) -clk_disable_unprepare (data->pclk); +clk_disable_unprepare (data->pclk);return 0 ; }
@@ -618,11 +609,9 @@ static int dw8250_runtime_resume(struct device *dev) {struct dw8250_data *data =dev_get_drvdata (dev); -if (!IS_ERR (data->pclk)) -clk_prepare_enable (data->pclk); +clk_prepare_enable (data->pclk); -if (!IS_ERR (data->clk)) -clk_prepare_enable (data->clk); +clk_prepare_enable (data->clk);return 0 ; }
Signature · 1 line
2.51.0
Sasha Levin
maintainerPATCH 2/3 serial: 8250_dw: Use devm_add_action_or_reset()
From: Andy Shevchenko <[email protected]>
[ Upstream commit 295b09128d12fb1a7a67f771cc0ae0df869eafaf ]
Slightly simplify ->probe() and drop a few goto labels by using devm_add_action_or_reset() for clock and reset cleanup.
Stable-dep-of: daeb4037adf7 ("serial: 8250_dw: handle reset control deassert error")
--- drivers/tty/serial/8250/8250_dw.c | 63 +++++++++++++++---------------- 1 file changed, 31 insertions(+), 32 deletions(-)
drivers/tty/serial/8250/8250_dw.c +31 -32
@@ -384,6 +384,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;
@@ -482,35 +492,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 */
@@ -528,10 +546,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;platform_set_drvdata (pdev, data);
@@ -539,17 +555,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)
@@ -561,12 +566,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);
Signature · 1 line
2.51.0
Sasha Levin
maintainerPATCH 3/3 serial: 8250_dw: handle reset control deassert error
In reply to Sasha LevinFrom: Artem Shimko <[email protected]>
[ 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.
--- drivers/tty/serial/8250/8250_dw.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/tty/serial/8250/8250_dw.c +3 -1
@@ -523,7 +523,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)
Signature · 1 line
2.51.0