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_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. */ 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 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 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 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 */ 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