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