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