platform-device-test.c 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. // SPDX-License-Identifier: GPL-2.0
  2. #include <kunit/resource.h>
  3. #include <linux/device.h>
  4. #include <linux/platform_device.h>
  5. #define DEVICE_NAME "test"
  6. struct test_priv {
  7. bool probe_done;
  8. bool release_done;
  9. wait_queue_head_t probe_wq;
  10. wait_queue_head_t release_wq;
  11. struct device *dev;
  12. };
  13. static int platform_device_devm_init(struct kunit *test)
  14. {
  15. struct test_priv *priv;
  16. priv = kunit_kzalloc(test, sizeof(*priv), GFP_KERNEL);
  17. KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv);
  18. init_waitqueue_head(&priv->probe_wq);
  19. init_waitqueue_head(&priv->release_wq);
  20. test->priv = priv;
  21. return 0;
  22. }
  23. static void devm_device_action(void *ptr)
  24. {
  25. struct test_priv *priv = ptr;
  26. priv->release_done = true;
  27. wake_up_interruptible(&priv->release_wq);
  28. }
  29. static void devm_put_device_action(void *ptr)
  30. {
  31. struct test_priv *priv = ptr;
  32. put_device(priv->dev);
  33. priv->release_done = true;
  34. wake_up_interruptible(&priv->release_wq);
  35. }
  36. #define RELEASE_TIMEOUT_MS 100
  37. /*
  38. * Tests that a platform bus, non-probed device will run its
  39. * device-managed actions when unregistered.
  40. */
  41. static void platform_device_devm_register_unregister_test(struct kunit *test)
  42. {
  43. struct platform_device *pdev;
  44. struct test_priv *priv = test->priv;
  45. int ret;
  46. pdev = platform_device_alloc(DEVICE_NAME, PLATFORM_DEVID_NONE);
  47. KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev);
  48. ret = platform_device_add(pdev);
  49. KUNIT_ASSERT_EQ(test, ret, 0);
  50. priv->dev = &pdev->dev;
  51. ret = devm_add_action_or_reset(priv->dev, devm_device_action, priv);
  52. KUNIT_ASSERT_EQ(test, ret, 0);
  53. platform_device_unregister(pdev);
  54. ret = wait_event_interruptible_timeout(priv->release_wq, priv->release_done,
  55. msecs_to_jiffies(RELEASE_TIMEOUT_MS));
  56. KUNIT_EXPECT_GT(test, ret, 0);
  57. }
  58. /*
  59. * Tests that a platform bus, non-probed device will run its
  60. * device-managed actions when unregistered, even if someone still holds
  61. * a reference to it.
  62. */
  63. static void platform_device_devm_register_get_unregister_with_devm_test(struct kunit *test)
  64. {
  65. struct platform_device *pdev;
  66. struct test_priv *priv = test->priv;
  67. int ret;
  68. pdev = platform_device_alloc(DEVICE_NAME, PLATFORM_DEVID_NONE);
  69. KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev);
  70. ret = platform_device_add(pdev);
  71. KUNIT_ASSERT_EQ(test, ret, 0);
  72. priv->dev = &pdev->dev;
  73. get_device(priv->dev);
  74. ret = devm_add_action_or_reset(priv->dev, devm_put_device_action, priv);
  75. KUNIT_ASSERT_EQ(test, ret, 0);
  76. platform_device_unregister(pdev);
  77. ret = wait_event_interruptible_timeout(priv->release_wq, priv->release_done,
  78. msecs_to_jiffies(RELEASE_TIMEOUT_MS));
  79. KUNIT_EXPECT_GT(test, ret, 0);
  80. }
  81. static int fake_probe(struct platform_device *pdev)
  82. {
  83. struct test_priv *priv = platform_get_drvdata(pdev);
  84. priv->probe_done = true;
  85. wake_up_interruptible(&priv->probe_wq);
  86. return 0;
  87. }
  88. static struct platform_driver fake_driver = {
  89. .probe = fake_probe,
  90. .driver = {
  91. .name = DEVICE_NAME,
  92. },
  93. };
  94. /*
  95. * Tests that a platform bus, probed device will run its device-managed
  96. * actions when unregistered.
  97. */
  98. static void probed_platform_device_devm_register_unregister_test(struct kunit *test)
  99. {
  100. struct platform_device *pdev;
  101. struct test_priv *priv = test->priv;
  102. int ret;
  103. ret = platform_driver_register(&fake_driver);
  104. KUNIT_ASSERT_EQ(test, ret, 0);
  105. pdev = platform_device_alloc(DEVICE_NAME, PLATFORM_DEVID_NONE);
  106. KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev);
  107. priv->dev = &pdev->dev;
  108. platform_set_drvdata(pdev, priv);
  109. ret = platform_device_add(pdev);
  110. KUNIT_ASSERT_EQ(test, ret, 0);
  111. ret = wait_event_interruptible_timeout(priv->probe_wq, priv->probe_done,
  112. msecs_to_jiffies(RELEASE_TIMEOUT_MS));
  113. KUNIT_ASSERT_GT(test, ret, 0);
  114. ret = devm_add_action_or_reset(priv->dev, devm_device_action, priv);
  115. KUNIT_ASSERT_EQ(test, ret, 0);
  116. platform_device_unregister(pdev);
  117. ret = wait_event_interruptible_timeout(priv->release_wq, priv->release_done,
  118. msecs_to_jiffies(RELEASE_TIMEOUT_MS));
  119. KUNIT_EXPECT_GT(test, ret, 0);
  120. platform_driver_unregister(&fake_driver);
  121. }
  122. /*
  123. * Tests that a platform bus, probed device will run its device-managed
  124. * actions when unregistered, even if someone still holds a reference to
  125. * it.
  126. */
  127. static void probed_platform_device_devm_register_get_unregister_with_devm_test(struct kunit *test)
  128. {
  129. struct platform_device *pdev;
  130. struct test_priv *priv = test->priv;
  131. int ret;
  132. ret = platform_driver_register(&fake_driver);
  133. KUNIT_ASSERT_EQ(test, ret, 0);
  134. pdev = platform_device_alloc(DEVICE_NAME, PLATFORM_DEVID_NONE);
  135. KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev);
  136. priv->dev = &pdev->dev;
  137. platform_set_drvdata(pdev, priv);
  138. ret = platform_device_add(pdev);
  139. KUNIT_ASSERT_EQ(test, ret, 0);
  140. ret = wait_event_interruptible_timeout(priv->probe_wq, priv->probe_done,
  141. msecs_to_jiffies(RELEASE_TIMEOUT_MS));
  142. KUNIT_ASSERT_GT(test, ret, 0);
  143. get_device(priv->dev);
  144. ret = devm_add_action_or_reset(priv->dev, devm_put_device_action, priv);
  145. KUNIT_ASSERT_EQ(test, ret, 0);
  146. platform_device_unregister(pdev);
  147. ret = wait_event_interruptible_timeout(priv->release_wq, priv->release_done,
  148. msecs_to_jiffies(RELEASE_TIMEOUT_MS));
  149. KUNIT_EXPECT_GT(test, ret, 0);
  150. platform_driver_unregister(&fake_driver);
  151. }
  152. static struct kunit_case platform_device_devm_tests[] = {
  153. KUNIT_CASE(platform_device_devm_register_unregister_test),
  154. KUNIT_CASE(platform_device_devm_register_get_unregister_with_devm_test),
  155. KUNIT_CASE(probed_platform_device_devm_register_unregister_test),
  156. KUNIT_CASE(probed_platform_device_devm_register_get_unregister_with_devm_test),
  157. {}
  158. };
  159. static struct kunit_suite platform_device_devm_test_suite = {
  160. .name = "platform-device-devm",
  161. .init = platform_device_devm_init,
  162. .test_cases = platform_device_devm_tests,
  163. };
  164. kunit_test_suite(platform_device_devm_test_suite);
  165. MODULE_DESCRIPTION("Test module for platform devices");
  166. MODULE_AUTHOR("Maxime Ripard <mripard@kernel.org>");
  167. MODULE_LICENSE("GPL");