OSDN Git Service

Merge tag 'topic/drm-misc-2016-03-22' of git://anongit.freedesktop.org/drm-intel...
[uclinux-h8/linux.git] / drivers / gpu / drm / omapdrm / omap_gem_dmabuf.c
index c75249d..af267c3 100644 (file)
 
 #include "omap_drv.h"
 
+/* -----------------------------------------------------------------------------
+ * DMABUF Export
+ */
+
 static struct sg_table *omap_gem_map_dma_buf(
                struct dma_buf_attachment *attachment,
                enum dma_data_direction dir)
@@ -179,15 +183,20 @@ struct dma_buf *omap_gem_prime_export(struct drm_device *dev,
        return dma_buf_export(&exp_info);
 }
 
+/* -----------------------------------------------------------------------------
+ * DMABUF Import
+ */
+
 struct drm_gem_object *omap_gem_prime_import(struct drm_device *dev,
-               struct dma_buf *buffer)
+                                            struct dma_buf *dma_buf)
 {
+       struct dma_buf_attachment *attach;
        struct drm_gem_object *obj;
+       struct sg_table *sgt;
+       int ret;
 
-       /* is this one of own objects? */
-       if (buffer->ops == &omap_dmabuf_ops) {
-               obj = buffer->priv;
-               /* is it from our device? */
+       if (dma_buf->ops == &omap_dmabuf_ops) {
+               obj = dma_buf->priv;
                if (obj->dev == dev) {
                        /*
                         * Importing dmabuf exported from out own gem increases
@@ -198,9 +207,33 @@ struct drm_gem_object *omap_gem_prime_import(struct drm_device *dev,
                }
        }
 
-       /*
-        * TODO add support for importing buffers from other devices..
-        * for now we don't need this but would be nice to add eventually
-        */
-       return ERR_PTR(-EINVAL);
+       attach = dma_buf_attach(dma_buf, dev->dev);
+       if (IS_ERR(attach))
+               return ERR_CAST(attach);
+
+       get_dma_buf(dma_buf);
+
+       sgt = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL);
+       if (IS_ERR(sgt)) {
+               ret = PTR_ERR(sgt);
+               goto fail_detach;
+       }
+
+       obj = omap_gem_new_dmabuf(dev, dma_buf->size, sgt);
+       if (IS_ERR(obj)) {
+               ret = PTR_ERR(obj);
+               goto fail_unmap;
+       }
+
+       obj->import_attach = attach;
+
+       return obj;
+
+fail_unmap:
+       dma_buf_unmap_attachment(attach, sgt, DMA_BIDIRECTIONAL);
+fail_detach:
+       dma_buf_detach(dma_buf, attach);
+       dma_buf_put(dma_buf);
+
+       return ERR_PTR(ret);
 }