Simplify the Exynos prime implementation by using the default behavior provided
by drm_gem_prime_import and drm_gem_prime_export.

Signed-off-by: Aaron Plattner <aplattner at nvidia.com>
---
v2: fix dumb mistakes now that I have a toolchain that can compile-test this

 drivers/gpu/drm/exynos/exynos_drm_dmabuf.c | 156 ++---------------------------
 drivers/gpu/drm/exynos/exynos_drm_dmabuf.h |  13 ++-
 drivers/gpu/drm/exynos/exynos_drm_drv.c    |   2 +
 3 files changed, 20 insertions(+), 151 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c 
b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c
index 539da9f..71b40f4 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c
@@ -28,8 +28,6 @@
 #include "exynos_drm_drv.h"
 #include "exynos_drm_gem.h"

-#include <linux/dma-buf.h>
-
 static struct sg_table *exynos_get_sgt(struct drm_device *drm_dev,
                                        struct exynos_drm_gem_buf *buf)
 {
@@ -56,15 +54,12 @@ out:
        return NULL;
 }

-static struct sg_table *
-               exynos_gem_map_dma_buf(struct dma_buf_attachment *attach,
-                                       enum dma_data_direction dir)
+struct sg_table *exynos_gem_prime_get_pages(struct drm_gem_object *obj)
 {
-       struct exynos_drm_gem_obj *gem_obj = attach->dmabuf->priv;
+       struct exynos_drm_gem_obj *gem_obj = to_exynos_gem_obj(obj);
        struct drm_device *dev = gem_obj->base.dev;
        struct exynos_drm_gem_buf *buf;
        struct sg_table *sgt = NULL;
-       int nents;

        DRM_DEBUG_PRIME("%s\n", __FILE__);

@@ -74,120 +69,20 @@ static struct sg_table *
                return sgt;
        }

-       mutex_lock(&dev->struct_mutex);
-
        sgt = exynos_get_sgt(dev, buf);
        if (!sgt)
-               goto err_unlock;
-
-       nents = dma_map_sg(attach->dev, sgt->sgl, sgt->nents, dir);
-       if (!nents) {
-               DRM_ERROR("failed to map sgl with iommu.\n");
-               sgt = NULL;
-               goto err_unlock;
-       }
+               goto err;

        DRM_DEBUG_PRIME("buffer size = 0x%lx\n", buf->size);

-err_unlock:
-       mutex_unlock(&dev->struct_mutex);
+err:
        return sgt;
 }

