xref: /linux/drivers/base/power/runtime-test.c (revision d0b8651a026125d58b50b464aeb78f2c5956179f)
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 
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_PTR_NE(test, NULL, 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. */
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_PTR_NE(test, NULL, 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 
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_PTR_NE(test, NULL, 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 
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_PTR_NE(test, NULL, 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 
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_PTR_NE(test, NULL, 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  */
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_PTR_NE(test, NULL, 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