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