Merge branch 'drm-armada-devel' of git://ftp.arm.linux.org.uk/~rmk/linux-arm into...
[deliverable/linux.git] / drivers / gpu / drm / armada / armada_gem.c
index 60a688ef81c71cf1174c081426c10c80e9453bdb..6e731db31aa49c9c65e9f6eebd3b789ca4daa78b 100644 (file)
@@ -46,22 +46,26 @@ static size_t roundup_gem_size(size_t size)
        return roundup(size, PAGE_SIZE);
 }
 
-/* dev->struct_mutex is held here */
 void armada_gem_free_object(struct drm_gem_object *obj)
 {
        struct armada_gem_object *dobj = drm_to_armada_gem(obj);
+       struct armada_private *priv = obj->dev->dev_private;
 
        DRM_DEBUG_DRIVER("release obj %p\n", dobj);
 
        drm_gem_free_mmap_offset(&dobj->obj);
 
+       might_lock(&priv->linear_lock);
+
        if (dobj->page) {
                /* page backed memory */
                unsigned int order = get_order(dobj->obj.size);
                __free_pages(dobj->page, order);
        } else if (dobj->linear) {
                /* linear backed memory */
+               mutex_lock(&priv->linear_lock);
                drm_mm_remove_node(dobj->linear);
+               mutex_unlock(&priv->linear_lock);
                kfree(dobj->linear);
                if (dobj->addr)
                        iounmap(dobj->addr);
@@ -144,10 +148,10 @@ armada_gem_linear_back(struct drm_device *dev, struct armada_gem_object *obj)
                if (!node)
                        return -ENOSPC;
 
-               mutex_lock(&dev->struct_mutex);
+               mutex_lock(&priv->linear_lock);
                ret = drm_mm_insert_node(&priv->linear, node, size, align,
                                         DRM_MM_SEARCH_DEFAULT);
-               mutex_unlock(&dev->struct_mutex);
+               mutex_unlock(&priv->linear_lock);
                if (ret) {
                        kfree(node);
                        return ret;
@@ -158,9 +162,9 @@ armada_gem_linear_back(struct drm_device *dev, struct armada_gem_object *obj)
                /* Ensure that the memory we're returning is cleared. */
                ptr = ioremap_wc(obj->linear->start, size);
                if (!ptr) {
-                       mutex_lock(&dev->struct_mutex);
+                       mutex_lock(&priv->linear_lock);
                        drm_mm_remove_node(obj->linear);
-                       mutex_unlock(&dev->struct_mutex);
+                       mutex_unlock(&priv->linear_lock);
                        kfree(obj->linear);
                        obj->linear = NULL;
                        return -ENOMEM;
@@ -274,18 +278,16 @@ int armada_gem_dumb_map_offset(struct drm_file *file, struct drm_device *dev,
        struct armada_gem_object *obj;
        int ret = 0;
 
-       mutex_lock(&dev->struct_mutex);
        obj = armada_gem_object_lookup(dev, file, handle);
        if (!obj) {
                DRM_ERROR("failed to lookup gem object\n");
-               ret = -EINVAL;
-               goto err_unlock;
+               return -EINVAL;
        }
 
        /* Don't allow imported objects to be mapped */
        if (obj->obj.import_attach) {
                ret = -EINVAL;
-               goto err_unlock;
+               goto err_unref;
        }
 
        ret = drm_gem_create_mmap_offset(&obj->obj);
@@ -294,9 +296,8 @@ int armada_gem_dumb_map_offset(struct drm_file *file, struct drm_device *dev,
                DRM_DEBUG_DRIVER("handle %#x offset %llx\n", handle, *offset);
        }
 
-       drm_gem_object_unreference(&obj->obj);
- err_unlock:
-       mutex_unlock(&dev->struct_mutex);
+ err_unref:
+       drm_gem_object_unreference_unlocked(&obj->obj);
 
        return ret;
 }
@@ -352,13 +353,13 @@ int armada_gem_mmap_ioctl(struct drm_device *dev, void *data,
                return -ENOENT;
 
        if (!dobj->obj.filp) {
-               drm_gem_object_unreference(&dobj->obj);
+               drm_gem_object_unreference_unlocked(&dobj->obj);
                return -EINVAL;
        }
 
        addr = vm_mmap(dobj->obj.filp, 0, args->size, PROT_READ | PROT_WRITE,
                       MAP_SHARED, args->offset);
-       drm_gem_object_unreference(&dobj->obj);
+       drm_gem_object_unreference_unlocked(&dobj->obj);
        if (IS_ERR_VALUE(addr))
                return addr;
 
This page took 0.025763 seconds and 5 git commands to generate.