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 | struct lpass_macro *lpass_macro_pds_init(struct device *dev) |
15 | { |
16 | struct lpass_macro *l_pds; |
17 | int ret; |
18 | |
19 | if (!of_property_present(np: dev->of_node, propname: "power-domains" )) |
20 | return NULL; |
21 | |
22 | l_pds = devm_kzalloc(dev, size: sizeof(*l_pds), GFP_KERNEL); |
23 | if (!l_pds) |
24 | return ERR_PTR(error: -ENOMEM); |
25 | |
26 | l_pds->macro_pd = dev_pm_domain_attach_by_name(dev, name: "macro" ); |
27 | if (IS_ERR_OR_NULL(ptr: l_pds->macro_pd)) { |
28 | ret = l_pds->macro_pd ? PTR_ERR(ptr: l_pds->macro_pd) : -ENODATA; |
29 | goto macro_err; |
30 | } |
31 | |
32 | ret = pm_runtime_resume_and_get(dev: l_pds->macro_pd); |
33 | if (ret < 0) |
34 | goto macro_sync_err; |
35 | |
36 | l_pds->dcodec_pd = dev_pm_domain_attach_by_name(dev, name: "dcodec" ); |
37 | if (IS_ERR_OR_NULL(ptr: l_pds->dcodec_pd)) { |
38 | ret = l_pds->dcodec_pd ? PTR_ERR(ptr: l_pds->dcodec_pd) : -ENODATA; |
39 | goto dcodec_err; |
40 | } |
41 | |
42 | ret = pm_runtime_resume_and_get(dev: l_pds->dcodec_pd); |
43 | if (ret < 0) |
44 | goto dcodec_sync_err; |
45 | return l_pds; |
46 | |
47 | dcodec_sync_err: |
48 | dev_pm_domain_detach(dev: l_pds->dcodec_pd, power_off: false); |
49 | dcodec_err: |
50 | pm_runtime_put(dev: l_pds->macro_pd); |
51 | macro_sync_err: |
52 | dev_pm_domain_detach(dev: l_pds->macro_pd, power_off: false); |
53 | macro_err: |
54 | return ERR_PTR(error: ret); |
55 | } |
56 | EXPORT_SYMBOL_GPL(lpass_macro_pds_init); |
57 | |
58 | void lpass_macro_pds_exit(struct lpass_macro *pds) |
59 | { |
60 | if (pds) { |
61 | pm_runtime_put(dev: pds->macro_pd); |
62 | dev_pm_domain_detach(dev: pds->macro_pd, power_off: false); |
63 | pm_runtime_put(dev: pds->dcodec_pd); |
64 | dev_pm_domain_detach(dev: pds->dcodec_pd, power_off: false); |
65 | } |
66 | } |
67 | EXPORT_SYMBOL_GPL(lpass_macro_pds_exit); |
68 | |
69 | MODULE_DESCRIPTION("Common macro driver" ); |
70 | MODULE_LICENSE("GPL" ); |
71 | |