ASoC: codecs: Fix error handling in power domain init and exit handlers
authorSrinivasa Rao Mandadapu <quic_srivasam@quicinc.com>
Tue, 22 Mar 2022 16:18:57 +0000 (21:48 +0530)
committerMark Brown <broonie@kernel.org>
Tue, 5 Apr 2022 09:23:07 +0000 (10:23 +0100)
Update error handling in power domain init and exit handlers, as existing handling
may cause issues in device remove function.
Use appropriate pm core api for power domain get and sync to avoid redundant code.

Fixes: 9e3d83c52844 ("ASoC: codecs: Add power domains support in digital macro codecs")

Signed-off-by: Srinivasa Rao Mandadapu <quic_srivasam@quicinc.com>
Co-developed-by: Venkata Prasad Potturu <quic_potturu@quicinc.com>
Signed-off-by: Venkata Prasad Potturu <quic_potturu@quicinc.com>
Reported-by: kernel test robot <lkp@intel.com>
Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
Link: https://lore.kernel.org/r/1647965937-32203-1-git-send-email-quic_srivasam@quicinc.com
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/codecs/lpass-macro-common.c

index 6cede75ed3b5d4fa3b68bda84eccccd8cb6a3920..3c661fd61173742460e46339425e6bd5f317dafd 100644 (file)
@@ -24,42 +24,45 @@ struct lpass_macro *lpass_macro_pds_init(struct device *dev)
                return ERR_PTR(-ENOMEM);
 
        l_pds->macro_pd = dev_pm_domain_attach_by_name(dev, "macro");
-       if (IS_ERR_OR_NULL(l_pds->macro_pd))
-               return NULL;
-
-       ret = pm_runtime_get_sync(l_pds->macro_pd);
-       if (ret < 0) {
-               pm_runtime_put_noidle(l_pds->macro_pd);
+       if (IS_ERR_OR_NULL(l_pds->macro_pd)) {
+               ret = PTR_ERR(l_pds->macro_pd);
                goto macro_err;
        }
 
+       ret = pm_runtime_resume_and_get(l_pds->macro_pd);
+       if (ret < 0)
+               goto macro_sync_err;
+
        l_pds->dcodec_pd = dev_pm_domain_attach_by_name(dev, "dcodec");
-       if (IS_ERR_OR_NULL(l_pds->dcodec_pd))
+       if (IS_ERR_OR_NULL(l_pds->dcodec_pd)) {
+               ret = PTR_ERR(l_pds->dcodec_pd);
                goto dcodec_err;
+       }
 
-       ret = pm_runtime_get_sync(l_pds->dcodec_pd);
-       if (ret < 0) {
-               pm_runtime_put_noidle(l_pds->dcodec_pd);
+       ret = pm_runtime_resume_and_get(l_pds->dcodec_pd);
+       if (ret < 0)
                goto dcodec_sync_err;
-       }
        return l_pds;
 
 dcodec_sync_err:
        dev_pm_domain_detach(l_pds->dcodec_pd, false);
 dcodec_err:
        pm_runtime_put(l_pds->macro_pd);
-macro_err:
+macro_sync_err:
        dev_pm_domain_detach(l_pds->macro_pd, false);
+macro_err:
        return ERR_PTR(ret);
 }
 EXPORT_SYMBOL_GPL(lpass_macro_pds_init);
 
 void lpass_macro_pds_exit(struct lpass_macro *pds)
 {
-       pm_runtime_put(pds->macro_pd);
-       dev_pm_domain_detach(pds->macro_pd, false);
-       pm_runtime_put(pds->dcodec_pd);
-       dev_pm_domain_detach(pds->dcodec_pd, false);
+       if (pds) {
+               pm_runtime_put(pds->macro_pd);
+               dev_pm_domain_detach(pds->macro_pd, false);
+               pm_runtime_put(pds->dcodec_pd);
+               dev_pm_domain_detach(pds->dcodec_pd, false);
+       }
 }
 EXPORT_SYMBOL_GPL(lpass_macro_pds_exit);