FAILED: patch "[PATCH] slimbus: qcom-ngd-ctrl: Register callbacks after creating the" failed to apply to 5.15-stable tree
Subsystems (3)
[email protected]
maintainerThe patch below does not apply to the 5.15-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.15.y
git checkout FETCH_HEAD
git cherry-pick -x 2a9d50e9ea406e0c8735938484adc20515ef1b47
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026061509-identical-efficient-87fe@gregkh' --subject-prefix 'PATCH 5.15.y' HEAD^..
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 2a9d50e9ea406e0c8735938484adc20515ef1b47 Mon Sep 17 00:00:00 2001
From: Bjorn Andersson <[email protected]>
Date: Sat, 30 May 2026 21:44:18 +0100
Subject: [PATCH] slimbus: qcom-ngd-ctrl: Register callbacks after creating the
ngd
When the remoteproc starts in parallel with the NGD driver being probed, or the remoteproc is already up when the PDR lookup is being registered, or in the theoretical event that we get an interrupt from the hardware, these callbacks will operate on uninitialized data. This result in issues to boot the affected boards.
One such example can be seen in the following fault, where qcom_slim_ngd_ssr_pdr_notify() schedules work on the NULL ngd_up_work.
[ 21.858578] ------------[ cut here ]------------ [ 21.858745] WARNING: kernel/workqueue.c:2338 at __queue_work+0x5e0/0x790, CPU#2: kworker/2:2/116 ... [ 21.859251] Call trace: [ 21.859255] __queue_work+0x5e0/0x790 (P) [ 21.859265] queue_work_on+0x6c/0xf0 [ 21.859273] qcom_slim_ngd_ssr_pdr_notify+0x110/0x150 [slim_qcom_ngd_ctrl] [ 21.859304] qcom_slim_ngd_ssr_notify+0x24/0x40 [slim_qcom_ngd_ctrl] [ 21.859318] notifier_call_chain+0xa4/0x230 [ 21.859329] srcu_notifier_call_chain+0x64/0xb8 [ 21.859338] ssr_notify_start+0x40/0x78 [qcom_common] [ 21.859355] rproc_start+0x130/0x230 [ 21.859367] rproc_boot+0x3d4/0x518
...
Move the enablement of interrupts, and the registration of SSR and PDR until after the NGD device has been registered.
This could be further refined by moving initialization to the control driver probe and by removing the platform driver model from the picture.
drivers/slimbus/qcom-ngd-ctrl.c +26 -19
@@ -1609,6 +1609,7 @@ static int qcom_slim_ngd_ctrl_probe(struct platform_device *pdev) {struct device *dev = &pdev->dev;struct qcom_slim_ngd_ctrl *ctrl; +int irq;int ret;struct pdr_service *pds;
@@ -1622,20 +1623,16 @@ static int qcom_slim_ngd_ctrl_probe(struct platform_device *pdev)if (IS_ERR (ctrl->base))return PTR_ERR (ctrl->base); - ret =platform_get_irq (pdev,0 ); -if (ret <0 ) -return ret; + irq =platform_get_irq (pdev,0 ); +if (irq <0 ) +return irq; - ret =devm_request_irq (dev, ret, qcom_slim_ngd_interrupt, -IRQF_TRIGGER_HIGH ,"slim-ngd" , ctrl); + ret =devm_request_irq (dev, irq, qcom_slim_ngd_interrupt, +IRQF_TRIGGER_HIGH |IRQF_NO_AUTOEN , +"slim-ngd" , ctrl);if (ret)return dev_err_probe (&pdev->dev, ret,"request IRQ failed\n" ); - ctrl->nb.notifier_call = qcom_slim_ngd_ssr_notify; - ctrl->notifier =qcom_register_ssr_notifier ("lpass" , &ctrl->nb); -if (IS_ERR (ctrl->notifier)) -return PTR_ERR (ctrl->notifier); - ctrl->dev = dev; ctrl->framer.rootfreq =SLIM_ROOT_FREQ >>3 ; ctrl->framer.superfreq =
@@ -1657,24 +1654,34 @@ static int qcom_slim_ngd_ctrl_probe(struct platform_device *pdev)init_completion (&ctrl->qmi_up); ctrl->pdr =pdr_handle_alloc (slim_pd_status, ctrl); -if (IS_ERR (ctrl->pdr)) { - ret =dev_err_probe (dev,PTR_ERR (ctrl->pdr), -"Failed to init PDR handle\n" ); - goto err_unregister_ssr; - } +if (IS_ERR (ctrl->pdr)) +return dev_err_probe (dev,PTR_ERR (ctrl->pdr),"Failed to init PDR handle\n" ); + + ret =of_qcom_slim_ngd_register (dev, ctrl); +if (ret) + goto err_pdr_release; pds =pdr_add_lookup (ctrl->pdr,"avs/audio" ,"msm/adsp/audio_pd" );if (IS_ERR (pds) &&PTR_ERR (pds) != -EALREADY ) { ret =dev_err_probe (dev,PTR_ERR (pds),"pdr add lookup failed\n" ); - goto err_pdr_release; + goto err_unregister_ngd; } -return of_qcom_slim_ngd_register (dev, ctrl); + ctrl->nb.notifier_call = qcom_slim_ngd_ssr_notify; + ctrl->notifier =qcom_register_ssr_notifier ("lpass" , &ctrl->nb); +if (IS_ERR (ctrl->notifier)) { + ret =PTR_ERR (ctrl->notifier); + goto err_unregister_ngd; + } +enable_irq (irq); + +return 0 ; + +err_unregister_ngd: +qcom_slim_ngd_unregister (ctrl); err_pdr_release:pdr_handle_release (ctrl->pdr); -err_unregister_ssr: -qcom_unregister_ssr_notifier (ctrl->notifier, &ctrl->nb);return ret; }
Sasha Levin
maintainerPATCH 1/4 slimbus: Convert to platform remove callback returning void
From: Uwe Kleine-König <[email protected]>
[ Upstream commit 880b33b0580c8ac9d0202b6e592cb116c99d1b65 ]
The .remove() callback for a platform driver returns an int which makes many driver authors wrongly assume it's possible to do error handling by returning an error code. However the value returned is ignored (apart from emitting a warning) and this typically results in resource leaks.
To improve here there is a quest to make the remove callback return void. In the first step of this quest all drivers are converted to .remove_new(), which already returns void. Eventually after all drivers are converted, .remove_new() will be renamed to .remove().
Trivially convert the slimbus drivers from always returning zero in the remove callback to the void returning variant.
Stable-dep-of: 2a9d50e9ea40 ("slimbus: qcom-ngd-ctrl: Register callbacks after creating the ngd")
--- drivers/slimbus/qcom-ctrl.c | 5 ++--- drivers/slimbus/qcom-ngd-ctrl.c | 11 ++++------- 2 files changed, 6 insertions(+), 10 deletions(-)
drivers/slimbus/qcom-ctrl.c +2 -3
@@ -630,7 +630,7 @@ static int qcom_slim_probe(struct platform_device *pdev)return ret; } -static int qcom_slim_remove (struct platform_device *pdev) +static void qcom_slim_remove (struct platform_device *pdev) {struct qcom_slim_ctrl *ctrl =platform_get_drvdata (pdev);
@@ -639,7 +639,6 @@ static int qcom_slim_remove(struct platform_device *pdev)clk_disable_unprepare (ctrl->rclk);clk_disable_unprepare (ctrl->hclk);destroy_workqueue (ctrl->rxwq); -return 0 ; }/*
@@ -726,7 +725,7 @@ static const struct of_device_id qcom_slim_dt_match[] = {static struct platform_driver qcom_slim_driver = { .probe = qcom_slim_probe, - .remove = qcom_slim_remove, + .remove_new = qcom_slim_remove, .driver = { .name ="qcom_slim_ctrl" , .of_match_table = qcom_slim_dt_match,
drivers/slimbus/qcom-ngd-ctrl.c +4 -7
@@ -1595,14 +1595,12 @@ static int qcom_slim_ngd_ctrl_probe(struct platform_device *pdev)return ret; } -static int qcom_slim_ngd_ctrl_remove (struct platform_device *pdev) +static void qcom_slim_ngd_ctrl_remove (struct platform_device *pdev) {platform_driver_unregister (&qcom_slim_ngd_driver); - -return 0 ; } -static int qcom_slim_ngd_remove (struct platform_device *pdev) +static void qcom_slim_ngd_remove (struct platform_device *pdev) {struct qcom_slim_ngd_ctrl *ctrl =platform_get_drvdata (pdev);
@@ -1617,7 +1615,6 @@ static int qcom_slim_ngd_remove(struct platform_device *pdev)kfree (ctrl->ngd); ctrl->ngd =NULL ; -return 0 ; }static int __maybe_unused qcom_slim_ngd_runtime_idle (struct device *dev)
@@ -1660,7 +1657,7 @@ static const struct dev_pm_ops qcom_slim_ngd_dev_pm_ops = {static struct platform_driver qcom_slim_ngd_ctrl_driver = { .probe = qcom_slim_ngd_ctrl_probe, - .remove = qcom_slim_ngd_ctrl_remove, + .remove_new = qcom_slim_ngd_ctrl_remove, .driver = { .name ="qcom,slim-ngd-ctrl" , .of_match_table = qcom_slim_ngd_dt_match,
@@ -1669,7 +1666,7 @@ static struct platform_driver qcom_slim_ngd_ctrl_driver = {static struct platform_driver qcom_slim_ngd_driver = { .probe = qcom_slim_ngd_probe, - .remove = qcom_slim_ngd_remove, + .remove_new = qcom_slim_ngd_remove, .driver = { .name =QCOM_SLIM_NGD_DRV_NAME , .pm = &qcom_slim_ngd_dev_pm_ops,
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 2/4 slimbus: qcom-ngd-ctrl: Fix up platform_driver registration
From: Bjorn Andersson <[email protected]>
[ Upstream commit 8663e8334d7b6007f5d8a4e5dd270246f35107a6 ]
Device drivers should not invoke platform_driver_register()/unregister() in their probe and remove paths. They should further not rely on platform_driver_unregister() as their only means of "deleting" their child devices.
Introduce a helper to unregister the child device and move the platform_driver_register()/unregister() to module_init()/exit().
Stable-dep-of: 2a9d50e9ea40 ("slimbus: qcom-ngd-ctrl: Register callbacks after creating the ngd")
--- drivers/slimbus/qcom-ngd-ctrl.c | 36 ++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-)
drivers/slimbus/qcom-ngd-ctrl.c +33 -3
@@ -1474,6 +1474,13 @@ static int of_qcom_slim_ngd_register(struct device *parent,return -ENODEV ; } +static void qcom_slim_ngd_unregister (struct qcom_slim_ngd_ctrl *ctrl) +{ +struct qcom_slim_ngd *ngd = ctrl->ngd; + +platform_device_del (ngd->pdev); +} +static int qcom_slim_ngd_probe (struct platform_device *pdev) {struct device *dev = &pdev->dev;
@@ -1583,7 +1590,6 @@ static int qcom_slim_ngd_ctrl_probe(struct platform_device *pdev) goto err_pdr_lookup; } -platform_driver_register (&qcom_slim_ngd_driver);return of_qcom_slim_ngd_register (dev, ctrl); err_pdr_alloc:
@@ -1597,7 +1603,9 @@ static int qcom_slim_ngd_ctrl_probe(struct platform_device *pdev)static void qcom_slim_ngd_ctrl_remove (struct platform_device *pdev) { -platform_driver_unregister (&qcom_slim_ngd_driver); +struct qcom_slim_ngd_ctrl *ctrl =platform_get_drvdata (pdev); + +qcom_slim_ngd_unregister (ctrl); }static void qcom_slim_ngd_remove (struct platform_device *pdev)
@@ -1673,6 +1681,28 @@ static struct platform_driver qcom_slim_ngd_driver = { }, }; -module_platform_driver (qcom_slim_ngd_ctrl_driver); +static int qcom_slim_ngd_init (void ) +{ +int ret; + + ret =platform_driver_register (&qcom_slim_ngd_driver); +if (ret) +return ret; + + ret =platform_driver_register (&qcom_slim_ngd_ctrl_driver); +if (ret) +platform_driver_unregister (&qcom_slim_ngd_driver); + +return ret; +} + +static void qcom_slim_ngd_exit (void ) +{ +platform_driver_unregister (&qcom_slim_ngd_ctrl_driver); +platform_driver_unregister (&qcom_slim_ngd_driver); +} + +module_init (qcom_slim_ngd_init); +module_exit (qcom_slim_ngd_exit);MODULE_LICENSE ("GPL v2" );MODULE_DESCRIPTION ("Qualcomm SLIMBus NGD controller" );
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 3/4 slimbus: qcom-ngd-ctrl: Fix probe error path ordering
In reply to Sasha LevinFrom: Bjorn Andersson <[email protected]>
[ Upstream commit 2c22ff152d380ec3d3af099fa05d0ac5ca9b4c1e ]
qcom_slim_ngd_ctrl_probe() first registers the SSR callback then allocates the PDR context, as such the error path needs to come in opposite order to allow us to unroll each step.
Stable-dep-of: 2a9d50e9ea40 ("slimbus: qcom-ngd-ctrl: Register callbacks after creating the ngd")
--- drivers/slimbus/qcom-ngd-ctrl.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-)
drivers/slimbus/qcom-ngd-ctrl.c +5 -6
@@ -1580,23 +1580,22 @@ static int qcom_slim_ngd_ctrl_probe(struct platform_device *pdev)if (IS_ERR (ctrl->pdr)) {dev_err (dev,"Failed to init PDR handle\n" ); ret =PTR_ERR (ctrl->pdr); - goto err_pdr_alloc; + goto err_unregister_ssr; } pds =pdr_add_lookup (ctrl->pdr,"avs/audio" ,"msm/adsp/audio_pd" );if (IS_ERR (pds) &&PTR_ERR (pds) != -EALREADY ) { ret =PTR_ERR (pds);dev_err (dev,"pdr add lookup failed: %d\n" , ret); - goto err_pdr_lookup; + goto err_pdr_release; }return of_qcom_slim_ngd_register (dev, ctrl); -err_pdr_alloc: -qcom_unregister_ssr_notifier (ctrl->notifier, &ctrl->nb); - -err_pdr_lookup: +err_pdr_release:pdr_handle_release (ctrl->pdr); +err_unregister_ssr: +qcom_unregister_ssr_notifier (ctrl->notifier, &ctrl->nb);return ret; }
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 4/4 slimbus: qcom-ngd-ctrl: Register callbacks after creating the ngd
In reply to Sasha LevinFrom: Bjorn Andersson <[email protected]>
[ Upstream commit 2a9d50e9ea406e0c8735938484adc20515ef1b47 ]
When the remoteproc starts in parallel with the NGD driver being probed, or the remoteproc is already up when the PDR lookup is being registered, or in the theoretical event that we get an interrupt from the hardware, these callbacks will operate on uninitialized data. This result in issues to boot the affected boards.
One such example can be seen in the following fault, where qcom_slim_ngd_ssr_pdr_notify() schedules work on the NULL ngd_up_work.
[ 21.858578] ------------[ cut here ]------------ [ 21.858745] WARNING: kernel/workqueue.c:2338 at __queue_work+0x5e0/0x790, CPU#2: kworker/2:2/116 ... [ 21.859251] Call trace: [ 21.859255] __queue_work+0x5e0/0x790 (P) [ 21.859265] queue_work_on+0x6c/0xf0 [ 21.859273] qcom_slim_ngd_ssr_pdr_notify+0x110/0x150 [slim_qcom_ngd_ctrl] [ 21.859304] qcom_slim_ngd_ssr_notify+0x24/0x40 [slim_qcom_ngd_ctrl] [ 21.859318] notifier_call_chain+0xa4/0x230 [ 21.859329] srcu_notifier_call_chain+0x64/0xb8 [ 21.859338] ssr_notify_start+0x40/0x78 [qcom_common] [ 21.859355] rproc_start+0x130/0x230 [ 21.859367] rproc_boot+0x3d4/0x518
...
Move the enablement of interrupts, and the registration of SSR and PDR until after the NGD device has been registered.
This could be further refined by moving initialization to the control driver probe and by removing the platform driver model from the picture.
--- drivers/slimbus/qcom-ngd-ctrl.c | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-)
drivers/slimbus/qcom-ngd-ctrl.c +20 -12
@@ -1545,17 +1545,13 @@ static int qcom_slim_ngd_ctrl_probe(struct platform_device *pdev) } ret =devm_request_irq (dev, res->start, qcom_slim_ngd_interrupt, -IRQF_TRIGGER_HIGH ,"slim-ngd" , ctrl); +IRQF_TRIGGER_HIGH |IRQF_NO_AUTOEN ,"slim-ngd" , + ctrl);if (ret) {dev_err (&pdev->dev,"request IRQ failed\n" );return ret; } - ctrl->nb.notifier_call = qcom_slim_ngd_ssr_notify; - ctrl->notifier =qcom_register_ssr_notifier ("lpass" , &ctrl->nb); -if (IS_ERR (ctrl->notifier)) -return PTR_ERR (ctrl->notifier); - ctrl->dev = dev; ctrl->framer.rootfreq =SLIM_ROOT_FREQ >>3 ; ctrl->framer.superfreq =
@@ -1579,23 +1575,35 @@ static int qcom_slim_ngd_ctrl_probe(struct platform_device *pdev) ctrl->pdr =pdr_handle_alloc (slim_pd_status, ctrl);if (IS_ERR (ctrl->pdr)) {dev_err (dev,"Failed to init PDR handle\n" ); - ret =PTR_ERR (ctrl->pdr); - goto err_unregister_ssr; +return PTR_ERR (ctrl->pdr); } + ret =of_qcom_slim_ngd_register (dev, ctrl); +if (ret) + goto err_pdr_release; + pds =pdr_add_lookup (ctrl->pdr,"avs/audio" ,"msm/adsp/audio_pd" );if (IS_ERR (pds) &&PTR_ERR (pds) != -EALREADY ) { ret =PTR_ERR (pds);dev_err (dev,"pdr add lookup failed: %d\n" , ret); - goto err_pdr_release; + goto err_unregister_ngd; } -return of_qcom_slim_ngd_register (dev, ctrl); + ctrl->nb.notifier_call = qcom_slim_ngd_ssr_notify; + ctrl->notifier =qcom_register_ssr_notifier ("lpass" , &ctrl->nb); +if (IS_ERR (ctrl->notifier)) { + ret =PTR_ERR (ctrl->notifier); + goto err_unregister_ngd; + } +enable_irq (res->start); + +return 0 ; + +err_unregister_ngd: +qcom_slim_ngd_unregister (ctrl); err_pdr_release:pdr_handle_release (ctrl->pdr); -err_unregister_ssr: -qcom_unregister_ssr_notifier (ctrl->notifier, &ctrl->nb);return ret; }
Signature · 1 line
2.53.0