]> Git Repo - linux.git/blob - drivers/gpu/drm/tests/drm_kunit_helpers.c
Merge tag 'for-linus-6.8-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux.git] / drivers / gpu / drm / tests / drm_kunit_helpers.c
1 // SPDX-License-Identifier: GPL-2.0
2
3 #include <drm/drm_atomic.h>
4 #include <drm/drm_drv.h>
5 #include <drm/drm_kunit_helpers.h>
6 #include <drm/drm_managed.h>
7
8 #include <kunit/device.h>
9 #include <kunit/resource.h>
10
11 #include <linux/device.h>
12 #include <linux/platform_device.h>
13
14 #define KUNIT_DEVICE_NAME       "drm-kunit-mock-device"
15
16 static const struct drm_mode_config_funcs drm_mode_config_funcs = {
17 };
18
19 /**
20  * drm_kunit_helper_alloc_device - Allocate a mock device for a KUnit test
21  * @test: The test context object
22  *
23  * This allocates a fake struct &device to create a mock for a KUnit
24  * test. The device will also be bound to a fake driver. It will thus be
25  * able to leverage the usual infrastructure and most notably the
26  * device-managed resources just like a "real" device.
27  *
28  * Resources will be cleaned up automatically, but the removal can be
29  * forced using @drm_kunit_helper_free_device.
30  *
31  * Returns:
32  * A pointer to the new device, or an ERR_PTR() otherwise.
33  */
34 struct device *drm_kunit_helper_alloc_device(struct kunit *test)
35 {
36         return kunit_device_register(test, KUNIT_DEVICE_NAME);
37 }
38 EXPORT_SYMBOL_GPL(drm_kunit_helper_alloc_device);
39
40 /**
41  * drm_kunit_helper_free_device - Frees a mock device
42  * @test: The test context object
43  * @dev: The device to free
44  *
45  * Frees a device allocated with drm_kunit_helper_alloc_device().
46  */
47 void drm_kunit_helper_free_device(struct kunit *test, struct device *dev)
48 {
49         kunit_device_unregister(test, dev);
50 }
51 EXPORT_SYMBOL_GPL(drm_kunit_helper_free_device);
52
53 struct drm_device *
54 __drm_kunit_helper_alloc_drm_device_with_driver(struct kunit *test,
55                                                 struct device *dev,
56                                                 size_t size, size_t offset,
57                                                 const struct drm_driver *driver)
58 {
59         struct drm_device *drm;
60         void *container;
61         int ret;
62
63         container = __devm_drm_dev_alloc(dev, driver, size, offset);
64         if (IS_ERR(container))
65                 return ERR_CAST(container);
66
67         drm = container + offset;
68         drm->mode_config.funcs = &drm_mode_config_funcs;
69
70         ret = drmm_mode_config_init(drm);
71         if (ret)
72                 return ERR_PTR(ret);
73
74         return drm;
75 }
76 EXPORT_SYMBOL_GPL(__drm_kunit_helper_alloc_drm_device_with_driver);
77
78 static void action_drm_release_context(void *ptr)
79 {
80         struct drm_modeset_acquire_ctx *ctx = ptr;
81
82         drm_modeset_drop_locks(ctx);
83         drm_modeset_acquire_fini(ctx);
84 }
85
86 /**
87  * drm_kunit_helper_acquire_ctx_alloc - Allocates an acquire context
88  * @test: The test context object
89  *
90  * Allocates and initializes a modeset acquire context.
91  *
92  * The context is tied to the kunit test context, so we must not call
93  * drm_modeset_acquire_fini() on it, it will be done so automatically.
94  *
95  * Returns:
96  * An ERR_PTR on error, a pointer to the newly allocated context otherwise
97  */
98 struct drm_modeset_acquire_ctx *
99 drm_kunit_helper_acquire_ctx_alloc(struct kunit *test)
100 {
101         struct drm_modeset_acquire_ctx *ctx;
102         int ret;
103
104         ctx = kunit_kzalloc(test, sizeof(*ctx), GFP_KERNEL);
105         KUNIT_ASSERT_NOT_NULL(test, ctx);
106
107         drm_modeset_acquire_init(ctx, 0);
108
109         ret = kunit_add_action_or_reset(test,
110                                         action_drm_release_context,
111                                         ctx);
112         if (ret)
113                 return ERR_PTR(ret);
114
115         return ctx;
116 }
117 EXPORT_SYMBOL_GPL(drm_kunit_helper_acquire_ctx_alloc);
118
119 static void kunit_action_drm_atomic_state_put(void *ptr)
120 {
121         struct drm_atomic_state *state = ptr;
122
123         drm_atomic_state_put(state);
124 }
125
126 /**
127  * drm_kunit_helper_atomic_state_alloc - Allocates an atomic state
128  * @test: The test context object
129  * @drm: The device to alloc the state for
130  * @ctx: Locking context for that atomic update
131  *
132  * Allocates a empty atomic state.
133  *
134  * The state is tied to the kunit test context, so we must not call
135  * drm_atomic_state_put() on it, it will be done so automatically.
136  *
137  * Returns:
138  * An ERR_PTR on error, a pointer to the newly allocated state otherwise
139  */
140 struct drm_atomic_state *
141 drm_kunit_helper_atomic_state_alloc(struct kunit *test,
142                                     struct drm_device *drm,
143                                     struct drm_modeset_acquire_ctx *ctx)
144 {
145         struct drm_atomic_state *state;
146         int ret;
147
148         state = drm_atomic_state_alloc(drm);
149         if (!state)
150                 return ERR_PTR(-ENOMEM);
151
152         ret = kunit_add_action_or_reset(test,
153                                         kunit_action_drm_atomic_state_put,
154                                         state);
155         if (ret)
156                 return ERR_PTR(ret);
157
158         state->acquire_ctx = ctx;
159
160         return state;
161 }
162 EXPORT_SYMBOL_GPL(drm_kunit_helper_atomic_state_alloc);
163
164 MODULE_AUTHOR("Maxime Ripard <[email protected]>");
165 MODULE_LICENSE("GPL");
This page took 0.061415 seconds and 4 git commands to generate.