]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/gpu/drm/radeon/radeon_gem.c
Merge branch 'linus' into perf/urgent
[karo-tx-linux.git] / drivers / gpu / drm / radeon / radeon_gem.c
index c7008b5210f74d43481017c6d544ae77f78f83cf..f28bd4b7ef980937c88eb54c30b5534adc5abf3b 100644 (file)
@@ -42,6 +42,8 @@ void radeon_gem_object_free(struct drm_gem_object *gobj)
        struct radeon_bo *robj = gem_to_radeon_bo(gobj);
 
        if (robj) {
+               if (robj->gem_base.import_attach)
+                       drm_prime_gem_destroy(&robj->gem_base, robj->tbo.sg);
                radeon_bo_unref(&robj);
        }
 }
@@ -59,7 +61,7 @@ int radeon_gem_object_create(struct radeon_device *rdev, int size,
        if (alignment < PAGE_SIZE) {
                alignment = PAGE_SIZE;
        }
-       r = radeon_bo_create(rdev, size, alignment, kernel, initial_domain, &robj);
+       r = radeon_bo_create(rdev, size, alignment, kernel, initial_domain, NULL, &robj);
        if (r) {
                if (r != -ERESTARTSYS)
                        DRM_ERROR("Failed to allocate GEM object (%d, %d, %u, %d)\n",
@@ -91,7 +93,7 @@ int radeon_gem_set_domain(struct drm_gem_object *gobj,
        }
        if (!domain) {
                /* Do nothings */
-               printk(KERN_WARNING "Set domain withou domain !\n");
+               printk(KERN_WARNING "Set domain without domain !\n");
                return 0;
        }
        if (domain == RADEON_GEM_DOMAIN_CPU) {
@@ -154,6 +156,17 @@ void radeon_gem_object_close(struct drm_gem_object *obj,
        radeon_bo_unreserve(rbo);
 }
 
+static int radeon_gem_handle_lockup(struct radeon_device *rdev, int r)
+{
+       if (r == -EDEADLK) {
+               radeon_mutex_lock(&rdev->cs_mutex);
+               r = radeon_gpu_reset(rdev);
+               if (!r)
+                       r = -EAGAIN;
+               radeon_mutex_unlock(&rdev->cs_mutex);
+       }
+       return r;
+}
 
 /*
  * GEM ioctls.
@@ -210,12 +223,14 @@ int radeon_gem_create_ioctl(struct drm_device *dev, void *data,
                                        args->initial_domain, false,
                                        false, &gobj);
        if (r) {
+               r = radeon_gem_handle_lockup(rdev, r);
                return r;
        }
        r = drm_gem_handle_create(filp, gobj, &handle);
        /* drop reference from allocate - handle holds it now */
        drm_gem_object_unreference_unlocked(gobj);
        if (r) {
+               r = radeon_gem_handle_lockup(rdev, r);
                return r;
        }
        args->handle = handle;
@@ -245,6 +260,7 @@ int radeon_gem_set_domain_ioctl(struct drm_device *dev, void *data,
        r = radeon_gem_set_domain(gobj, args->read_domains, args->write_domain);
 
        drm_gem_object_unreference_unlocked(gobj);
+       r = radeon_gem_handle_lockup(robj->rdev, r);
        return r;
 }
 
@@ -301,6 +317,7 @@ int radeon_gem_busy_ioctl(struct drm_device *dev, void *data,
                break;
        }
        drm_gem_object_unreference_unlocked(gobj);
+       r = radeon_gem_handle_lockup(robj->rdev, r);
        return r;
 }
 
@@ -322,6 +339,7 @@ int radeon_gem_wait_idle_ioctl(struct drm_device *dev, void *data,
        if (robj->rdev->asic->ioctl_wait_idle)
                robj->rdev->asic->ioctl_wait_idle(robj->rdev, robj);
        drm_gem_object_unreference_unlocked(gobj);
+       r = radeon_gem_handle_lockup(robj->rdev, r);
        return r;
 }