]> Pileus Git - ~andy/linux/blobdiff - drivers/gpu/drm/nouveau/nouveau_gem.c
Merge git://git.kvack.org/~bcrl/aio-next
[~andy/linux] / drivers / gpu / drm / nouveau / nouveau_gem.c
index f32b71238c03c3426034004779481925c8dc00ec..78a27f8ad7d97be653a63506bb60bd9c7b518252 100644 (file)
 #include "nouveau_ttm.h"
 #include "nouveau_gem.h"
 
-int
-nouveau_gem_object_new(struct drm_gem_object *gem)
-{
-       return 0;
-}
-
 void
 nouveau_gem_object_del(struct drm_gem_object *gem)
 {
-       struct nouveau_bo *nvbo = gem->driver_private;
+       struct nouveau_bo *nvbo = nouveau_gem_object(gem);
        struct ttm_buffer_object *bo = &nvbo->bo;
 
-       if (!nvbo)
-               return;
-       nvbo->gem = NULL;
-
        if (gem->import_attach)
                drm_prime_gem_destroy(gem, nvbo->bo.sg);
 
-       ttm_bo_unref(&bo);
-
        drm_gem_object_release(gem);
-       kfree(gem);
+
+       /* reset filp so nouveau_bo_del_ttm() can test for it */
+       gem->filp = NULL;
+       ttm_bo_unref(&bo);
 }
 
 int
@@ -115,8 +106,7 @@ nouveau_gem_object_unmap(struct nouveau_bo *nvbo, struct nouveau_vma *vma)
 
        if (mapped) {
                spin_lock(&nvbo->bo.bdev->fence_lock);
-               if (nvbo->bo.sync_obj)
-                       fence = nouveau_fence_ref(nvbo->bo.sync_obj);
+               fence = nouveau_fence_ref(nvbo->bo.sync_obj);
                spin_unlock(&nvbo->bo.bdev->fence_lock);
        }
 
@@ -186,14 +176,15 @@ nouveau_gem_new(struct drm_device *dev, int size, int align, uint32_t domain,
        if (nv_device(drm->device)->card_type >= NV_50)
                nvbo->valid_domains &= domain;
 
-       nvbo->gem = drm_gem_object_alloc(dev, nvbo->bo.mem.size);
-       if (!nvbo->gem) {
+       /* Initialize the embedded gem-object. We return a single gem-reference
+        * to the caller, instead of a normal nouveau_bo ttm reference. */
+       ret = drm_gem_object_init(dev, &nvbo->gem, nvbo->bo.mem.size);
+       if (ret) {
                nouveau_bo_ref(NULL, pnvbo);
                return -ENOMEM;
        }
 
-       nvbo->bo.persistent_swap_storage = nvbo->gem->filp;
-       nvbo->gem->driver_private = nvbo;
+       nvbo->bo.persistent_swap_storage = nvbo->gem.filp;
        return 0;
 }
 
@@ -250,15 +241,15 @@ nouveau_gem_ioctl_new(struct drm_device *dev, void *data,
        if (ret)
                return ret;
 
-       ret = drm_gem_handle_create(file_priv, nvbo->gem, &req->info.handle);
+       ret = drm_gem_handle_create(file_priv, &nvbo->gem, &req->info.handle);
        if (ret == 0) {
-               ret = nouveau_gem_info(file_priv, nvbo->gem, &req->info);
+               ret = nouveau_gem_info(file_priv, &nvbo->gem, &req->info);
                if (ret)
                        drm_gem_handle_delete(file_priv, req->info.handle);
        }
 
        /* drop reference from allocate - handle holds it now */
-       drm_gem_object_unreference_unlocked(nvbo->gem);
+       drm_gem_object_unreference_unlocked(&nvbo->gem);
        return ret;
 }
 
@@ -266,7 +257,7 @@ static int
 nouveau_gem_set_domain(struct drm_gem_object *gem, uint32_t read_domains,
                       uint32_t write_domains, uint32_t valid_domains)
 {
-       struct nouveau_bo *nvbo = gem->driver_private;
+       struct nouveau_bo *nvbo = nouveau_gem_object(gem);
        struct ttm_buffer_object *bo = &nvbo->bo;
        uint32_t domains = valid_domains & nvbo->valid_domains &
                (write_domains ? write_domains : read_domains);
@@ -317,7 +308,8 @@ validate_fini_list(struct list_head *list, struct nouveau_fence *fence,
        list_for_each_safe(entry, tmp, list) {
                nvbo = list_entry(entry, struct nouveau_bo, entry);
 
-               nouveau_bo_fence(nvbo, fence);
+               if (likely(fence))
+                       nouveau_bo_fence(nvbo, fence);
 
                if (unlikely(nvbo->validate_mapped)) {
                        ttm_bo_kunmap(&nvbo->kmap);
@@ -327,7 +319,7 @@ validate_fini_list(struct list_head *list, struct nouveau_fence *fence,
                list_del(&nvbo->entry);
                nvbo->reserved_by = NULL;
                ttm_bo_unreserve_ticket(&nvbo->bo, ticket);
-               drm_gem_object_unreference_unlocked(nvbo->gem);
+               drm_gem_object_unreference_unlocked(&nvbo->gem);
        }
 }
 
@@ -376,7 +368,7 @@ retry:
                        validate_fini(op, NULL);
                        return -ENOENT;
                }
-               nvbo = gem->driver_private;
+               nvbo = nouveau_gem_object(gem);
                if (nvbo == res_bo) {
                        res_bo = NULL;
                        drm_gem_object_unreference_unlocked(gem);
@@ -446,8 +438,7 @@ validate_sync(struct nouveau_channel *chan, struct nouveau_bo *nvbo)
        int ret = 0;
 
        spin_lock(&nvbo->bo.bdev->fence_lock);
-       if (nvbo->bo.sync_obj)
-               fence = nouveau_fence_ref(nvbo->bo.sync_obj);
+       fence = nouveau_fence_ref(nvbo->bo.sync_obj);
        spin_unlock(&nvbo->bo.bdev->fence_lock);
 
        if (fence) {
@@ -478,7 +469,7 @@ validate_list(struct nouveau_channel *chan, struct nouveau_cli *cli,
                        return ret;
                }
 
-               ret = nouveau_gem_set_domain(nvbo->gem, b->read_domains,
+               ret = nouveau_gem_set_domain(&nvbo->gem, b->read_domains,
                                             b->write_domains,
                                             b->valid_domains);
                if (unlikely(ret)) {