|
@@ -318,23 +318,16 @@ void exynos_drm_gem_put_dma_addr(struct drm_device *dev,
|
|
|
drm_gem_object_unreference_unlocked(obj);
|
|
|
}
|
|
|
|
|
|
-int exynos_drm_gem_mmap_buffer(struct file *filp,
|
|
|
+int exynos_drm_gem_mmap_buffer(struct exynos_drm_gem_obj *exynos_gem_obj,
|
|
|
struct vm_area_struct *vma)
|
|
|
{
|
|
|
- struct drm_gem_object *obj = filp->private_data;
|
|
|
- struct exynos_drm_gem_obj *exynos_gem_obj = to_exynos_gem_obj(obj);
|
|
|
- struct drm_device *drm_dev = obj->dev;
|
|
|
+ struct drm_device *drm_dev = exynos_gem_obj->base.dev;
|
|
|
struct exynos_drm_gem_buf *buffer;
|
|
|
unsigned long vm_size;
|
|
|
int ret;
|
|
|
|
|
|
- WARN_ON(!mutex_is_locked(&obj->dev->struct_mutex));
|
|
|
-
|
|
|
- vma->vm_flags |= VM_IO | VM_DONTEXPAND | VM_DONTDUMP;
|
|
|
- vma->vm_private_data = obj;
|
|
|
- vma->vm_ops = drm_dev->driver->gem_vm_ops;
|
|
|
-
|
|
|
- update_vm_cache_attr(exynos_gem_obj, vma);
|
|
|
+ vma->vm_flags &= ~VM_PFNMAP;
|
|
|
+ vma->vm_pgoff = 0;
|
|
|
|
|
|
vm_size = vma->vm_end - vma->vm_start;
|
|
|
|
|
@@ -356,60 +349,6 @@ int exynos_drm_gem_mmap_buffer(struct file *filp,
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
- /*
|
|
|
- * take a reference to this mapping of the object. And this reference
|
|
|
- * is unreferenced by the corresponding vm_close call.
|
|
|
- */
|
|
|
- drm_gem_object_reference(obj);
|
|
|
-
|
|
|
- drm_vm_open_locked(drm_dev, vma);
|
|
|
-
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-int exynos_drm_gem_mmap_ioctl(struct drm_device *dev, void *data,
|
|
|
- struct drm_file *file_priv)
|
|
|
-{
|
|
|
- struct drm_exynos_file_private *exynos_file_priv;
|
|
|
- struct drm_exynos_gem_mmap *args = data;
|
|
|
- struct drm_gem_object *obj;
|
|
|
- struct file *anon_filp;
|
|
|
- unsigned long addr;
|
|
|
-
|
|
|
- if (!(dev->driver->driver_features & DRIVER_GEM)) {
|
|
|
- DRM_ERROR("does not support GEM.\n");
|
|
|
- return -ENODEV;
|
|
|
- }
|
|
|
-
|
|
|
- mutex_lock(&dev->struct_mutex);
|
|
|
-
|
|
|
- obj = drm_gem_object_lookup(dev, file_priv, args->handle);
|
|
|
- if (!obj) {
|
|
|
- DRM_ERROR("failed to lookup gem object.\n");
|
|
|
- mutex_unlock(&dev->struct_mutex);
|
|
|
- return -EINVAL;
|
|
|
- }
|
|
|
-
|
|
|
- exynos_file_priv = file_priv->driver_priv;
|
|
|
- anon_filp = exynos_file_priv->anon_filp;
|
|
|
- anon_filp->private_data = obj;
|
|
|
-
|
|
|
- addr = vm_mmap(anon_filp, 0, args->size, PROT_READ | PROT_WRITE,
|
|
|
- MAP_SHARED, 0);
|
|
|
-
|
|
|
- drm_gem_object_unreference(obj);
|
|
|
-
|
|
|
- if (IS_ERR_VALUE(addr)) {
|
|
|
- mutex_unlock(&dev->struct_mutex);
|
|
|
- return (int)addr;
|
|
|
- }
|
|
|
-
|
|
|
- mutex_unlock(&dev->struct_mutex);
|
|
|
-
|
|
|
- args->mapped = addr;
|
|
|
-
|
|
|
- DRM_DEBUG_KMS("mapped = 0x%lx\n", (unsigned long)args->mapped);
|
|
|
-
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -693,16 +632,20 @@ int exynos_drm_gem_mmap(struct file *filp, struct vm_area_struct *vma)
|
|
|
exynos_gem_obj = to_exynos_gem_obj(obj);
|
|
|
|
|
|
ret = check_gem_flags(exynos_gem_obj->flags);
|
|
|
- if (ret) {
|
|
|
- drm_gem_vm_close(vma);
|
|
|
- drm_gem_free_mmap_offset(obj);
|
|
|
- return ret;
|
|
|
- }
|
|
|
-
|
|
|
- vma->vm_flags &= ~VM_PFNMAP;
|
|
|
- vma->vm_flags |= VM_MIXEDMAP;
|
|
|
+ if (ret)
|
|
|
+ goto err_close_vm;
|
|
|
|
|
|
update_vm_cache_attr(exynos_gem_obj, vma);
|
|
|
|
|
|
+ ret = exynos_drm_gem_mmap_buffer(exynos_gem_obj, vma);
|
|
|
+ if (ret)
|
|
|
+ goto err_close_vm;
|
|
|
+
|
|
|
+ return ret;
|
|
|
+
|
|
|
+err_close_vm:
|
|
|
+ drm_gem_vm_close(vma);
|
|
|
+ drm_gem_free_mmap_offset(obj);
|
|
|
+
|
|
|
return ret;
|
|
|
}
|