# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
 
 exynosdrm-y := exynos_drm_drv.o exynos_drm_crtc.o exynos_drm_fb.o \
-               exynos_drm_gem.o exynos_drm_plane.o
+               exynos_drm_gem.o exynos_drm_plane.o exynos_drm_dma.o
 
 exynosdrm-$(CONFIG_DRM_FBDEV_EMULATION) += exynos_drm_fbdev.o
 exynosdrm-$(CONFIG_EXYNOS_IOMMU) += exynos_drm_iommu.o
 
 #include "exynos_drm_crtc.h"
 #include "exynos_drm_fb.h"
 #include "exynos_drm_plane.h"
-#include "exynos_drm_iommu.h"
 #include "regs-decon5433.h"
 
 #define DSD_CFG_MUX 0x1004
        decon_disable(ctx->crtc);
 
        /* detach this sub driver from iommu mapping if supported. */
-       drm_iommu_detach_device(ctx->drm_dev, ctx->dev);
+       exynos_drm_unregister_dma(ctx->drm_dev, ctx->dev);
 }
 
 static const struct component_ops decon_component_ops = {
 
 #include "exynos_drm_plane.h"
 #include "exynos_drm_drv.h"
 #include "exynos_drm_fb.h"
-#include "exynos_drm_iommu.h"
 #include "regs-decon7.h"
 
 /*
 static void decon_ctx_remove(struct decon_context *ctx)
 {
        /* detach this sub driver from iommu mapping if supported. */
-       drm_iommu_detach_device(ctx->drm_dev, ctx->dev);
+       exynos_drm_unregister_dma(ctx->drm_dev, ctx->dev);
 }
 
 static u32 decon_calc_clkdiv(struct decon_context *ctx,
 
--- /dev/null
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright (c) 2012 Samsung Electronics Co., Ltd.
+// Author: Andrzej Hajda <a.hajda@samsung.com>
+
+#include "exynos_drm_drv.h"
+#include "exynos_drm_iommu.h"
+
+int exynos_drm_register_dma(struct drm_device *drm, struct device *dev)
+{
+       struct exynos_drm_private *priv = drm->dev_private;
+       int ret;
+
+       if (!priv->dma_dev) {
+               priv->dma_dev = dev;
+               DRM_INFO("Exynos DRM: using %s device for DMA mapping operations\n",
+                        dev_name(dev));
+               /* create common IOMMU mapping for all Exynos DRM devices */
+               ret = drm_create_iommu_mapping(drm);
+               if (ret < 0) {
+                       priv->dma_dev = NULL;
+                       DRM_ERROR("failed to create iommu mapping.\n");
+                       return -EINVAL;
+               }
+       }
+
+       return drm_iommu_attach_device(drm, dev);
+}
+
+void exynos_drm_unregister_dma(struct drm_device *drm, struct device *dev)
+{
+       if (IS_ENABLED(CONFIG_EXYNOS_IOMMU))
+               drm_iommu_detach_device(drm, dev);
+}
+
+void exynos_drm_cleanup_dma(struct drm_device *drm)
+{
+       if (IS_ENABLED(CONFIG_EXYNOS_IOMMU))
+               drm_release_iommu_mapping(drm);
+}
 
 #include "exynos_drm_ipp.h"
 #include "exynos_drm_vidi.h"
 #include "exynos_drm_g2d.h"
-#include "exynos_drm_iommu.h"
 
 #define DRIVER_NAME    "exynos"
 #define DRIVER_DESC    "Samsung SoC DRM"
 #define DRIVER_MAJOR   1
 #define DRIVER_MINOR   1
 
-int exynos_drm_register_dma(struct drm_device *drm, struct device *dev)
-{
-       struct exynos_drm_private *priv = drm->dev_private;
-       int ret;
-
-       if (!priv->dma_dev) {
-               priv->dma_dev = dev;
-               DRM_INFO("Exynos DRM: using %s device for DMA mapping operations\n",
-                        dev_name(dev));
-               /* create common IOMMU mapping for all Exynos DRM devices */
-               ret = drm_create_iommu_mapping(drm);
-               if (ret < 0) {
-                       priv->dma_dev = NULL;
-                       DRM_ERROR("failed to create iommu mapping.\n");
-                       return -EINVAL;
-               }
-       }
-
-       return drm_iommu_attach_device(drm, dev);
-}
-
 static int exynos_drm_open(struct drm_device *dev, struct drm_file *file)
 {
        struct drm_exynos_file_private *file_priv;
        component_unbind_all(drm->dev, drm);
 err_mode_config_cleanup:
        drm_mode_config_cleanup(drm);
-       drm_release_iommu_mapping(drm);
+       exynos_drm_cleanup_dma(drm);
        kfree(private);
 err_free_drm:
        drm_dev_put(drm);
 
        component_unbind_all(drm->dev, drm);
        drm_mode_config_cleanup(drm);
-       drm_release_iommu_mapping(drm);
+       exynos_drm_cleanup_dma(drm);
 
        kfree(drm->dev_private);
        drm->dev_private = NULL;
 
        return priv->dma_dev;
 }
 
+static inline bool is_drm_iommu_supported(struct drm_device *drm_dev)
+{
+       struct exynos_drm_private *priv = drm_dev->dev_private;
+
+       return priv->mapping ? true : false;
+}
+
 int exynos_drm_register_dma(struct drm_device *drm, struct device *dev);
+void exynos_drm_unregister_dma(struct drm_device *drm, struct device *dev);
+void exynos_drm_cleanup_dma(struct drm_device *drm);
 
 #ifdef CONFIG_DRM_EXYNOS_DPI
 struct drm_encoder *exynos_dpi_probe(struct device *dev);
 
 #include "exynos_drm_drv.h"
 #include "exynos_drm_fb.h"
 #include "exynos_drm_fbdev.h"
-#include "exynos_drm_iommu.h"
 #include "exynos_drm_crtc.h"
 
 static int check_fb_gem_memory_type(struct drm_device *drm_dev,
 
 #include "exynos_drm_drv.h"
 #include "exynos_drm_fb.h"
 #include "exynos_drm_fbdev.h"
-#include "exynos_drm_iommu.h"
 
 #define MAX_CONNECTOR          4
 #define PREFERRED_BPP          32
 
 #include <drm/exynos_drm.h>
 #include "regs-fimc.h"
 #include "exynos_drm_drv.h"
-#include "exynos_drm_iommu.h"
 #include "exynos_drm_ipp.h"
 
 /*
        struct exynos_drm_ipp *ipp = &ctx->ipp;
 
        exynos_drm_ipp_unregister(drm_dev, ipp);
-       drm_iommu_detach_device(drm_dev, dev);
+       exynos_drm_unregister_dma(drm_dev, dev);
 }
 
 static const struct component_ops fimc_component_ops = {
 
 #include "exynos_drm_fb.h"
 #include "exynos_drm_crtc.h"
 #include "exynos_drm_plane.h"
-#include "exynos_drm_iommu.h"
 
 /*
  * FIMD stands for Fully Interactive Mobile Display and
 
        fimd_disable(ctx->crtc);
 
-       drm_iommu_detach_device(ctx->drm_dev, ctx->dev);
+       exynos_drm_unregister_dma(ctx->drm_dev, ctx->dev);
 
        if (ctx->encoder)
                exynos_dpi_remove(ctx->encoder);
 
 #include "exynos_drm_drv.h"
 #include "exynos_drm_g2d.h"
 #include "exynos_drm_gem.h"
-#include "exynos_drm_iommu.h"
 
 #define G2D_HW_MAJOR_VER               4
 #define G2D_HW_MINOR_VER               1
        priv->g2d_dev = NULL;
 
        cancel_work_sync(&g2d->runqueue_work);
-       drm_iommu_detach_device(g2d->drm_dev, dev);
+       exynos_drm_unregister_dma(g2d->drm_dev, dev);
 }
 
 static const struct component_ops g2d_component_ops = {
 
 
 #include "exynos_drm_drv.h"
 #include "exynos_drm_gem.h"
-#include "exynos_drm_iommu.h"
 
 static int exynos_drm_alloc_buf(struct exynos_drm_gem *exynos_gem)
 {
 
 #include <drm/exynos_drm.h>
 #include "regs-gsc.h"
 #include "exynos_drm_drv.h"
-#include "exynos_drm_iommu.h"
 #include "exynos_drm_ipp.h"
 
 /*
        struct exynos_drm_ipp *ipp = &ctx->ipp;
 
        exynos_drm_ipp_unregister(drm_dev, ipp);
-       drm_iommu_detach_device(drm_dev, dev);
+       exynos_drm_unregister_dma(drm_dev, dev);
 }
 
 static const struct component_ops gsc_component_ops = {
 
 void drm_iommu_detach_device(struct drm_device *dev_dev,
                                struct device *subdrv_dev);
 
-static inline bool is_drm_iommu_supported(struct drm_device *drm_dev)
-{
-       struct exynos_drm_private *priv = drm_dev->dev_private;
-
-       return priv->mapping ? true : false;
-}
-
 #else
 
 static inline int drm_create_iommu_mapping(struct drm_device *drm_dev)
 {
 }
 
-static inline bool is_drm_iommu_supported(struct drm_device *drm_dev)
-{
-       return false;
-}
-
 #endif
 #endif
 
 #include <drm/exynos_drm.h>
 #include "regs-rotator.h"
 #include "exynos_drm_drv.h"
-#include "exynos_drm_iommu.h"
 #include "exynos_drm_ipp.h"
 
 /*
        struct exynos_drm_ipp *ipp = &rot->ipp;
 
        exynos_drm_ipp_unregister(drm_dev, ipp);
-       drm_iommu_detach_device(rot->drm_dev, rot->dev);
+       exynos_drm_unregister_dma(rot->drm_dev, rot->dev);
 }
 
 static const struct component_ops rotator_component_ops = {
 
 #include "regs-scaler.h"
 #include "exynos_drm_fb.h"
 #include "exynos_drm_drv.h"
-#include "exynos_drm_iommu.h"
 #include "exynos_drm_ipp.h"
 
 #define scaler_read(offset)            readl(scaler->regs + (offset))
        struct exynos_drm_ipp *ipp = &scaler->ipp;
 
        exynos_drm_ipp_unregister(drm_dev, ipp);
-       drm_iommu_detach_device(scaler->drm_dev, scaler->dev);
+       exynos_drm_unregister_dma(scaler->drm_dev, scaler->dev);
 }
 
 static const struct component_ops scaler_component_ops = {
 
 #include "exynos_drm_crtc.h"
 #include "exynos_drm_fb.h"
 #include "exynos_drm_plane.h"
-#include "exynos_drm_iommu.h"
 
 #define MIXER_WIN_NR           3
 #define VP_DEFAULT_WIN         2
 
 static void mixer_ctx_remove(struct mixer_context *mixer_ctx)
 {
-       drm_iommu_detach_device(mixer_ctx->drm_dev, mixer_ctx->dev);
+       exynos_drm_unregister_dma(mixer_ctx->drm_dev, mixer_ctx->dev);
 }
 
 static int mixer_enable_vblank(struct exynos_drm_crtc *crtc)