Current implementation of q6v5_wcss_probe() in qcom_q6v5_wcss.c and does not remove the subdevs on the error path. Fix this bug by calling qcom_remove_{ssr,sysmon,pdm,glink}_subdev(), and qcom_q6v5_deinit() appropriately. Signed-off-by: Joe Hattori <joe@xxxxxxxxxxxxxxxxxxxxx> --- drivers/remoteproc/qcom_q6v5_wcss.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/drivers/remoteproc/qcom_q6v5_wcss.c b/drivers/remoteproc/qcom_q6v5_wcss.c index e913dabae992..1e85beb8f9f6 100644 --- a/drivers/remoteproc/qcom_q6v5_wcss.c +++ b/drivers/remoteproc/qcom_q6v5_wcss.c @@ -1056,18 +1056,33 @@ static int q6v5_wcss_probe(struct platform_device *pdev) qcom_add_pdm_subdev(rproc, &wcss->pdm_subdev); qcom_add_ssr_subdev(rproc, &wcss->ssr_subdev, "q6wcss"); - if (desc->ssctl_id) + if (desc->ssctl_id) { wcss->sysmon = qcom_add_sysmon_subdev(rproc, desc->sysmon_name, desc->ssctl_id); + if (IS_ERR(wcss->sysmon)) { + ret = PTR_ERR(wcss->sysmon); + goto deinit_remove_subdevs; + } + } ret = rproc_add(rproc); if (ret) - return ret; + goto remove_sysmon_subdev; platform_set_drvdata(pdev, rproc); return 0; + +remove_sysmon_subdev: + if (desc->ssctl_id) + qcom_remove_sysmon_subdev(wcss->sysmon); +deinit_remove_subdevs: + qcom_q6v5_deinit(&wcss->q6v5); + qcom_remove_glink_subdev(rproc, &wcss->glink_subdev); + qcom_remove_pdm_subdev(rproc, &wcss->pdm_subdev); + qcom_remove_ssr_subdev(rproc, &wcss->ssr_subdev); + return ret; } static void q6v5_wcss_remove(struct platform_device *pdev) -- 2.34.1