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