1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright 2025 Google, Inc.
4 */
5
6 #include <linux/cleanup.h>
7 #include <linux/pm_runtime.h>
8 #include <kunit/device.h>
9 #include <kunit/test.h>
10
11 #define DEVICE_NAME "pm_runtime_test_device"
12
pm_runtime_depth_test(struct kunit * test)13 static void pm_runtime_depth_test(struct kunit *test)
14 {
15 struct device *dev = kunit_device_register(test, DEVICE_NAME);
16
17 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
18
19 pm_runtime_enable(dev);
20
21 KUNIT_EXPECT_TRUE(test, pm_runtime_suspended(dev));
22 KUNIT_EXPECT_EQ(test, 0, pm_runtime_get_sync(dev));
23 KUNIT_EXPECT_TRUE(test, pm_runtime_active(dev));
24 KUNIT_EXPECT_EQ(test, 1, pm_runtime_get_sync(dev)); /* "already active" */
25 KUNIT_EXPECT_EQ(test, 0, pm_runtime_put_sync(dev));
26 KUNIT_EXPECT_EQ(test, 0, pm_runtime_put_sync(dev));
27 KUNIT_EXPECT_TRUE(test, pm_runtime_suspended(dev));
28 }
29
30 /* Test pm_runtime_put() and friends when already suspended. */
pm_runtime_already_suspended_test(struct kunit * test)31 static void pm_runtime_already_suspended_test(struct kunit *test)
32 {
33 struct device *dev = kunit_device_register(test, DEVICE_NAME);
34
35 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
36
37 pm_runtime_enable(dev);
38 KUNIT_EXPECT_TRUE(test, pm_runtime_suspended(dev));
39
40 pm_runtime_get_noresume(dev);
41 KUNIT_EXPECT_EQ(test, 0, pm_runtime_barrier(dev)); /* no wakeup needed */
42 pm_runtime_put(dev);
43
44 pm_runtime_get_noresume(dev);
45 KUNIT_EXPECT_EQ(test, 1, pm_runtime_put_sync(dev));
46
47 KUNIT_EXPECT_EQ(test, 1, pm_runtime_suspend(dev));
48 KUNIT_EXPECT_EQ(test, 1, pm_runtime_autosuspend(dev));
49 KUNIT_EXPECT_EQ(test, 1, pm_request_autosuspend(dev));
50
51 pm_runtime_get_noresume(dev);
52 KUNIT_EXPECT_EQ(test, 1, pm_runtime_put_sync_autosuspend(dev));
53
54 pm_runtime_get_noresume(dev);
55 pm_runtime_put_autosuspend(dev);
56
57 /* Grab 2 refcounts */
58 pm_runtime_get_noresume(dev);
59 pm_runtime_get_noresume(dev);
60 /* The first put() sees usage_count 1 */
61 KUNIT_EXPECT_EQ(test, 0, pm_runtime_put_sync_autosuspend(dev));
62 /* The second put() sees usage_count 0 but tells us "already suspended". */
63 KUNIT_EXPECT_EQ(test, 1, pm_runtime_put_sync_autosuspend(dev));
64
65 /* Should have remained suspended the whole time. */
66 KUNIT_EXPECT_TRUE(test, pm_runtime_suspended(dev));
67 }
68
pm_runtime_idle_test(struct kunit * test)69 static void pm_runtime_idle_test(struct kunit *test)
70 {
71 struct device *dev = kunit_device_register(test, DEVICE_NAME);
72
73 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
74
75 pm_runtime_enable(dev);
76
77 KUNIT_EXPECT_TRUE(test, pm_runtime_suspended(dev));
78 KUNIT_EXPECT_EQ(test, 0, pm_runtime_get_sync(dev));
79 KUNIT_EXPECT_TRUE(test, pm_runtime_active(dev));
80 KUNIT_EXPECT_EQ(test, -EAGAIN, pm_runtime_idle(dev));
81 KUNIT_EXPECT_TRUE(test, pm_runtime_active(dev));
82 pm_runtime_put_noidle(dev);
83 KUNIT_EXPECT_TRUE(test, pm_runtime_active(dev));
84 KUNIT_EXPECT_EQ(test, 0, pm_runtime_idle(dev));
85 KUNIT_EXPECT_TRUE(test, pm_runtime_suspended(dev));
86 KUNIT_EXPECT_EQ(test, -EAGAIN, pm_runtime_idle(dev));
87 KUNIT_EXPECT_EQ(test, -EAGAIN, pm_request_idle(dev));
88 }
89
pm_runtime_disabled_test(struct kunit * test)90 static void pm_runtime_disabled_test(struct kunit *test)
91 {
92 struct device *dev = kunit_device_register(test, DEVICE_NAME);
93
94 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
95
96 /* Never called pm_runtime_enable() */
97 KUNIT_EXPECT_FALSE(test, pm_runtime_enabled(dev));
98
99 /* "disabled" is treated as "active" */
100 KUNIT_EXPECT_TRUE(test, pm_runtime_active(dev));
101 KUNIT_EXPECT_FALSE(test, pm_runtime_suspended(dev));
102
103 /*
104 * Note: these "fail", but they still acquire/release refcounts, so
105 * keep them balanced.
106 */
107 KUNIT_EXPECT_EQ(test, -EACCES, pm_runtime_get(dev));
108 pm_runtime_put(dev);
109
110 KUNIT_EXPECT_EQ(test, -EACCES, pm_runtime_get_sync(dev));
111 KUNIT_EXPECT_EQ(test, -EACCES, pm_runtime_put_sync(dev));
112
113 KUNIT_EXPECT_EQ(test, -EACCES, pm_runtime_get(dev));
114 pm_runtime_put_autosuspend(dev);
115
116 KUNIT_EXPECT_EQ(test, -EACCES, pm_runtime_resume_and_get(dev));
117 KUNIT_EXPECT_EQ(test, -EACCES, pm_runtime_idle(dev));
118 KUNIT_EXPECT_EQ(test, -EACCES, pm_request_idle(dev));
119 KUNIT_EXPECT_EQ(test, -EACCES, pm_request_resume(dev));
120 KUNIT_EXPECT_EQ(test, -EACCES, pm_request_autosuspend(dev));
121 KUNIT_EXPECT_EQ(test, -EACCES, pm_runtime_suspend(dev));
122 KUNIT_EXPECT_EQ(test, -EACCES, pm_runtime_resume(dev));
123 KUNIT_EXPECT_EQ(test, -EACCES, pm_runtime_autosuspend(dev));
124
125 /* Still disabled */
126 KUNIT_EXPECT_TRUE(test, pm_runtime_active(dev));
127 KUNIT_EXPECT_FALSE(test, pm_runtime_enabled(dev));
128 }
129
pm_runtime_error_test(struct kunit * test)130 static void pm_runtime_error_test(struct kunit *test)
131 {
132 struct device *dev = kunit_device_register(test, DEVICE_NAME);
133
134 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
135
136 pm_runtime_enable(dev);
137 KUNIT_EXPECT_TRUE(test, pm_runtime_suspended(dev));
138
139 /* Fake a .runtime_resume() error */
140 dev->power.runtime_error = -EIO;
141
142 /*
143 * Note: these "fail", but they still acquire/release refcounts, so
144 * keep them balanced.
145 */
146 KUNIT_EXPECT_EQ(test, -EINVAL, pm_runtime_get(dev));
147 pm_runtime_put(dev);
148
149 KUNIT_EXPECT_EQ(test, -EINVAL, pm_runtime_get_sync(dev));
150 KUNIT_EXPECT_EQ(test, -EINVAL, pm_runtime_put_sync(dev));
151
152 KUNIT_EXPECT_EQ(test, -EINVAL, pm_runtime_get(dev));
153 pm_runtime_put_autosuspend(dev);
154
155 KUNIT_EXPECT_EQ(test, -EINVAL, pm_runtime_get(dev));
156 KUNIT_EXPECT_EQ(test, -EINVAL, pm_runtime_put_sync_autosuspend(dev));
157
158 KUNIT_EXPECT_EQ(test, -EINVAL, pm_runtime_resume_and_get(dev));
159 KUNIT_EXPECT_EQ(test, -EINVAL, pm_runtime_idle(dev));
160 KUNIT_EXPECT_EQ(test, -EINVAL, pm_request_idle(dev));
161 KUNIT_EXPECT_EQ(test, -EINVAL, pm_request_resume(dev));
162 KUNIT_EXPECT_EQ(test, -EINVAL, pm_request_autosuspend(dev));
163 KUNIT_EXPECT_EQ(test, -EINVAL, pm_runtime_suspend(dev));
164 KUNIT_EXPECT_EQ(test, -EINVAL, pm_runtime_resume(dev));
165 KUNIT_EXPECT_EQ(test, -EINVAL, pm_runtime_autosuspend(dev));
166
167 /* Error is still pending */
168 KUNIT_EXPECT_TRUE(test, pm_runtime_suspended(dev));
169 KUNIT_EXPECT_EQ(test, -EIO, dev->power.runtime_error);
170 /* Clear error */
171 KUNIT_EXPECT_EQ(test, 0, pm_runtime_set_suspended(dev));
172 KUNIT_EXPECT_EQ(test, 0, dev->power.runtime_error);
173 /* Still suspended */
174 KUNIT_EXPECT_TRUE(test, pm_runtime_suspended(dev));
175
176 KUNIT_EXPECT_EQ(test, 0, pm_runtime_get(dev));
177 KUNIT_EXPECT_EQ(test, 1, pm_runtime_barrier(dev)); /* resume was pending */
178 pm_runtime_put(dev);
179 pm_runtime_suspend(dev); /* flush the put(), to suspend */
180 KUNIT_EXPECT_TRUE(test, pm_runtime_suspended(dev));
181
182 KUNIT_EXPECT_EQ(test, 0, pm_runtime_get_sync(dev));
183 KUNIT_EXPECT_EQ(test, 0, pm_runtime_put_sync(dev));
184
185 KUNIT_EXPECT_EQ(test, 0, pm_runtime_get_sync(dev));
186 pm_runtime_put_autosuspend(dev);
187
188 KUNIT_EXPECT_EQ(test, 0, pm_runtime_resume_and_get(dev));
189
190 /*
191 * The following should all return -EAGAIN (usage is non-zero) or 1
192 * (already resumed).
193 */
194 KUNIT_EXPECT_EQ(test, -EAGAIN, pm_runtime_idle(dev));
195 KUNIT_EXPECT_EQ(test, -EAGAIN, pm_request_idle(dev));
196 KUNIT_EXPECT_EQ(test, 1, pm_request_resume(dev));
197 KUNIT_EXPECT_EQ(test, -EAGAIN, pm_request_autosuspend(dev));
198 KUNIT_EXPECT_EQ(test, -EAGAIN, pm_runtime_suspend(dev));
199 KUNIT_EXPECT_EQ(test, 1, pm_runtime_resume(dev));
200 KUNIT_EXPECT_EQ(test, -EAGAIN, pm_runtime_autosuspend(dev));
201
202 KUNIT_EXPECT_EQ(test, 0, pm_runtime_put_sync(dev));
203
204 /* Suspended again */
205 KUNIT_EXPECT_TRUE(test, pm_runtime_suspended(dev));
206 }
207
208 /*
209 * Explore a typical probe() sequence in which a device marks itself powered,
210 * but doesn't hold any runtime PM reference, so it suspends as soon as it goes
211 * idle.
212 */
pm_runtime_probe_active_test(struct kunit * test)213 static void pm_runtime_probe_active_test(struct kunit *test)
214 {
215 struct device *dev = kunit_device_register(test, DEVICE_NAME);
216
217 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
218
219 KUNIT_EXPECT_TRUE(test, pm_runtime_status_suspended(dev));
220
221 KUNIT_EXPECT_EQ(test, 0, pm_runtime_set_active(dev));
222 KUNIT_EXPECT_TRUE(test, pm_runtime_active(dev));
223
224 pm_runtime_enable(dev);
225 KUNIT_EXPECT_TRUE(test, pm_runtime_active(dev));
226
227 /* Nothing to flush. We stay active. */
228 KUNIT_EXPECT_EQ(test, 0, pm_runtime_barrier(dev));
229 KUNIT_EXPECT_TRUE(test, pm_runtime_active(dev));
230
231 /* Ask for idle? Now we suspend. */
232 KUNIT_EXPECT_EQ(test, 0, pm_runtime_idle(dev));
233 KUNIT_EXPECT_TRUE(test, pm_runtime_suspended(dev));
234 }
235
236 static struct kunit_case pm_runtime_test_cases[] = {
237 KUNIT_CASE(pm_runtime_depth_test),
238 KUNIT_CASE(pm_runtime_already_suspended_test),
239 KUNIT_CASE(pm_runtime_idle_test),
240 KUNIT_CASE(pm_runtime_disabled_test),
241 KUNIT_CASE(pm_runtime_error_test),
242 KUNIT_CASE(pm_runtime_probe_active_test),
243 {}
244 };
245
246 static struct kunit_suite pm_runtime_test_suite = {
247 .name = "pm_runtime_test_cases",
248 .test_cases = pm_runtime_test_cases,
249 };
250
251 kunit_test_suite(pm_runtime_test_suite);
252 MODULE_DESCRIPTION("Runtime power management unit test suite");
253 MODULE_LICENSE("GPL");
254