Loading...
Note: File does not exist in v3.1.
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
16static 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 */
34struct device *drm_kunit_helper_alloc_device(struct kunit *test)
35{
36 return kunit_device_register(test, KUNIT_DEVICE_NAME);
37}
38EXPORT_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 */
47void drm_kunit_helper_free_device(struct kunit *test, struct device *dev)
48{
49 kunit_device_unregister(test, dev);
50}
51EXPORT_SYMBOL_GPL(drm_kunit_helper_free_device);
52
53struct 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}
76EXPORT_SYMBOL_GPL(__drm_kunit_helper_alloc_drm_device_with_driver);
77
78static 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 */
98struct drm_modeset_acquire_ctx *
99drm_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}
117EXPORT_SYMBOL_GPL(drm_kunit_helper_acquire_ctx_alloc);
118
119static 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 */
140struct drm_atomic_state *
141drm_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}
162EXPORT_SYMBOL_GPL(drm_kunit_helper_atomic_state_alloc);
163
164MODULE_AUTHOR("Maxime Ripard <maxime@cerno.tech>");
165MODULE_LICENSE("GPL");