1 /*
2  * Copyright (c) 2018 Intel Corporation
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/pm/device.h>
8 #include <zephyr/pm/device_runtime.h>
9 #include <zephyr/sys/printk.h>
10 #include "dummy_parent.h"
11 #include "dummy_driver.h"
12 
13 static const struct device *parent;
14 
dummy_open(const struct device * dev)15 static int dummy_open(const struct device *dev)
16 {
17 	int ret;
18 	enum pm_device_state state;
19 
20 	/* Make sure parent is resumed */
21 	ret = pm_device_runtime_get(parent);
22 	if (ret < 0) {
23 		return ret;
24 	}
25 
26 	ret = pm_device_runtime_get(dev);
27 	if (ret < 0) {
28 		(void)pm_device_runtime_put(parent);
29 		return ret;
30 	}
31 
32 	(void)pm_device_state_get(dev, &state);
33 	if (state == PM_DEVICE_STATE_ACTIVE) {
34 		printk("Dummy device resumed\n");
35 		ret = 0;
36 	} else {
37 		printk("Dummy device Not resumed\n");
38 		ret = -1;
39 	}
40 
41 	return ret;
42 }
43 
dummy_read(const struct device * dev,uint32_t * val)44 static int dummy_read(const struct device *dev, uint32_t *val)
45 {
46 	struct dummy_parent_api *api;
47 	int ret;
48 
49 	api = (struct dummy_parent_api *)parent->api;
50 	ret = api->transfer(parent, DUMMY_PARENT_RD, val);
51 	return ret;
52 }
53 
dummy_write(const struct device * dev,uint32_t val)54 static int dummy_write(const struct device *dev, uint32_t val)
55 {
56 	struct dummy_parent_api *api;
57 	int ret;
58 
59 	api = (struct dummy_parent_api *)parent->api;
60 	ret = api->transfer(parent, DUMMY_PARENT_WR, &val);
61 	return ret;
62 }
63 
dummy_close(const struct device * dev)64 static int dummy_close(const struct device *dev)
65 {
66 	int ret;
67 
68 	ret = pm_device_runtime_put(dev);
69 	if (ret == 1) {
70 		printk("Async suspend request queued\n");
71 	}
72 
73 	/* Parent can be suspended */
74 	if (parent) {
75 		pm_device_runtime_put(parent);
76 	}
77 
78 	return ret;
79 }
80 
dummy_device_pm_action(const struct device * dev,enum pm_device_action action)81 static int dummy_device_pm_action(const struct device *dev,
82 				  enum pm_device_action action)
83 {
84 	switch (action) {
85 	case PM_DEVICE_ACTION_RESUME:
86 		printk("child resuming..\n");
87 		break;
88 	case PM_DEVICE_ACTION_SUSPEND:
89 		printk("child suspending..\n");
90 		break;
91 	default:
92 		return -ENOTSUP;
93 	}
94 
95 	return 0;
96 }
97 
98 static const struct dummy_driver_api funcs = {
99 	.open = dummy_open,
100 	.read = dummy_read,
101 	.write = dummy_write,
102 	.close = dummy_close,
103 };
104 
dummy_init(const struct device * dev)105 int dummy_init(const struct device *dev)
106 {
107 	parent = device_get_binding(DUMMY_PARENT_NAME);
108 	if (!parent) {
109 		printk("parent not found\n");
110 	}
111 
112 	return pm_device_runtime_enable(dev);
113 }
114 
115 PM_DEVICE_DEFINE(dummy_driver, dummy_device_pm_action);
116 
117 DEVICE_DEFINE(dummy_driver, DUMMY_DRIVER_NAME, &dummy_init,
118 		    PM_DEVICE_GET(dummy_driver), NULL, NULL, POST_KERNEL,
119 		    CONFIG_KERNEL_INIT_PRIORITY_DEVICE, &funcs);
120