1 // SPDX-License-Identifier: GPL-2.0
3 #include <drm/drm_atomic.h>
4 #include <drm/drm_atomic_helper.h>
5 #include <drm/drm_drv.h>
6 #include <drm/drm_kunit_helpers.h>
7 #include <drm/drm_managed.h>
9 #include <kunit/device.h>
10 #include <kunit/resource.h>
12 #include <linux/device.h>
13 #include <linux/platform_device.h>
15 #define KUNIT_DEVICE_NAME "drm-kunit-mock-device"
17 static const struct drm_mode_config_funcs drm_mode_config_funcs = {
18 .atomic_check = drm_atomic_helper_check,
19 .atomic_commit = drm_atomic_helper_commit,
23 * drm_kunit_helper_alloc_device - Allocate a mock device for a KUnit test
24 * @test: The test context object
26 * This allocates a fake struct &device to create a mock for a KUnit
27 * test. The device will also be bound to a fake driver. It will thus be
28 * able to leverage the usual infrastructure and most notably the
29 * device-managed resources just like a "real" device.
31 * Resources will be cleaned up automatically, but the removal can be
32 * forced using @drm_kunit_helper_free_device.
35 * A pointer to the new device, or an ERR_PTR() otherwise.
37 struct device *drm_kunit_helper_alloc_device(struct kunit *test)
39 return kunit_device_register(test, KUNIT_DEVICE_NAME);
41 EXPORT_SYMBOL_GPL(drm_kunit_helper_alloc_device);
44 * drm_kunit_helper_free_device - Frees a mock device
45 * @test: The test context object
46 * @dev: The device to free
48 * Frees a device allocated with drm_kunit_helper_alloc_device().
50 void drm_kunit_helper_free_device(struct kunit *test, struct device *dev)
52 kunit_device_unregister(test, dev);
54 EXPORT_SYMBOL_GPL(drm_kunit_helper_free_device);
57 __drm_kunit_helper_alloc_drm_device_with_driver(struct kunit *test,
59 size_t size, size_t offset,
60 const struct drm_driver *driver)
62 struct drm_device *drm;
66 container = __devm_drm_dev_alloc(dev, driver, size, offset);
67 if (IS_ERR(container))
68 return ERR_CAST(container);
70 drm = container + offset;
71 drm->mode_config.funcs = &drm_mode_config_funcs;
73 ret = drmm_mode_config_init(drm);
79 EXPORT_SYMBOL_GPL(__drm_kunit_helper_alloc_drm_device_with_driver);
81 static void action_drm_release_context(void *ptr)
83 struct drm_modeset_acquire_ctx *ctx = ptr;
85 drm_modeset_drop_locks(ctx);
86 drm_modeset_acquire_fini(ctx);
90 * drm_kunit_helper_acquire_ctx_alloc - Allocates an acquire context
91 * @test: The test context object
93 * Allocates and initializes a modeset acquire context.
95 * The context is tied to the kunit test context, so we must not call
96 * drm_modeset_acquire_fini() on it, it will be done so automatically.
99 * An ERR_PTR on error, a pointer to the newly allocated context otherwise
101 struct drm_modeset_acquire_ctx *
102 drm_kunit_helper_acquire_ctx_alloc(struct kunit *test)
104 struct drm_modeset_acquire_ctx *ctx;
107 ctx = kunit_kzalloc(test, sizeof(*ctx), GFP_KERNEL);
108 KUNIT_ASSERT_NOT_NULL(test, ctx);
110 drm_modeset_acquire_init(ctx, 0);
112 ret = kunit_add_action_or_reset(test,
113 action_drm_release_context,
120 EXPORT_SYMBOL_GPL(drm_kunit_helper_acquire_ctx_alloc);
122 static void kunit_action_drm_atomic_state_put(void *ptr)
124 struct drm_atomic_state *state = ptr;
126 drm_atomic_state_put(state);
130 * drm_kunit_helper_atomic_state_alloc - Allocates an atomic state
131 * @test: The test context object
132 * @drm: The device to alloc the state for
133 * @ctx: Locking context for that atomic update
135 * Allocates a empty atomic state.
137 * The state is tied to the kunit test context, so we must not call
138 * drm_atomic_state_put() on it, it will be done so automatically.
141 * An ERR_PTR on error, a pointer to the newly allocated state otherwise
143 struct drm_atomic_state *
144 drm_kunit_helper_atomic_state_alloc(struct kunit *test,
145 struct drm_device *drm,
146 struct drm_modeset_acquire_ctx *ctx)
148 struct drm_atomic_state *state;
151 state = drm_atomic_state_alloc(drm);
153 return ERR_PTR(-ENOMEM);
155 ret = kunit_add_action_or_reset(test,
156 kunit_action_drm_atomic_state_put,
161 state->acquire_ctx = ctx;
165 EXPORT_SYMBOL_GPL(drm_kunit_helper_atomic_state_alloc);
167 MODULE_AUTHOR("Maxime Ripard <maxime@cerno.tech>");
168 MODULE_LICENSE("GPL");