162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci
362306a36Sopenharmony_ci#include <drm/drm_drv.h>
462306a36Sopenharmony_ci#include <drm/drm_kunit_helpers.h>
562306a36Sopenharmony_ci#include <drm/drm_managed.h>
662306a36Sopenharmony_ci
762306a36Sopenharmony_ci#include <kunit/resource.h>
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci#include <linux/device.h>
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci/* Ought to be enough for anybody */
1262306a36Sopenharmony_ci#define TEST_TIMEOUT_MS	100
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_cistruct managed_test_priv {
1562306a36Sopenharmony_ci	bool action_done;
1662306a36Sopenharmony_ci	wait_queue_head_t action_wq;
1762306a36Sopenharmony_ci};
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_cistatic void drm_action(struct drm_device *drm, void *ptr)
2062306a36Sopenharmony_ci{
2162306a36Sopenharmony_ci	struct managed_test_priv *priv = ptr;
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_ci	priv->action_done = true;
2462306a36Sopenharmony_ci	wake_up_interruptible(&priv->action_wq);
2562306a36Sopenharmony_ci}
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_cistatic void drm_test_managed_run_action(struct kunit *test)
2862306a36Sopenharmony_ci{
2962306a36Sopenharmony_ci	struct managed_test_priv *priv;
3062306a36Sopenharmony_ci	struct drm_device *drm;
3162306a36Sopenharmony_ci	struct device *dev;
3262306a36Sopenharmony_ci	int ret;
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_ci	priv = kunit_kzalloc(test, sizeof(*priv), GFP_KERNEL);
3562306a36Sopenharmony_ci	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv);
3662306a36Sopenharmony_ci	init_waitqueue_head(&priv->action_wq);
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_ci	dev = drm_kunit_helper_alloc_device(test);
3962306a36Sopenharmony_ci	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_ci	drm = __drm_kunit_helper_alloc_drm_device(test, dev, sizeof(*drm), 0, DRIVER_MODESET);
4262306a36Sopenharmony_ci	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, drm);
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_ci	ret = drmm_add_action_or_reset(drm, drm_action, priv);
4562306a36Sopenharmony_ci	KUNIT_EXPECT_EQ(test, ret, 0);
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_ci	ret = drm_dev_register(drm, 0);
4862306a36Sopenharmony_ci	KUNIT_ASSERT_EQ(test, ret, 0);
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_ci	drm_dev_unregister(drm);
5162306a36Sopenharmony_ci	drm_kunit_helper_free_device(test, dev);
5262306a36Sopenharmony_ci
5362306a36Sopenharmony_ci	ret = wait_event_interruptible_timeout(priv->action_wq, priv->action_done,
5462306a36Sopenharmony_ci					       msecs_to_jiffies(TEST_TIMEOUT_MS));
5562306a36Sopenharmony_ci	KUNIT_EXPECT_GT(test, ret, 0);
5662306a36Sopenharmony_ci}
5762306a36Sopenharmony_ci
5862306a36Sopenharmony_cistatic struct kunit_case drm_managed_tests[] = {
5962306a36Sopenharmony_ci	KUNIT_CASE(drm_test_managed_run_action),
6062306a36Sopenharmony_ci	{}
6162306a36Sopenharmony_ci};
6262306a36Sopenharmony_ci
6362306a36Sopenharmony_cistatic struct kunit_suite drm_managed_test_suite = {
6462306a36Sopenharmony_ci	.name = "drm-test-managed",
6562306a36Sopenharmony_ci	.test_cases = drm_managed_tests
6662306a36Sopenharmony_ci};
6762306a36Sopenharmony_ci
6862306a36Sopenharmony_cikunit_test_suite(drm_managed_test_suite);
6962306a36Sopenharmony_ci
7062306a36Sopenharmony_ciMODULE_AUTHOR("Maxime Ripard <maxime@cerno.tech>");
7162306a36Sopenharmony_ciMODULE_LICENSE("GPL");
72