| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224 |
- // SPDX-License-Identifier: GPL-2.0
- /*
- * KUnit test for KUnit platform driver infrastructure.
- */
- #include <linux/platform_device.h>
- #include <kunit/platform_device.h>
- #include <kunit/test.h>
- /*
- * Test that kunit_platform_device_alloc() creates a platform device.
- */
- static void kunit_platform_device_alloc_test(struct kunit *test)
- {
- KUNIT_EXPECT_NOT_ERR_OR_NULL(test,
- kunit_platform_device_alloc(test, "kunit-platform", 1));
- }
- /*
- * Test that kunit_platform_device_add() registers a platform device on the
- * platform bus with the proper name and id.
- */
- static void kunit_platform_device_add_test(struct kunit *test)
- {
- struct platform_device *pdev;
- const char *name = "kunit-platform-add";
- const int id = -1;
- pdev = kunit_platform_device_alloc(test, name, id);
- KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev);
- KUNIT_EXPECT_EQ(test, 0, kunit_platform_device_add(test, pdev));
- KUNIT_EXPECT_TRUE(test, dev_is_platform(&pdev->dev));
- KUNIT_EXPECT_STREQ(test, pdev->name, name);
- KUNIT_EXPECT_EQ(test, pdev->id, id);
- }
- /*
- * Test that kunit_platform_device_add() called twice with the same device name
- * and id fails the second time and properly cleans up.
- */
- static void kunit_platform_device_add_twice_fails_test(struct kunit *test)
- {
- struct platform_device *pdev;
- const char *name = "kunit-platform-add-2";
- const int id = -1;
- pdev = kunit_platform_device_alloc(test, name, id);
- KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev);
- KUNIT_ASSERT_EQ(test, 0, kunit_platform_device_add(test, pdev));
- pdev = kunit_platform_device_alloc(test, name, id);
- KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev);
- KUNIT_EXPECT_NE(test, 0, kunit_platform_device_add(test, pdev));
- }
- static int kunit_platform_device_find_by_name(struct device *dev, const void *data)
- {
- return strcmp(dev_name(dev), data) == 0;
- }
- /*
- * Test that kunit_platform_device_add() cleans up by removing the platform
- * device when the test finishes. */
- static void kunit_platform_device_add_cleans_up(struct kunit *test)
- {
- struct platform_device *pdev;
- const char *name = "kunit-platform-clean";
- const int id = -1;
- struct kunit fake;
- struct device *dev;
- kunit_init_test(&fake, "kunit_platform_device_add_fake_test", NULL);
- KUNIT_ASSERT_EQ(test, fake.status, KUNIT_SUCCESS);
- pdev = kunit_platform_device_alloc(&fake, name, id);
- KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev);
- KUNIT_ASSERT_EQ(test, 0, kunit_platform_device_add(&fake, pdev));
- dev = bus_find_device(&platform_bus_type, NULL, name,
- kunit_platform_device_find_by_name);
- KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
- put_device(dev);
- /* Remove pdev */
- kunit_cleanup(&fake);
- /*
- * Failing to migrate the kunit_resource would lead to an extra
- * put_device() call on the platform device. The best we can do here is
- * make sure the device no longer exists on the bus, but if something
- * is wrong we'll see a refcount underflow here. We can't test for a
- * refcount underflow because the kref matches the lifetime of the
- * device which should already be freed and could be used by something
- * else.
- */
- dev = bus_find_device(&platform_bus_type, NULL, name,
- kunit_platform_device_find_by_name);
- KUNIT_EXPECT_PTR_EQ(test, NULL, dev);
- put_device(dev);
- }
- /*
- * Test suite for struct platform_device kunit APIs
- */
- static struct kunit_case kunit_platform_device_test_cases[] = {
- KUNIT_CASE(kunit_platform_device_alloc_test),
- KUNIT_CASE(kunit_platform_device_add_test),
- KUNIT_CASE(kunit_platform_device_add_twice_fails_test),
- KUNIT_CASE(kunit_platform_device_add_cleans_up),
- {}
- };
- static struct kunit_suite kunit_platform_device_suite = {
- .name = "kunit_platform_device",
- .test_cases = kunit_platform_device_test_cases,
- };
- struct kunit_platform_driver_test_context {
- struct platform_driver pdrv;
- const char *data;
- };
- static const char * const test_data = "test data";
- static inline struct kunit_platform_driver_test_context *
- to_test_context(struct platform_device *pdev)
- {
- return container_of(to_platform_driver(pdev->dev.driver),
- struct kunit_platform_driver_test_context,
- pdrv);
- }
- static int kunit_platform_driver_probe(struct platform_device *pdev)
- {
- struct kunit_platform_driver_test_context *ctx;
- ctx = to_test_context(pdev);
- ctx->data = test_data;
- return 0;
- }
- /* Test that kunit_platform_driver_register() registers a driver that probes. */
- static void kunit_platform_driver_register_test(struct kunit *test)
- {
- struct platform_device *pdev;
- struct kunit_platform_driver_test_context *ctx;
- DECLARE_COMPLETION_ONSTACK(comp);
- const char *name = "kunit-platform-register";
- ctx = kunit_kzalloc(test, sizeof(*ctx), GFP_KERNEL);
- KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
- pdev = kunit_platform_device_alloc(test, name, -1);
- KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev);
- KUNIT_ASSERT_EQ(test, 0, kunit_platform_device_add(test, pdev));
- ctx->pdrv.probe = kunit_platform_driver_probe;
- ctx->pdrv.driver.name = name;
- ctx->pdrv.driver.owner = THIS_MODULE;
- KUNIT_ASSERT_EQ(test, 0, kunit_platform_device_prepare_wait_for_probe(test, pdev, &comp));
- KUNIT_EXPECT_EQ(test, 0, kunit_platform_driver_register(test, &ctx->pdrv));
- KUNIT_EXPECT_NE(test, 0, wait_for_completion_timeout(&comp, 3 * HZ));
- KUNIT_EXPECT_STREQ(test, ctx->data, test_data);
- }
- /*
- * Test that kunit_platform_device_prepare_wait_for_probe() completes the completion
- * when the device is already probed.
- */
- static void kunit_platform_device_prepare_wait_for_probe_completes_when_already_probed(struct kunit *test)
- {
- struct platform_device *pdev;
- struct kunit_platform_driver_test_context *ctx;
- DECLARE_COMPLETION_ONSTACK(comp);
- const char *name = "kunit-platform-wait";
- ctx = kunit_kzalloc(test, sizeof(*ctx), GFP_KERNEL);
- KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
- pdev = kunit_platform_device_alloc(test, name, -1);
- KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev);
- KUNIT_ASSERT_EQ(test, 0, kunit_platform_device_add(test, pdev));
- ctx->pdrv.probe = kunit_platform_driver_probe;
- ctx->pdrv.driver.name = name;
- ctx->pdrv.driver.owner = THIS_MODULE;
- /* Make sure driver has actually probed */
- KUNIT_ASSERT_EQ(test, 0, kunit_platform_device_prepare_wait_for_probe(test, pdev, &comp));
- KUNIT_ASSERT_EQ(test, 0, kunit_platform_driver_register(test, &ctx->pdrv));
- KUNIT_ASSERT_NE(test, 0, wait_for_completion_timeout(&comp, 3 * HZ));
- reinit_completion(&comp);
- KUNIT_ASSERT_EQ(test, 0, kunit_platform_device_prepare_wait_for_probe(test, pdev, &comp));
- KUNIT_EXPECT_NE(test, 0, wait_for_completion_timeout(&comp, HZ));
- }
- static struct kunit_case kunit_platform_driver_test_cases[] = {
- KUNIT_CASE(kunit_platform_driver_register_test),
- KUNIT_CASE(kunit_platform_device_prepare_wait_for_probe_completes_when_already_probed),
- {}
- };
- /*
- * Test suite for struct platform_driver kunit APIs
- */
- static struct kunit_suite kunit_platform_driver_suite = {
- .name = "kunit_platform_driver",
- .test_cases = kunit_platform_driver_test_cases,
- };
- kunit_test_suites(
- &kunit_platform_device_suite,
- &kunit_platform_driver_suite,
- );
- MODULE_LICENSE("GPL");
- MODULE_DESCRIPTION("KUnit test for KUnit platform driver infrastructure");
|