Re: [PATCH 4/7] slimbus: qcom-ngd-ctrl: Register callbacks after creating the ngd

From: Mukesh Ojha

Date: Tue Mar 10 2026 - 03:49:43 EST


On Mon, Mar 09, 2026 at 11:09:05PM -0500, Bjorn Andersson wrote:
> 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 three registrations of interrupts, 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.
>
> Fixes: 917809e2280b ("slimbus: ngd: Add qcom SLIMBus NGD driver")
> Cc: stable@xxxxxxxxxxxxxxx
> Signed-off-by: Bjorn Andersson <bjorn.andersson@xxxxxxxxxxxxxxxx>
> ---
> drivers/slimbus/qcom-ngd-ctrl.c | 52 ++++++++++++++++++++++++-----------------
> 1 file changed, 30 insertions(+), 22 deletions(-)
>
> diff --git a/drivers/slimbus/qcom-ngd-ctrl.c b/drivers/slimbus/qcom-ngd-ctrl.c
> index 09ce3299e15c25b1b9cf6b1559850adf4aa20737..76944c515291a62fb9cb192bec5cd5c2caa542f4 100644
> --- a/drivers/slimbus/qcom-ngd-ctrl.c
> +++ b/drivers/slimbus/qcom-ngd-ctrl.c
> @@ -1613,6 +1613,7 @@ static int qcom_slim_ngd_ctrl_probe(struct platform_device *pdev)
> struct qcom_slim_ngd_ctrl *ctrl;
> int ret;
> struct pdr_service *pds;
> + int irq;
>
> ctrl = devm_kzalloc(dev, sizeof(*ctrl), GFP_KERNEL);
> if (!ctrl)
> @@ -1624,19 +1625,9 @@ 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;
> -
> - ret = devm_request_irq(dev, ret, qcom_slim_ngd_interrupt,
> - IRQF_TRIGGER_HIGH, "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);
> + irq = platform_get_irq(pdev, 0);
> + if (irq < 0)
> + return irq;
>
> ctrl->dev = dev;
> ctrl->framer.rootfreq = SLIM_ROOT_FREQ >> 3;
> @@ -1659,24 +1650,41 @@ 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;
> + }
> +
> + ret = devm_request_irq(dev, irq, qcom_slim_ngd_interrupt,
> + IRQF_TRIGGER_HIGH, "slim-ngd", ctrl);
> + if (ret) {
> + ret = dev_err_probe(&pdev->dev, ret, "request IRQ failed\n");
> + goto err_unregister_ssr;
> + }
> +
> + return 0;
>
> -err_pdr_release:
> - pdr_handle_release(ctrl->pdr);
> err_unregister_ssr:
> qcom_unregister_ssr_notifier(ctrl->notifier, &ctrl->nb);
> +err_unregister_ngd:
> + qcom_slim_ngd_unregister(ctrl);
> +err_pdr_release:
> + pdr_handle_release(ctrl->pdr);
>
> return ret;
> }

Reviewed-by: Mukesh Ojha <mukesh.ojha@xxxxxxxxxxxxxxxx>

>
> --
> 2.51.0
>

--
-Mukesh Ojha