Path: blob/master/drivers/base/test/platform-device-test.c
26428 views
// SPDX-License-Identifier: GPL-2.012#include <kunit/platform_device.h>3#include <kunit/resource.h>45#include <linux/device.h>6#include <linux/device/bus.h>7#include <linux/of_platform.h>8#include <linux/platform_device.h>910#define DEVICE_NAME "test"1112struct test_priv {13bool probe_done;14bool release_done;15wait_queue_head_t probe_wq;16wait_queue_head_t release_wq;17struct device *dev;18};1920static int platform_device_devm_init(struct kunit *test)21{22struct test_priv *priv;2324priv = kunit_kzalloc(test, sizeof(*priv), GFP_KERNEL);25KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv);26init_waitqueue_head(&priv->probe_wq);27init_waitqueue_head(&priv->release_wq);2829test->priv = priv;3031return 0;32}3334static void devm_device_action(void *ptr)35{36struct test_priv *priv = ptr;3738priv->release_done = true;39wake_up_interruptible(&priv->release_wq);40}4142static void devm_put_device_action(void *ptr)43{44struct test_priv *priv = ptr;4546put_device(priv->dev);47priv->release_done = true;48wake_up_interruptible(&priv->release_wq);49}5051#define RELEASE_TIMEOUT_MS 1005253/*54* Tests that a platform bus, non-probed device will run its55* device-managed actions when unregistered.56*/57static void platform_device_devm_register_unregister_test(struct kunit *test)58{59struct platform_device *pdev;60struct test_priv *priv = test->priv;61int ret;6263pdev = platform_device_alloc(DEVICE_NAME, PLATFORM_DEVID_NONE);64KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev);6566ret = platform_device_add(pdev);67KUNIT_ASSERT_EQ(test, ret, 0);6869priv->dev = &pdev->dev;7071ret = devm_add_action_or_reset(priv->dev, devm_device_action, priv);72KUNIT_ASSERT_EQ(test, ret, 0);7374platform_device_unregister(pdev);7576ret = wait_event_interruptible_timeout(priv->release_wq, priv->release_done,77msecs_to_jiffies(RELEASE_TIMEOUT_MS));78KUNIT_EXPECT_GT(test, ret, 0);79}8081/*82* Tests that a platform bus, non-probed device will run its83* device-managed actions when unregistered, even if someone still holds84* a reference to it.85*/86static void platform_device_devm_register_get_unregister_with_devm_test(struct kunit *test)87{88struct platform_device *pdev;89struct test_priv *priv = test->priv;90int ret;9192pdev = platform_device_alloc(DEVICE_NAME, PLATFORM_DEVID_NONE);93KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev);9495ret = platform_device_add(pdev);96KUNIT_ASSERT_EQ(test, ret, 0);9798priv->dev = &pdev->dev;99100get_device(priv->dev);101102ret = devm_add_action_or_reset(priv->dev, devm_put_device_action, priv);103KUNIT_ASSERT_EQ(test, ret, 0);104105platform_device_unregister(pdev);106107ret = wait_event_interruptible_timeout(priv->release_wq, priv->release_done,108msecs_to_jiffies(RELEASE_TIMEOUT_MS));109KUNIT_EXPECT_GT(test, ret, 0);110}111112static int fake_probe(struct platform_device *pdev)113{114struct test_priv *priv = platform_get_drvdata(pdev);115116priv->probe_done = true;117wake_up_interruptible(&priv->probe_wq);118119return 0;120}121122static struct platform_driver fake_driver = {123.probe = fake_probe,124.driver = {125.name = DEVICE_NAME,126},127};128129/*130* Tests that a platform bus, probed device will run its device-managed131* actions when unregistered.132*/133static void probed_platform_device_devm_register_unregister_test(struct kunit *test)134{135struct platform_device *pdev;136struct test_priv *priv = test->priv;137int ret;138139ret = platform_driver_register(&fake_driver);140KUNIT_ASSERT_EQ(test, ret, 0);141142pdev = platform_device_alloc(DEVICE_NAME, PLATFORM_DEVID_NONE);143KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev);144145priv->dev = &pdev->dev;146platform_set_drvdata(pdev, priv);147148ret = platform_device_add(pdev);149KUNIT_ASSERT_EQ(test, ret, 0);150151ret = wait_event_interruptible_timeout(priv->probe_wq, priv->probe_done,152msecs_to_jiffies(RELEASE_TIMEOUT_MS));153KUNIT_ASSERT_GT(test, ret, 0);154155ret = devm_add_action_or_reset(priv->dev, devm_device_action, priv);156KUNIT_ASSERT_EQ(test, ret, 0);157158platform_device_unregister(pdev);159160ret = wait_event_interruptible_timeout(priv->release_wq, priv->release_done,161msecs_to_jiffies(RELEASE_TIMEOUT_MS));162KUNIT_EXPECT_GT(test, ret, 0);163164platform_driver_unregister(&fake_driver);165}166167/*168* Tests that a platform bus, probed device will run its device-managed169* actions when unregistered, even if someone still holds a reference to170* it.171*/172static void probed_platform_device_devm_register_get_unregister_with_devm_test(struct kunit *test)173{174struct platform_device *pdev;175struct test_priv *priv = test->priv;176int ret;177178ret = platform_driver_register(&fake_driver);179KUNIT_ASSERT_EQ(test, ret, 0);180181pdev = platform_device_alloc(DEVICE_NAME, PLATFORM_DEVID_NONE);182KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev);183184priv->dev = &pdev->dev;185platform_set_drvdata(pdev, priv);186187ret = platform_device_add(pdev);188KUNIT_ASSERT_EQ(test, ret, 0);189190ret = wait_event_interruptible_timeout(priv->probe_wq, priv->probe_done,191msecs_to_jiffies(RELEASE_TIMEOUT_MS));192KUNIT_ASSERT_GT(test, ret, 0);193194get_device(priv->dev);195196ret = devm_add_action_or_reset(priv->dev, devm_put_device_action, priv);197KUNIT_ASSERT_EQ(test, ret, 0);198199platform_device_unregister(pdev);200201ret = wait_event_interruptible_timeout(priv->release_wq, priv->release_done,202msecs_to_jiffies(RELEASE_TIMEOUT_MS));203KUNIT_EXPECT_GT(test, ret, 0);204205platform_driver_unregister(&fake_driver);206}207208static struct kunit_case platform_device_devm_tests[] = {209KUNIT_CASE(platform_device_devm_register_unregister_test),210KUNIT_CASE(platform_device_devm_register_get_unregister_with_devm_test),211KUNIT_CASE(probed_platform_device_devm_register_unregister_test),212KUNIT_CASE(probed_platform_device_devm_register_get_unregister_with_devm_test),213{}214};215216static struct kunit_suite platform_device_devm_test_suite = {217.name = "platform-device-devm",218.init = platform_device_devm_init,219.test_cases = platform_device_devm_tests,220};221222static void platform_device_find_by_null_test(struct kunit *test)223{224struct platform_device *pdev;225int ret;226227pdev = kunit_platform_device_alloc(test, DEVICE_NAME, PLATFORM_DEVID_NONE);228KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev);229230ret = kunit_platform_device_add(test, pdev);231KUNIT_ASSERT_EQ(test, ret, 0);232233KUNIT_EXPECT_PTR_EQ(test, of_find_device_by_node(NULL), NULL);234235KUNIT_EXPECT_PTR_EQ(test, bus_find_device_by_of_node(&platform_bus_type, NULL), NULL);236KUNIT_EXPECT_PTR_EQ(test, bus_find_device_by_fwnode(&platform_bus_type, NULL), NULL);237KUNIT_EXPECT_PTR_EQ(test, bus_find_device_by_acpi_dev(&platform_bus_type, NULL), NULL);238239KUNIT_EXPECT_FALSE(test, device_match_of_node(&pdev->dev, NULL));240KUNIT_EXPECT_FALSE(test, device_match_fwnode(&pdev->dev, NULL));241KUNIT_EXPECT_FALSE(test, device_match_acpi_dev(&pdev->dev, NULL));242KUNIT_EXPECT_FALSE(test, device_match_acpi_handle(&pdev->dev, NULL));243}244245static struct kunit_case platform_device_match_tests[] = {246KUNIT_CASE(platform_device_find_by_null_test),247{}248};249250static struct kunit_suite platform_device_match_test_suite = {251.name = "platform-device-match",252.test_cases = platform_device_match_tests,253};254255kunit_test_suites(256&platform_device_devm_test_suite,257&platform_device_match_test_suite,258);259260MODULE_DESCRIPTION("Test module for platform devices");261MODULE_AUTHOR("Maxime Ripard <[email protected]>");262MODULE_LICENSE("GPL");263264265