This allows importing bo's to own device to work without requiring that the 
buffer is pinned in GART.

Signed-off-by: Maarten Lankhorst <maarten.lankhorst at canonical.com>
---
 drivers/gpu/drm/drm_prime.c | 41 ++++++++++++++++++++++++++---------------
 1 file changed, 26 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c
index 85bbc52..16b302a 100644
--- a/drivers/gpu/drm/drm_prime.c
+++ b/drivers/gpu/drm/drm_prime.c
@@ -63,6 +63,29 @@ struct drm_prime_member {
        uint32_t handle;
 };

+static int drm_gem_map_attach(struct dma_buf *dma_buf,
+                             struct device *target_dev,
+                             struct dma_buf_attachment *attach)
+{
+       struct drm_gem_object *obj = dma_buf->priv;
+       struct drm_device *dev = obj->dev;
+
+       if (!dev->driver->gem_prime_pin)
+               return 0;
+
+       return dev->driver->gem_prime_pin(obj);
+}
+
+static void drm_gem_map_detach(struct dma_buf *dma_buf,
+                              struct dma_buf_attachment *attach)
+{
+       struct drm_gem_object *obj = dma_buf->priv;
+       struct drm_device *dev = obj->dev;
+
+       if (dev->driver->gem_prime_unpin)
+               dev->driver->gem_prime_unpin(obj);
+}
+
 static struct sg_table *drm_gem_map_dma_buf(struct dma_buf_attachment *attach,
                enum dma_data_direction dir)
 {
@@ -91,13 +114,10 @@ static void drm_gem_unmap_dma_buf(struct 
dma_buf_attachment *attach,
 static void drm_gem_dmabuf_release(struct dma_buf *dma_buf)
 {
        struct drm_gem_object *obj = dma_buf->priv;
-       struct drm_device *dev = obj->dev;

        if (obj->export_dma_buf == dma_buf) {
                /* drop the reference on the export fd holds */
                obj->export_dma_buf = NULL;
-               if (dev->driver->gem_prime_unpin)
-                       dev->driver->gem_prime_unpin(obj);
                drm_gem_object_unreference_unlocked(obj);
        }
 }
@@ -148,6 +168,8 @@ static int drm_gem_dmabuf_mmap(struct dma_buf *dma_buf,
 }

 static const struct dma_buf_ops drm_gem_prime_dmabuf_ops =  {
+       .attach = drm_gem_map_attach,
+       .detach = drm_gem_map_detach,
        .map_dma_buf = drm_gem_map_dma_buf,
        .unmap_dma_buf = drm_gem_unmap_dma_buf,
        .release = drm_gem_dmabuf_release,
@@ -187,19 +209,8 @@ static const struct dma_buf_ops drm_gem_prime_dmabuf_ops = 
 {
 struct dma_buf *drm_gem_prime_export(struct drm_device *dev,
                                     struct drm_gem_object *obj, int flags)
 {
-       struct dma_buf *buf;
-
-       if (dev->driver->gem_prime_pin) {
-               int ret = dev->driver->gem_prime_pin(obj);
-               if (ret)
-                       return ERR_PTR(ret);
-       }
-       buf = dma_buf_export(obj, &drm_gem_prime_dmabuf_ops, obj->size,
+       return dma_buf_export(obj, &drm_gem_prime_dmabuf_ops, obj->size,
                             0600);
-
-       if (IS_ERR(buf) && dev->driver->gem_prime_unpin)
-               dev->driver->gem_prime_unpin(obj);
-       return buf;
 }
 EXPORT_SYMBOL(drm_gem_prime_export);

-- 
1.8.2

Reply via email to