-static void exynos_gem_unmap_dma_buf(struct dma_buf_attachment *attach,
-                                               struct sg_table *sgt,
-                                               enum dma_data_direction dir)
-{
-       dma_unmap_sg(attach->dev, sgt->sgl, sgt->nents, dir);
-
-       sg_free_table(sgt);
-       kfree(sgt);
-       sgt = NULL;
-}
-
-static void exynos_dmabuf_release(struct dma_buf *dmabuf)
+struct drm_gem_object *exynos_gem_prime_import_sg(struct drm_device *dev,
+                                                 size_t size,
+                                                 struct sg_table *sgt)
 {
-       struct exynos_drm_gem_obj *exynos_gem_obj = dmabuf->priv;
-
-       DRM_DEBUG_PRIME("%s\n", __FILE__);
-
-       /*
-        * exynos_dmabuf_release() call means that file object's
-        * f_count is 0 and it calls drm_gem_object_handle_unreference()
-        * to drop the references that these values had been increased
-        * at drm_prime_handle_to_fd()
-        */
-       if (exynos_gem_obj->base.export_dma_buf == dmabuf) {
-               exynos_gem_obj->base.export_dma_buf = NULL;
-
-               /*
-                * drop this gem object refcount to release allocated buffer
-                * and resources.
-                */
-               drm_gem_object_unreference_unlocked(&exynos_gem_obj->base);
-       }
-}
-
-static void *exynos_gem_dmabuf_kmap_atomic(struct dma_buf *dma_buf,
-                                               unsigned long page_num)
-{
-       /* TODO */
-
-       return NULL;
-}
-
-static void exynos_gem_dmabuf_kunmap_atomic(struct dma_buf *dma_buf,
-                                               unsigned long page_num,
-                                               void *addr)
-{
-       /* TODO */
-}
-
-static void *exynos_gem_dmabuf_kmap(struct dma_buf *dma_buf,
-                                       unsigned long page_num)
-{
-       /* TODO */
-
-       return NULL;
-}
-
-static void exynos_gem_dmabuf_kunmap(struct dma_buf *dma_buf,
-                                       unsigned long page_num, void *addr)
-{
-       /* TODO */
-}
-
-static int exynos_gem_dmabuf_mmap(struct dma_buf *dma_buf,
-       struct vm_area_struct *vma)
-{
-       return -ENOTTY;
-}
-
-static struct dma_buf_ops exynos_dmabuf_ops = {
-       .map_dma_buf            = exynos_gem_map_dma_buf,
-       .unmap_dma_buf          = exynos_gem_unmap_dma_buf,
-       .kmap                   = exynos_gem_dmabuf_kmap,
-       .kmap_atomic            = exynos_gem_dmabuf_kmap_atomic,
-       .kunmap                 = exynos_gem_dmabuf_kunmap,
-       .kunmap_atomic          = exynos_gem_dmabuf_kunmap_atomic,
-       .mmap                   = exynos_gem_dmabuf_mmap,
-       .release                = exynos_dmabuf_release,
-};
-
-struct dma_buf *exynos_dmabuf_prime_export(struct drm_device *drm_dev,
-                               struct drm_gem_object *obj, int flags)
-{
-       struct exynos_drm_gem_obj *exynos_gem_obj = to_exynos_gem_obj(obj);
-
-       return dma_buf_export(exynos_gem_obj, &exynos_dmabuf_ops,
-                               exynos_gem_obj->base.size, 0600);
-}
-
-struct drm_gem_object *exynos_dmabuf_prime_import(struct drm_device *drm_dev,
-                               struct dma_buf *dma_buf)
-{
-       struct dma_buf_attachment *attach;
-       struct sg_table *sgt;
        struct scatterlist *sgl;
        struct exynos_drm_gem_obj *exynos_gem_obj;
        struct exynos_drm_gem_buf *buffer;
@@ -195,39 +90,13 @@ struct drm_gem_object *exynos_dmabuf_prime_import(struct 
drm_device *drm_dev,

        DRM_DEBUG_PRIME("%s\n", __FILE__);

-       /* is this one of own objects? */
-       if (dma_buf->ops == &exynos_dmabuf_ops) {
-               struct drm_gem_object *obj;
-
-               exynos_gem_obj = dma_buf->priv;
-               obj = &exynos_gem_obj->base;
-
-               /* is it from our device? */
-               if (obj->dev == drm_dev) {
-                       drm_gem_object_reference(obj);
-                       return obj;
-               }
-       }
-
-       attach = dma_buf_attach(dma_buf, drm_dev->dev);
-       if (IS_ERR(attach))
-               return ERR_PTR(-EINVAL);
-
-
-       sgt = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL);
-       if (IS_ERR_OR_NULL(sgt)) {
-               ret = PTR_ERR(sgt);
-               goto err_buf_detach;
-       }
-
        buffer = kzalloc(sizeof(*buffer), GFP_KERNEL);
        if (!buffer) {
                DRM_ERROR("failed to allocate exynos_drm_gem_buf.\n");
-               ret = -ENOMEM;
-               goto err_unmap_attach;
+               return ERR_PTR(-ENOMEM);
        }

-       exynos_gem_obj = exynos_drm_gem_init(drm_dev, dma_buf->size);
+       exynos_gem_obj = exynos_drm_gem_init(dev, size);
        if (!exynos_gem_obj) {
                ret = -ENOMEM;
                goto err_free_buffer;
@@ -235,7 +104,7 @@ struct drm_gem_object *exynos_dmabuf_prime_import(struct 
drm_device *drm_dev,

        sgl = sgt->sgl;

-       buffer->size = dma_buf->size;
+       buffer->size = size;
        buffer->dma_addr = sg_dma_address(sgl);

        if (sgt->nents == 1) {
@@ -253,7 +122,6 @@ struct drm_gem_object *exynos_dmabuf_prime_import(struct 
drm_device *drm_dev,

        exynos_gem_obj->buffer = buffer;
        buffer->sgt = sgt;
-       exynos_gem_obj->base.import_attach = attach;

        DRM_DEBUG_PRIME("dma_addr = 0x%x, size = 0x%lx\n", buffer->dma_addr,
                                                                buffer->size);
@@ -263,10 +131,6 @@ struct drm_gem_object *exynos_dmabuf_prime_import(struct 
drm_device *drm_dev,
 err_free_buffer:
        kfree(buffer);
        buffer = NULL;
-err_unmap_attach:
-       dma_buf_unmap_attachment(attach, sgt, DMA_BIDIRECTIONAL);
-err_buf_detach:
-       dma_buf_detach(dma_buf, attach);
        return ERR_PTR(ret);
 }

diff --git a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.h 
b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.h
index 662a8f9..f198183 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.h
@@ -27,13 +27,16 @@
 #define _EXYNOS_DRM_DMABUF_H_

 #ifdef CONFIG_DRM_EXYNOS_DMABUF
-struct dma_buf *exynos_dmabuf_prime_export(struct drm_device *drm_dev,
-                               struct drm_gem_object *obj, int flags);
-
-struct drm_gem_object *exynos_dmabuf_prime_import(struct drm_device *drm_dev,
-                                               struct dma_buf *dma_buf);
+#define exynos_dmabuf_prime_export             drm_gem_prime_export
+#define exynos_dmabuf_prime_import             drm_gem_prime_import
+struct sg_table *exynos_gem_prime_get_pages(struct drm_gem_object *obj);
+struct drm_gem_object *exynos_gem_prime_import_sg(struct drm_device *dev,
+                                                 size_t size,
+                                                 struct sg_table *sg);
 #else
 #define exynos_dmabuf_prime_export             NULL
 #define exynos_dmabuf_prime_import             NULL
+#define exynos_gem_prime_get_pages             NULL
+#define exynos_gem_prime_import_sg             NULL
 #endif
 #endif
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c 
b/drivers/gpu/drm/exynos/exynos_drm_drv.c
index 2b287d2..2a04e97 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
@@ -283,6 +283,8 @@ static struct drm_driver exynos_drm_driver = {
        .prime_fd_to_handle     = drm_gem_prime_fd_to_handle,
        .gem_prime_export       = exynos_dmabuf_prime_export,
        .gem_prime_import       = exynos_dmabuf_prime_import,
+       .gem_prime_get_pages    = exynos_gem_prime_get_pages,
+       .gem_prime_import_sg    = exynos_gem_prime_import_sg,
        .ioctls                 = exynos_ioctls,
        .fops                   = &exynos_drm_driver_fops,
        .name   = DRIVER_NAME,
-- 
1.8.0.1

Reply via email to