1 // SPDX-License-Identifier: GPL-2.0 2 3 #include <kunit/fwnode.h> 4 #include <kunit/platform_device.h> 5 #include <kunit/resource.h> 6 7 #include <linux/device.h> 8 #include <linux/device/bus.h> 9 #include <linux/fwnode.h> 10 #include <linux/of_platform.h> 11 #include <linux/platform_device.h> 12 #include <linux/property.h> 13 14 #define DEVICE_NAME "test" 15 16 struct test_priv { 17 bool probe_done; 18 bool release_done; 19 wait_queue_head_t probe_wq; 20 wait_queue_head_t release_wq; 21 struct device *dev; 22 }; 23 24 static int platform_device_devm_init(struct kunit *test) 25 { 26 struct test_priv *priv; 27 28 priv = kunit_kzalloc(test, sizeof(*priv), GFP_KERNEL); 29 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv); 30 init_waitqueue_head(&priv->probe_wq); 31 init_waitqueue_head(&priv->release_wq); 32 33 test->priv = priv; 34 35 return 0; 36 } 37 38 static void devm_device_action(void *ptr) 39 { 40 struct test_priv *priv = ptr; 41 42 priv->release_done = true; 43 wake_up_interruptible(&priv->release_wq); 44 } 45 46 static void devm_put_device_action(void *ptr) 47 { 48 struct test_priv *priv = ptr; 49 50 put_device(priv->dev); 51 priv->release_done = true; 52 wake_up_interruptible(&priv->release_wq); 53 } 54 55 #define RELEASE_TIMEOUT_MS 100 56 57 /* 58 * Tests that a platform bus, non-probed device will run its 59 * device-managed actions when unregistered. 60 */ 61 static void platform_device_devm_register_unregister_test(struct kunit *test) 62 { 63 struct platform_device *pdev; 64 struct test_priv *priv = test->priv; 65 int ret; 66 67 pdev = platform_device_alloc(DEVICE_NAME, PLATFORM_DEVID_NONE); 68 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev); 69 70 ret = platform_device_add(pdev); 71 KUNIT_ASSERT_EQ(test, ret, 0); 72 73 priv->dev = &pdev->dev; 74 75 ret = devm_add_action_or_reset(priv->dev, devm_device_action, priv); 76 KUNIT_ASSERT_EQ(test, ret, 0); 77 78 platform_device_unregister(pdev); 79 80 ret = wait_event_interruptible_timeout(priv->release_wq, priv->release_done, 81 msecs_to_jiffies(RELEASE_TIMEOUT_MS)); 82 KUNIT_EXPECT_GT(test, ret, 0); 83 } 84 85 /* 86 * Tests that a platform bus, non-probed device will run its 87 * device-managed actions when unregistered, even if someone still holds 88 * a reference to it. 89 */ 90 static void platform_device_devm_register_get_unregister_with_devm_test(struct kunit *test) 91 { 92 struct platform_device *pdev; 93 struct test_priv *priv = test->priv; 94 int ret; 95 96 pdev = platform_device_alloc(DEVICE_NAME, PLATFORM_DEVID_NONE); 97 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev); 98 99 ret = platform_device_add(pdev); 100 KUNIT_ASSERT_EQ(test, ret, 0); 101 102 priv->dev = &pdev->dev; 103 104 get_device(priv->dev); 105 106 ret = devm_add_action_or_reset(priv->dev, devm_put_device_action, priv); 107 KUNIT_ASSERT_EQ(test, ret, 0); 108 109 platform_device_unregister(pdev); 110 111 ret = wait_event_interruptible_timeout(priv->release_wq, priv->release_done, 112 msecs_to_jiffies(RELEASE_TIMEOUT_MS)); 113 KUNIT_EXPECT_GT(test, ret, 0); 114 } 115 116 static int fake_probe(struct platform_device *pdev) 117 { 118 struct test_priv *priv = platform_get_drvdata(pdev); 119 120 priv->probe_done = true; 121 wake_up_interruptible(&priv->probe_wq); 122 123 return 0; 124 } 125 126 static struct platform_driver fake_driver = { 127 .probe = fake_probe, 128 .driver = { 129 .name = DEVICE_NAME, 130 }, 131 }; 132 133 /* 134 * Tests that a platform bus, probed device will run its device-managed 135 * actions when unregistered. 136 */ 137 static void probed_platform_device_devm_register_unregister_test(struct kunit *test) 138 { 139 struct platform_device *pdev; 140 struct test_priv *priv = test->priv; 141 int ret; 142 143 ret = platform_driver_register(&fake_driver); 144 KUNIT_ASSERT_EQ(test, ret, 0); 145 146 pdev = platform_device_alloc(DEVICE_NAME, PLATFORM_DEVID_NONE); 147 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev); 148 149 priv->dev = &pdev->dev; 150 platform_set_drvdata(pdev, priv); 151 152 ret = platform_device_add(pdev); 153 KUNIT_ASSERT_EQ(test, ret, 0); 154 155 ret = wait_event_interruptible_timeout(priv->probe_wq, priv->probe_done, 156 msecs_to_jiffies(RELEASE_TIMEOUT_MS)); 157 KUNIT_ASSERT_GT(test, ret, 0); 158 159 ret = devm_add_action_or_reset(priv->dev, devm_device_action, priv); 160 KUNIT_ASSERT_EQ(test, ret, 0); 161 162 platform_device_unregister(pdev); 163 164 ret = wait_event_interruptible_timeout(priv->release_wq, priv->release_done, 165 msecs_to_jiffies(RELEASE_TIMEOUT_MS)); 166 KUNIT_EXPECT_GT(test, ret, 0); 167 168 platform_driver_unregister(&fake_driver); 169 } 170 171 /* 172 * Tests that a platform bus, probed device will run its device-managed 173 * actions when unregistered, even if someone still holds a reference to 174 * it. 175 */ 176 static void probed_platform_device_devm_register_get_unregister_with_devm_test(struct kunit *test) 177 { 178 struct platform_device *pdev; 179 struct test_priv *priv = test->priv; 180 int ret; 181 182 ret = platform_driver_register(&fake_driver); 183 KUNIT_ASSERT_EQ(test, ret, 0); 184 185 pdev = platform_device_alloc(DEVICE_NAME, PLATFORM_DEVID_NONE); 186 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev); 187 188 priv->dev = &pdev->dev; 189 platform_set_drvdata(pdev, priv); 190 191 ret = platform_device_add(pdev); 192 KUNIT_ASSERT_EQ(test, ret, 0); 193 194 ret = wait_event_interruptible_timeout(priv->probe_wq, priv->probe_done, 195 msecs_to_jiffies(RELEASE_TIMEOUT_MS)); 196 KUNIT_ASSERT_GT(test, ret, 0); 197 198 get_device(priv->dev); 199 200 ret = devm_add_action_or_reset(priv->dev, devm_put_device_action, priv); 201 KUNIT_ASSERT_EQ(test, ret, 0); 202 203 platform_device_unregister(pdev); 204 205 ret = wait_event_interruptible_timeout(priv->release_wq, priv->release_done, 206 msecs_to_jiffies(RELEASE_TIMEOUT_MS)); 207 KUNIT_EXPECT_GT(test, ret, 0); 208 209 platform_driver_unregister(&fake_driver); 210 } 211 212 static struct kunit_case platform_device_devm_tests[] = { 213 KUNIT_CASE(platform_device_devm_register_unregister_test), 214 KUNIT_CASE(platform_device_devm_register_get_unregister_with_devm_test), 215 KUNIT_CASE(probed_platform_device_devm_register_unregister_test), 216 KUNIT_CASE(probed_platform_device_devm_register_get_unregister_with_devm_test), 217 {} 218 }; 219 220 static struct kunit_suite platform_device_devm_test_suite = { 221 .name = "platform-device-devm", 222 .init = platform_device_devm_init, 223 .test_cases = platform_device_devm_tests, 224 }; 225 226 static void platform_device_find_by_null_test(struct kunit *test) 227 { 228 struct platform_device *pdev; 229 int ret; 230 231 pdev = kunit_platform_device_alloc(test, DEVICE_NAME, PLATFORM_DEVID_NONE); 232 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev); 233 234 ret = kunit_platform_device_add(test, pdev); 235 KUNIT_ASSERT_EQ(test, ret, 0); 236 237 KUNIT_EXPECT_PTR_EQ(test, of_find_device_by_node(NULL), NULL); 238 239 KUNIT_EXPECT_PTR_EQ(test, bus_find_device_by_of_node(&platform_bus_type, NULL), NULL); 240 KUNIT_EXPECT_PTR_EQ(test, bus_find_device_by_fwnode(&platform_bus_type, NULL), NULL); 241 KUNIT_EXPECT_PTR_EQ(test, bus_find_device_by_acpi_dev(&platform_bus_type, NULL), NULL); 242 243 KUNIT_EXPECT_FALSE(test, device_match_of_node(&pdev->dev, NULL)); 244 KUNIT_EXPECT_FALSE(test, device_match_fwnode(&pdev->dev, NULL)); 245 KUNIT_EXPECT_FALSE(test, device_match_acpi_dev(&pdev->dev, NULL)); 246 KUNIT_EXPECT_FALSE(test, device_match_acpi_handle(&pdev->dev, NULL)); 247 } 248 249 static struct kunit_case platform_device_match_tests[] = { 250 KUNIT_CASE(platform_device_find_by_null_test), 251 {} 252 }; 253 254 static struct kunit_suite platform_device_match_test_suite = { 255 .name = "platform-device-match", 256 .test_cases = platform_device_match_tests, 257 }; 258 259 static int platform_device_swnode_test_probe(struct platform_device *pdev) 260 { 261 return 0; 262 } 263 264 static struct platform_driver platform_swnode_test_driver = { 265 .probe = platform_device_swnode_test_probe, 266 .driver = { 267 .name = DEVICE_NAME, 268 }, 269 }; 270 271 static const struct software_node platform_device_test_swnode = { }; 272 273 /* 274 * Check that reusing a software node works correctly. If the call to 275 * platform_device_register_full() fails after adding the secondary firmware 276 * node, the software node must be unregistered in the device's release() 277 * callback or the subsequent call to platform_device_register_full() will fail 278 * with -EBUSY due to the software node already having been registered. 279 */ 280 static void platform_device_swnode_add_twice(struct kunit *test) 281 { 282 struct platform_device_info pdevinfo; 283 struct platform_device *pdev; 284 struct fwnode_handle *fwnode; 285 bool bound = false; 286 int ret; 287 288 fwnode = kunit_kzalloc(test, sizeof(*fwnode), GFP_KERNEL); 289 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, fwnode); 290 291 ret = kunit_platform_driver_register(test, &platform_swnode_test_driver); 292 KUNIT_ASSERT_EQ(test, ret, 0); 293 294 fwnode_init(fwnode, NULL); 295 pdevinfo = (struct platform_device_info){ 296 .name = DEVICE_NAME, 297 .id = PLATFORM_DEVID_NONE, 298 .fwnode = fwnode, 299 .swnode = &platform_device_test_swnode, 300 }; 301 302 pdev = platform_device_register_full(&pdevinfo); 303 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev); 304 305 wait_for_device_probe(); 306 scoped_guard(device, &pdev->dev) 307 bound = device_is_bound(&pdev->dev); 308 309 KUNIT_ASSERT_TRUE(test, bound); 310 311 platform_device_unregister(pdev); 312 313 pdev = platform_device_register_full(&pdevinfo); 314 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev); 315 316 wait_for_device_probe(); 317 scoped_guard(device, &pdev->dev) 318 bound = device_is_bound(&pdev->dev); 319 320 KUNIT_ASSERT_TRUE(test, bound); 321 322 platform_device_unregister(pdev); 323 } 324 325 /* 326 * Check that passing a software node as the primary firmware node of the 327 * platform device does not result in it being unregistered by the call to 328 * device_remove_software_node() in its release path. 329 */ 330 static void platform_device_swnode_as_primary(struct kunit *test) 331 { 332 struct platform_device_info pdevinfo; 333 struct platform_device *pdev; 334 struct fwnode_handle *fwnode; 335 bool bound = false; 336 int ret; 337 338 ret = kunit_platform_driver_register(test, &platform_swnode_test_driver); 339 KUNIT_ASSERT_EQ(test, ret, 0); 340 341 fwnode = kunit_software_node_register(test, &platform_device_test_swnode); 342 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, fwnode); 343 344 pdevinfo = (struct platform_device_info){ 345 .name = DEVICE_NAME, 346 .id = PLATFORM_DEVID_NONE, 347 .fwnode = fwnode, 348 }; 349 350 pdev = platform_device_register_full(&pdevinfo); 351 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev); 352 353 wait_for_device_probe(); 354 scoped_guard(device, &pdev->dev) 355 bound = device_is_bound(&pdev->dev); 356 357 KUNIT_ASSERT_TRUE(test, bound); 358 359 platform_device_unregister(pdev); 360 361 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, software_node_fwnode(&platform_device_test_swnode)); 362 } 363 364 /* 365 * Check that passing two software nodes to platform_device_register_full() 366 * fails. 367 */ 368 static void platform_device_two_swnodes(struct kunit *test) 369 { 370 static const struct property_entry properties[] = { 371 PROPERTY_ENTRY_U32("foo", 42), 372 { } 373 }; 374 375 struct platform_device_info pdevinfo; 376 struct platform_device *pdev; 377 struct fwnode_handle *fwnode; 378 int ret; 379 380 ret = kunit_platform_driver_register(test, &platform_swnode_test_driver); 381 KUNIT_ASSERT_EQ(test, ret, 0); 382 383 fwnode = kunit_software_node_register(test, &platform_device_test_swnode); 384 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, fwnode); 385 386 pdevinfo = (struct platform_device_info){ 387 .name = DEVICE_NAME, 388 .id = PLATFORM_DEVID_NONE, 389 .fwnode = fwnode, 390 .swnode = &platform_device_test_swnode, 391 }; 392 393 pdev = platform_device_register_full(&pdevinfo); 394 KUNIT_ASSERT_TRUE(test, IS_ERR(pdev)); 395 KUNIT_ASSERT_EQ_MSG(test, PTR_ERR(pdev), -EINVAL, 396 "Expected errno == -EINVAL, got: %pe", pdev); 397 398 pdevinfo = (struct platform_device_info){ 399 .name = DEVICE_NAME, 400 .id = PLATFORM_DEVID_NONE, 401 .swnode = &platform_device_test_swnode, 402 .properties = properties, 403 }; 404 405 pdev = platform_device_register_full(&pdevinfo); 406 KUNIT_ASSERT_TRUE(test, IS_ERR(pdev)); 407 KUNIT_ASSERT_EQ_MSG(test, PTR_ERR(pdev), -EINVAL, 408 "Expected errno == -EINVAL, got: %pe", pdev); 409 410 pdevinfo = (struct platform_device_info){ 411 .name = DEVICE_NAME, 412 .id = PLATFORM_DEVID_NONE, 413 .fwnode = fwnode, 414 .properties = properties, 415 }; 416 417 pdev = platform_device_register_full(&pdevinfo); 418 KUNIT_ASSERT_TRUE(test, IS_ERR(pdev)); 419 KUNIT_ASSERT_EQ_MSG(test, PTR_ERR(pdev), -EINVAL, 420 "Expected errno == -EINVAL, got: %pe", pdev); 421 } 422 423 static struct kunit_case platform_device_swnode_tests[] = { 424 KUNIT_CASE(platform_device_swnode_add_twice), 425 KUNIT_CASE(platform_device_swnode_as_primary), 426 KUNIT_CASE(platform_device_two_swnodes), 427 {} 428 }; 429 430 static struct kunit_suite platform_device_swnode_test_suite = { 431 .name = "platform-device-swnode", 432 .test_cases = platform_device_swnode_tests, 433 }; 434 435 kunit_test_suites( 436 &platform_device_devm_test_suite, 437 &platform_device_match_test_suite, 438 &platform_device_swnode_test_suite, 439 ); 440 441 MODULE_DESCRIPTION("Test module for platform devices"); 442 MODULE_AUTHOR("Maxime Ripard <mripard@kernel.org>"); 443 MODULE_LICENSE("GPL"); 444