LCOV - code coverage report
Current view: top level - drivers/gpu/drm/tests - drm_kunit_helpers.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 35 66 53.0 %
Date: 2023-08-24 13:40:31 Functions: 6 11 54.5 %

          Line data    Source code
       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/resource.h>
       9             : 
      10             : #include <linux/device.h>
      11             : #include <linux/platform_device.h>
      12             : 
      13             : #define KUNIT_DEVICE_NAME       "drm-kunit-mock-device"
      14             : 
      15             : static const struct drm_mode_config_funcs drm_mode_config_funcs = {
      16             : };
      17             : 
      18           5 : static int fake_probe(struct platform_device *pdev)
      19             : {
      20           5 :         return 0;
      21             : }
      22             : 
      23             : static struct platform_driver fake_platform_driver = {
      24             :         .probe  = fake_probe,
      25             :         .driver = {
      26             :                 .name   = KUNIT_DEVICE_NAME,
      27             :         },
      28             : };
      29             : 
      30           5 : static void kunit_action_platform_driver_unregister(void *ptr)
      31             : {
      32           5 :         struct platform_driver *drv = ptr;
      33             : 
      34           5 :         platform_driver_unregister(drv);
      35             : 
      36           5 : }
      37             : 
      38           5 : static void kunit_action_platform_device_put(void *ptr)
      39             : {
      40           5 :         struct platform_device *pdev = ptr;
      41             : 
      42           5 :         platform_device_put(pdev);
      43           5 : }
      44             : 
      45           5 : static void kunit_action_platform_device_del(void *ptr)
      46             : {
      47           5 :         struct platform_device *pdev = ptr;
      48             : 
      49           5 :         platform_device_del(pdev);
      50           5 : }
      51             : 
      52             : /**
      53             :  * drm_kunit_helper_alloc_device - Allocate a mock device for a KUnit test
      54             :  * @test: The test context object
      55             :  *
      56             :  * This allocates a fake struct &device to create a mock for a KUnit
      57             :  * test. The device will also be bound to a fake driver. It will thus be
      58             :  * able to leverage the usual infrastructure and most notably the
      59             :  * device-managed resources just like a "real" device.
      60             :  *
      61             :  * Resources will be cleaned up automatically, but the removal can be
      62             :  * forced using @drm_kunit_helper_free_device.
      63             :  *
      64             :  * Returns:
      65             :  * A pointer to the new device, or an ERR_PTR() otherwise.
      66             :  */
      67           5 : struct device *drm_kunit_helper_alloc_device(struct kunit *test)
      68             : {
      69             :         struct platform_device *pdev;
      70             :         int ret;
      71             : 
      72           5 :         ret = platform_driver_register(&fake_platform_driver);
      73           5 :         KUNIT_ASSERT_EQ(test, ret, 0);
      74             : 
      75           5 :         ret = kunit_add_action_or_reset(test,
      76             :                                         kunit_action_platform_driver_unregister,
      77             :                                         &fake_platform_driver);
      78           5 :         KUNIT_ASSERT_EQ(test, ret, 0);
      79             : 
      80           5 :         pdev = platform_device_alloc(KUNIT_DEVICE_NAME, PLATFORM_DEVID_NONE);
      81          10 :         KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev);
      82             : 
      83           5 :         ret = kunit_add_action_or_reset(test,
      84             :                                         kunit_action_platform_device_put,
      85             :                                         pdev);
      86           5 :         KUNIT_ASSERT_EQ(test, ret, 0);
      87             : 
      88           5 :         ret = platform_device_add(pdev);
      89           5 :         KUNIT_ASSERT_EQ(test, ret, 0);
      90             : 
      91           5 :         ret = kunit_add_action_or_reset(test,
      92             :                                         kunit_action_platform_device_del,
      93             :                                         pdev);
      94           5 :         KUNIT_ASSERT_EQ(test, ret, 0);
      95             : 
      96           5 :         return &pdev->dev;
      97             : }
      98             : EXPORT_SYMBOL_GPL(drm_kunit_helper_alloc_device);
      99             : 
     100             : /**
     101             :  * drm_kunit_helper_free_device - Frees a mock device
     102             :  * @test: The test context object
     103             :  * @dev: The device to free
     104             :  *
     105             :  * Frees a device allocated with drm_kunit_helper_alloc_device().
     106             :  */
     107           0 : void drm_kunit_helper_free_device(struct kunit *test, struct device *dev)
     108             : {
     109           0 :         struct platform_device *pdev = to_platform_device(dev);
     110             : 
     111           0 :         kunit_release_action(test,
     112             :                              kunit_action_platform_device_del,
     113             :                              pdev);
     114             : 
     115           0 :         kunit_release_action(test,
     116             :                              kunit_action_platform_device_put,
     117             :                              pdev);
     118             : 
     119           0 :         kunit_release_action(test,
     120             :                              kunit_action_platform_driver_unregister,
     121             :                              pdev);
     122           0 : }
     123             : EXPORT_SYMBOL_GPL(drm_kunit_helper_free_device);
     124             : 
     125             : struct drm_device *
     126           5 : __drm_kunit_helper_alloc_drm_device_with_driver(struct kunit *test,
     127             :                                                 struct device *dev,
     128             :                                                 size_t size, size_t offset,
     129             :                                                 const struct drm_driver *driver)
     130             : {
     131             :         struct drm_device *drm;
     132             :         void *container;
     133             :         int ret;
     134             : 
     135           5 :         container = __devm_drm_dev_alloc(dev, driver, size, offset);
     136           5 :         if (IS_ERR(container))
     137             :                 return ERR_CAST(container);
     138             : 
     139           5 :         drm = container + offset;
     140           5 :         drm->mode_config.funcs = &drm_mode_config_funcs;
     141             : 
     142           5 :         ret = drmm_mode_config_init(drm);
     143           5 :         if (ret)
     144           0 :                 return ERR_PTR(ret);
     145             : 
     146             :         return drm;
     147             : }
     148             : EXPORT_SYMBOL_GPL(__drm_kunit_helper_alloc_drm_device_with_driver);
     149             : 
     150           0 : static void action_drm_release_context(void *ptr)
     151             : {
     152           0 :         struct drm_modeset_acquire_ctx *ctx = ptr;
     153             : 
     154           0 :         drm_modeset_drop_locks(ctx);
     155           0 :         drm_modeset_acquire_fini(ctx);
     156           0 : }
     157             : 
     158             : /**
     159             :  * drm_kunit_helper_context_alloc - Allocates an acquire context
     160             :  * @test: The test context object
     161             :  *
     162             :  * Allocates and initializes a modeset acquire context.
     163             :  *
     164             :  * The context is tied to the kunit test context, so we must not call
     165             :  * drm_modeset_acquire_fini() on it, it will be done so automatically.
     166             :  *
     167             :  * Returns:
     168             :  * An ERR_PTR on error, a pointer to the newly allocated context otherwise
     169             :  */
     170             : struct drm_modeset_acquire_ctx *
     171           0 : drm_kunit_helper_acquire_ctx_alloc(struct kunit *test)
     172             : {
     173             :         struct drm_modeset_acquire_ctx *ctx;
     174             :         int ret;
     175             : 
     176           0 :         ctx = kunit_kzalloc(test, sizeof(*ctx), GFP_KERNEL);
     177           0 :         KUNIT_ASSERT_NOT_NULL(test, ctx);
     178             : 
     179           0 :         drm_modeset_acquire_init(ctx, 0);
     180             : 
     181           0 :         ret = kunit_add_action_or_reset(test,
     182             :                                         action_drm_release_context,
     183             :                                         ctx);
     184           0 :         if (ret)
     185           0 :                 return ERR_PTR(ret);
     186             : 
     187             :         return ctx;
     188             : }
     189             : EXPORT_SYMBOL_GPL(drm_kunit_helper_acquire_ctx_alloc);
     190             : 
     191           0 : static void kunit_action_drm_atomic_state_put(void *ptr)
     192             : {
     193           0 :         struct drm_atomic_state *state = ptr;
     194             : 
     195           0 :         drm_atomic_state_put(state);
     196           0 : }
     197             : 
     198             : /**
     199             :  * drm_kunit_helper_atomic_state_alloc - Allocates an atomic state
     200             :  * @test: The test context object
     201             :  * @drm: The device to alloc the state for
     202             :  * @ctx: Locking context for that atomic update
     203             :  *
     204             :  * Allocates a empty atomic state.
     205             :  *
     206             :  * The state is tied to the kunit test context, so we must not call
     207             :  * drm_atomic_state_put() on it, it will be done so automatically.
     208             :  *
     209             :  * Returns:
     210             :  * An ERR_PTR on error, a pointer to the newly allocated state otherwise
     211             :  */
     212             : struct drm_atomic_state *
     213           0 : drm_kunit_helper_atomic_state_alloc(struct kunit *test,
     214             :                                     struct drm_device *drm,
     215             :                                     struct drm_modeset_acquire_ctx *ctx)
     216             : {
     217             :         struct drm_atomic_state *state;
     218             :         int ret;
     219             : 
     220           0 :         state = drm_atomic_state_alloc(drm);
     221           0 :         if (!state)
     222             :                 return ERR_PTR(-ENOMEM);
     223             : 
     224           0 :         ret = kunit_add_action_or_reset(test,
     225             :                                         kunit_action_drm_atomic_state_put,
     226             :                                         state);
     227           0 :         if (ret)
     228           0 :                 return ERR_PTR(ret);
     229             : 
     230           0 :         state->acquire_ctx = ctx;
     231             : 
     232           0 :         return state;
     233             : }
     234             : EXPORT_SYMBOL_GPL(drm_kunit_helper_atomic_state_alloc);
     235             : 
     236             : MODULE_AUTHOR("Maxime Ripard <maxime@cerno.tech>");
     237             : MODULE_LICENSE("GPL");

Generated by: LCOV version 1.14