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