xref: /linux/drivers/base/test/platform-device-test.c (revision 59e6295fac26b8e85c1ea859cdd89fa1e47519d7)
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