1 // SPDX-License-Identifier: GPL-2.0 AND MIT
2 /*
3 * Copyright © 2023 Intel Corporation
4 */
5
6 #include <kunit/test.h>
7 #include <kunit/static_stub.h>
8 #include <kunit/visibility.h>
9
10 #include <drm/drm_drv.h>
11 #include <drm/drm_kunit_helpers.h>
12
13 #include "tests/xe_kunit_helpers.h"
14 #include "tests/xe_pci_test.h"
15 #include "xe_device.h"
16 #include "xe_device_types.h"
17 #include "xe_pm.h"
18
19 /**
20 * xe_kunit_helper_alloc_xe_device - Allocate a &xe_device for a KUnit test.
21 * @test: the &kunit where this &xe_device will be used
22 * @dev: The parent device object
23 *
24 * This function allocates xe_device using drm_kunit_helper_alloc_device().
25 * The xe_device allocation is managed by the test.
26 *
27 * @dev should be allocated using drm_kunit_helper_alloc_device().
28 *
29 * This function uses KUNIT_ASSERT to detect any allocation failures.
30 *
31 * Return: A pointer to the new &xe_device.
32 */
xe_kunit_helper_alloc_xe_device(struct kunit * test,struct device * dev)33 struct xe_device *xe_kunit_helper_alloc_xe_device(struct kunit *test,
34 struct device *dev)
35 {
36 struct xe_device *xe;
37
38 xe = drm_kunit_helper_alloc_drm_device(test, dev,
39 struct xe_device,
40 drm, DRIVER_GEM);
41 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xe);
42 return xe;
43 }
44 EXPORT_SYMBOL_IF_KUNIT(xe_kunit_helper_alloc_xe_device);
45
kunit_action_restore_priv(void * priv)46 static void kunit_action_restore_priv(void *priv)
47 {
48 struct kunit *test = kunit_get_current_test();
49
50 test->priv = priv;
51 }
52
53 /**
54 * xe_kunit_helper_xe_device_test_init - Prepare a &xe_device for a KUnit test.
55 * @test: the &kunit where this fake &xe_device will be used
56 *
57 * This function allocates and initializes a fake &xe_device and stores its
58 * pointer as &kunit.priv to allow the test code to access it.
59 *
60 * This function can be directly used as custom implementation of
61 * &kunit_suite.init.
62 *
63 * It is possible to prepare specific variant of the fake &xe_device by passing
64 * in &kunit.priv pointer to the struct xe_pci_fake_data supplemented with
65 * desired parameters prior to calling this function.
66 *
67 * This function uses KUNIT_ASSERT to detect any failures.
68 *
69 * Return: Always 0.
70 */
xe_kunit_helper_xe_device_test_init(struct kunit * test)71 int xe_kunit_helper_xe_device_test_init(struct kunit *test)
72 {
73 struct xe_device *xe;
74 struct device *dev;
75 int err;
76
77 dev = drm_kunit_helper_alloc_device(test);
78 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
79
80 xe = xe_kunit_helper_alloc_xe_device(test, dev);
81 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xe);
82
83 err = xe_pci_fake_device_init(xe);
84 KUNIT_ASSERT_EQ(test, err, 0);
85
86 err = kunit_add_action_or_reset(test, kunit_action_restore_priv, test->priv);
87 KUNIT_ASSERT_EQ(test, err, 0);
88
89 test->priv = xe;
90 return 0;
91 }
92 EXPORT_SYMBOL_IF_KUNIT(xe_kunit_helper_xe_device_test_init);
93
94 KUNIT_DEFINE_ACTION_WRAPPER(put_xe_pm_runtime, xe_pm_runtime_put, struct xe_device *);
95
96 /**
97 * xe_kunit_helper_xe_device_live_test_init - Prepare a &xe_device for
98 * use in a live KUnit test.
99 * @test: the &kunit where live &xe_device will be used
100 *
101 * This function expects pointer to the &xe_device in the &test.param_value,
102 * like it is prepared by the &xe_pci_live_device_gen_param and stores that
103 * pointer as &kunit.priv to allow the test code to access it.
104 *
105 * This function makes sure that device is not wedged and then resumes it
106 * to avoid waking up the device inside the test. It uses deferred cleanup
107 * action to release a runtime_pm reference.
108 *
109 * This function can be used as custom implementation of &kunit_suite.init.
110 *
111 * This function uses KUNIT_ASSERT to detect any failures.
112 *
113 * Return: Always 0.
114 */
xe_kunit_helper_xe_device_live_test_init(struct kunit * test)115 int xe_kunit_helper_xe_device_live_test_init(struct kunit *test)
116 {
117 struct xe_device *xe = xe_device_const_cast(test->param_value);
118
119 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xe);
120 kunit_info(test, "running on %s device\n", xe->info.platform_name);
121
122 KUNIT_ASSERT_FALSE(test, xe_device_wedged(xe));
123 xe_pm_runtime_get(xe);
124 KUNIT_ASSERT_EQ(test, 0, kunit_add_action_or_reset(test, put_xe_pm_runtime, xe));
125
126 test->priv = xe;
127 return 0;
128 }
129 EXPORT_SYMBOL_IF_KUNIT(xe_kunit_helper_xe_device_live_test_init);
130