1 // SPDX-License-Identifier: GPL-2.0 2 3 #include <kunit/platform_device.h> 4 #include <kunit/resource.h> 5 6 #include <linux/device.h> 7 #include <linux/device/bus.h> 8 #include <linux/of_platform.h> 9 #include <linux/platform_device.h> 10 11 #define DEVICE_NAME "test" 12 13 struct test_priv { 14 bool probe_done; 15 bool release_done; 16 wait_queue_head_t probe_wq; 17 wait_queue_head_t release_wq; 18 struct device *dev; 19 }; 20 21 static int platform_device_devm_init(struct kunit *test) 22 { 23 struct test_priv *priv; 24 25 priv = kunit_kzalloc(test, sizeof(*priv), GFP_KERNEL); 26 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv); 27 init_waitqueue_head(&priv->probe_wq); 28 init_waitqueue_head(&priv->release_wq); 29 30 test->priv = priv; 31 32 return 0; 33 } 34 35 static void devm_device_action(void *ptr) 36 { 37 struct test_priv *priv = ptr; 38 39 priv->release_done = true; 40 wake_up_interruptible(&priv->release_wq); 41 } 42 43 static void devm_put_device_action(void *ptr) 44 { 45 struct test_priv *priv = ptr; 46 47 put_device(priv->dev); 48 priv->release_done = true; 49 wake_up_interruptible(&priv->release_wq); 50 } 51 52 #define RELEASE_TIMEOUT_MS 100 53 54 /* 55 * Tests that a platform bus, non-probed device will run its 56 * device-managed actions when unregistered. 57 */ 58 static void platform_device_devm_register_unregister_test(struct kunit *test) 59 { 60 struct platform_device *pdev; 61 struct test_priv *priv = test->priv; 62 int ret; 63 64 pdev = platform_device_alloc(DEVICE_NAME, PLATFORM_DEVID_NONE); 65 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev); 66 67 ret = platform_device_add(pdev); 68 KUNIT_ASSERT_EQ(test, ret, 0); 69 70 priv->dev = &pdev->dev; 71 72 ret = devm_add_action_or_reset(priv->dev, devm_device_action, priv); 73 KUNIT_ASSERT_EQ(test, ret, 0); 74 75 platform_device_unregister(pdev); 76 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 82 /* 83 * Tests that a platform bus, non-probed device will run its 84 * device-managed actions when unregistered, even if someone still holds 85 * a reference to it. 86 */ 87 static void platform_device_devm_register_get_unregister_with_devm_test(struct kunit *test) 88 { 89 struct platform_device *pdev; 90 struct test_priv *priv = test->priv; 91 int ret; 92 93 pdev = platform_device_alloc(DEVICE_NAME, PLATFORM_DEVID_NONE); 94 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev); 95 96 ret = platform_device_add(pdev); 97 KUNIT_ASSERT_EQ(test, ret, 0); 98 99 priv->dev = &pdev->dev; 100 101 get_device(priv->dev); 102 103 ret = devm_add_action_or_reset(priv->dev, devm_put_device_action, priv); 104 KUNIT_ASSERT_EQ(test, ret, 0); 105 106 platform_device_unregister(pdev); 107 108 ret = wait_event_interruptible_timeout(priv->release_wq, priv->release_done, 109 msecs_to_jiffies(RELEASE_TIMEOUT_MS)); 110 KUNIT_EXPECT_GT(test, ret, 0); 111 } 112 113 static int fake_probe(struct platform_device *pdev) 114 { 115 struct test_priv *priv = platform_get_drvdata(pdev); 116 117 priv->probe_done = true; 118 wake_up_interruptible(&priv->probe_wq); 119 120 return 0; 121 } 122 123 static struct platform_driver fake_driver = { 124 .probe = fake_probe, 125 .driver = { 126 .name = DEVICE_NAME, 127 }, 128 }; 129 130 /* 131 * Tests that a platform bus, probed device will run its device-managed 132 * actions when unregistered. 133 */ 134 static void probed_platform_device_devm_register_unregister_test(struct kunit *test) 135 { 136 struct platform_device *pdev; 137 struct test_priv *priv = test->priv; 138 int ret; 139 140 ret = platform_driver_register(&fake_driver); 141 KUNIT_ASSERT_EQ(test, ret, 0); 142 143 pdev = platform_device_alloc(DEVICE_NAME, PLATFORM_DEVID_NONE); 144 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev); 145 146 priv->dev = &pdev->dev; 147 platform_set_drvdata(pdev, priv); 148 149 ret = platform_device_add(pdev); 150 KUNIT_ASSERT_EQ(test, ret, 0); 151 152 ret = wait_event_interruptible_timeout(priv->probe_wq, priv->probe_done, 153 msecs_to_jiffies(RELEASE_TIMEOUT_MS)); 154 KUNIT_ASSERT_GT(test, ret, 0); 155 156 ret = devm_add_action_or_reset(priv->dev, devm_device_action, priv); 157 KUNIT_ASSERT_EQ(test, ret, 0); 158 159 platform_device_unregister(pdev); 160 161 ret = wait_event_interruptible_timeout(priv->release_wq, priv->release_done, 162 msecs_to_jiffies(RELEASE_TIMEOUT_MS)); 163 KUNIT_EXPECT_GT(test, ret, 0); 164 165 platform_driver_unregister(&fake_driver); 166 } 167 168 /* 169 * Tests that a platform bus, probed device will run its device-managed 170 * actions when unregistered, even if someone still holds a reference to 171 * it. 172 */ 173 static void probed_platform_device_devm_register_get_unregister_with_devm_test(struct kunit *test) 174 { 175 struct platform_device *pdev; 176 struct test_priv *priv = test->priv; 177 int ret; 178 179 ret = platform_driver_register(&fake_driver); 180 KUNIT_ASSERT_EQ(test, ret, 0); 181 182 pdev = platform_device_alloc(DEVICE_NAME, PLATFORM_DEVID_NONE); 183 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev); 184 185 priv->dev = &pdev->dev; 186 platform_set_drvdata(pdev, priv); 187 188 ret = platform_device_add(pdev); 189 KUNIT_ASSERT_EQ(test, ret, 0); 190 191 ret = wait_event_interruptible_timeout(priv->probe_wq, priv->probe_done, 192 msecs_to_jiffies(RELEASE_TIMEOUT_MS)); 193 KUNIT_ASSERT_GT(test, ret, 0); 194 195 get_device(priv->dev); 196 197 ret = devm_add_action_or_reset(priv->dev, devm_put_device_action, priv); 198 KUNIT_ASSERT_EQ(test, ret, 0); 199 200 platform_device_unregister(pdev); 201 202 ret = wait_event_interruptible_timeout(priv->release_wq, priv->release_done, 203 msecs_to_jiffies(RELEASE_TIMEOUT_MS)); 204 KUNIT_EXPECT_GT(test, ret, 0); 205 206 platform_driver_unregister(&fake_driver); 207 } 208 209 static struct kunit_case platform_device_devm_tests[] = { 210 KUNIT_CASE(platform_device_devm_register_unregister_test), 211 KUNIT_CASE(platform_device_devm_register_get_unregister_with_devm_test), 212 KUNIT_CASE(probed_platform_device_devm_register_unregister_test), 213 KUNIT_CASE(probed_platform_device_devm_register_get_unregister_with_devm_test), 214 {} 215 }; 216 217 static struct kunit_suite platform_device_devm_test_suite = { 218 .name = "platform-device-devm", 219 .init = platform_device_devm_init, 220 .test_cases = platform_device_devm_tests, 221 }; 222 223 static void platform_device_find_by_null_test(struct kunit *test) 224 { 225 struct platform_device *pdev; 226 int ret; 227 228 pdev = kunit_platform_device_alloc(test, DEVICE_NAME, PLATFORM_DEVID_NONE); 229 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev); 230 231 ret = kunit_platform_device_add(test, pdev); 232 KUNIT_ASSERT_EQ(test, ret, 0); 233 234 KUNIT_EXPECT_PTR_EQ(test, of_find_device_by_node(NULL), NULL); 235 236 KUNIT_EXPECT_PTR_EQ(test, bus_find_device_by_of_node(&platform_bus_type, NULL), NULL); 237 KUNIT_EXPECT_PTR_EQ(test, bus_find_device_by_fwnode(&platform_bus_type, NULL), NULL); 238 KUNIT_EXPECT_PTR_EQ(test, bus_find_device_by_acpi_dev(&platform_bus_type, NULL), NULL); 239 240 KUNIT_EXPECT_FALSE(test, device_match_of_node(&pdev->dev, NULL)); 241 KUNIT_EXPECT_FALSE(test, device_match_fwnode(&pdev->dev, NULL)); 242 KUNIT_EXPECT_FALSE(test, device_match_acpi_dev(&pdev->dev, NULL)); 243 KUNIT_EXPECT_FALSE(test, device_match_acpi_handle(&pdev->dev, NULL)); 244 } 245 246 static struct kunit_case platform_device_match_tests[] = { 247 KUNIT_CASE(platform_device_find_by_null_test), 248 {} 249 }; 250 251 static struct kunit_suite platform_device_match_test_suite = { 252 .name = "platform-device-match", 253 .test_cases = platform_device_match_tests, 254 }; 255 256 kunit_test_suites( 257 &platform_device_devm_test_suite, 258 &platform_device_match_test_suite, 259 ); 260 261 MODULE_DESCRIPTION("Test module for platform devices"); 262 MODULE_AUTHOR("Maxime Ripard <mripard@kernel.org>"); 263 MODULE_LICENSE("GPL"); 264