1 // SPDX-License-Identifier: GPL-2.0-only 2 // Copyright (c) 2022, The Linux Foundation. All rights reserved. 3 4 #include <linux/cleanup.h> 5 #include <linux/export.h> 6 #include <linux/module.h> 7 #include <linux/init.h> 8 #include <linux/of.h> 9 #include <linux/platform_device.h> 10 #include <linux/pm_domain.h> 11 #include <linux/pm_runtime.h> 12 13 #include "lpass-macro-common.h" 14 15 static DEFINE_MUTEX(lpass_codec_mutex); 16 static enum lpass_codec_version lpass_codec_version; 17 18 struct lpass_macro *lpass_macro_pds_init(struct device *dev) 19 { 20 struct lpass_macro *l_pds; 21 int ret; 22 23 if (!of_property_present(dev->of_node, "power-domains")) 24 return NULL; 25 26 l_pds = devm_kzalloc(dev, sizeof(*l_pds), GFP_KERNEL); 27 if (!l_pds) 28 return ERR_PTR(-ENOMEM); 29 30 l_pds->macro_pd = dev_pm_domain_attach_by_name(dev, "macro"); 31 if (IS_ERR_OR_NULL(l_pds->macro_pd)) { 32 ret = l_pds->macro_pd ? PTR_ERR(l_pds->macro_pd) : -ENODATA; 33 goto macro_err; 34 } 35 36 ret = pm_runtime_resume_and_get(l_pds->macro_pd); 37 if (ret < 0) 38 goto macro_sync_err; 39 40 l_pds->dcodec_pd = dev_pm_domain_attach_by_name(dev, "dcodec"); 41 if (IS_ERR_OR_NULL(l_pds->dcodec_pd)) { 42 ret = l_pds->dcodec_pd ? PTR_ERR(l_pds->dcodec_pd) : -ENODATA; 43 goto dcodec_err; 44 } 45 46 ret = pm_runtime_resume_and_get(l_pds->dcodec_pd); 47 if (ret < 0) 48 goto dcodec_sync_err; 49 return l_pds; 50 51 dcodec_sync_err: 52 dev_pm_domain_detach(l_pds->dcodec_pd, false); 53 dcodec_err: 54 pm_runtime_put(l_pds->macro_pd); 55 macro_sync_err: 56 dev_pm_domain_detach(l_pds->macro_pd, false); 57 macro_err: 58 return ERR_PTR(ret); 59 } 60 EXPORT_SYMBOL_GPL(lpass_macro_pds_init); 61 62 void lpass_macro_pds_exit(struct lpass_macro *pds) 63 { 64 if (pds) { 65 pm_runtime_put(pds->macro_pd); 66 dev_pm_domain_detach(pds->macro_pd, false); 67 pm_runtime_put(pds->dcodec_pd); 68 dev_pm_domain_detach(pds->dcodec_pd, false); 69 } 70 } 71 EXPORT_SYMBOL_GPL(lpass_macro_pds_exit); 72 73 void lpass_macro_set_codec_version(enum lpass_codec_version version) 74 { 75 guard(mutex)(&lpass_codec_mutex); 76 lpass_codec_version = version; 77 } 78 EXPORT_SYMBOL_GPL(lpass_macro_set_codec_version); 79 80 enum lpass_codec_version lpass_macro_get_codec_version(void) 81 { 82 guard(mutex)(&lpass_codec_mutex); 83 84 return lpass_codec_version; 85 } 86 EXPORT_SYMBOL_GPL(lpass_macro_get_codec_version); 87 88 MODULE_DESCRIPTION("Common macro driver"); 89 MODULE_LICENSE("GPL"); 90