1 // SPDX-License-Identifier: GPL-2.0 2 3 #include <drm/drm_drv.h> 4 #include <drm/drm_kunit_helpers.h> 5 #include <drm/drm_managed.h> 6 7 #include <kunit/resource.h> 8 9 #include <linux/device.h> 10 #include <linux/platform_device.h> 11 12 #define KUNIT_DEVICE_NAME "drm-kunit-mock-device" 13 14 static const struct drm_mode_config_funcs drm_mode_config_funcs = { 15 }; 16 17 static int fake_probe(struct platform_device *pdev) 18 { 19 return 0; 20 } 21 22 static struct platform_driver fake_platform_driver = { 23 .probe = fake_probe, 24 .driver = { 25 .name = KUNIT_DEVICE_NAME, 26 }, 27 }; 28 29 /** 30 * drm_kunit_helper_alloc_device - Allocate a mock device for a KUnit test 31 * @test: The test context object 32 * 33 * This allocates a fake struct &device to create a mock for a KUnit 34 * test. The device will also be bound to a fake driver. It will thus be 35 * able to leverage the usual infrastructure and most notably the 36 * device-managed resources just like a "real" device. 37 * 38 * Callers need to make sure drm_kunit_helper_free_device() on the 39 * device when done. 40 * 41 * Returns: 42 * A pointer to the new device, or an ERR_PTR() otherwise. 43 */ 44 struct device *drm_kunit_helper_alloc_device(struct kunit *test) 45 { 46 struct platform_device *pdev; 47 int ret; 48 49 ret = platform_driver_register(&fake_platform_driver); 50 KUNIT_ASSERT_EQ(test, ret, 0); 51 52 pdev = platform_device_alloc(KUNIT_DEVICE_NAME, PLATFORM_DEVID_NONE); 53 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev); 54 55 ret = platform_device_add(pdev); 56 KUNIT_ASSERT_EQ(test, ret, 0); 57 58 return &pdev->dev; 59 } 60 EXPORT_SYMBOL_GPL(drm_kunit_helper_alloc_device); 61 62 /** 63 * drm_kunit_helper_free_device - Frees a mock device 64 * @test: The test context object 65 * @dev: The device to free 66 * 67 * Frees a device allocated with drm_kunit_helper_alloc_device(). 68 */ 69 void drm_kunit_helper_free_device(struct kunit *test, struct device *dev) 70 { 71 struct platform_device *pdev = to_platform_device(dev); 72 73 platform_device_unregister(pdev); 74 platform_driver_unregister(&fake_platform_driver); 75 } 76 EXPORT_SYMBOL_GPL(drm_kunit_helper_free_device); 77 78 struct drm_device * 79 __drm_kunit_helper_alloc_drm_device_with_driver(struct kunit *test, 80 struct device *dev, 81 size_t size, size_t offset, 82 const struct drm_driver *driver) 83 { 84 struct drm_device *drm; 85 void *container; 86 int ret; 87 88 container = __devm_drm_dev_alloc(dev, driver, size, offset); 89 if (IS_ERR(container)) 90 return ERR_CAST(container); 91 92 drm = container + offset; 93 drm->mode_config.funcs = &drm_mode_config_funcs; 94 95 ret = drmm_mode_config_init(drm); 96 if (ret) 97 return ERR_PTR(ret); 98 99 return drm; 100 } 101 EXPORT_SYMBOL_GPL(__drm_kunit_helper_alloc_drm_device_with_driver); 102 103 MODULE_AUTHOR("Maxime Ripard <maxime@cerno.tech>"); 104 MODULE_LICENSE("GPL"); 105