summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/exynos/exynos_drm_gem.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-01-29 20:49:12 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2014-01-29 20:49:12 -0800
commit9b0cd304f26b9fca140de15deeac2bf357d1f388 (patch)
tree03a0d74614865a5b776b2a98a433232013b1d369 /drivers/gpu/drm/exynos/exynos_drm_gem.c
parentca2a650f3dfdc30d71d21bcbb04d2d057779f3f9 (diff)
parentef64cf9d06049e4e9df661f3be60b217e476bee1 (diff)
Merge branch 'drm-next' of git://people.freedesktop.org/~airlied/linux
Pull drm updates from Dave Airlie: "Been a bit busy, first week of kids school, and waiting on other trees to go in before I could send this, so its a bit later than I'd normally like. Highlights: - core: timestamp fixes, lots of misc cleanups - new drivers: bochs virtual vga - vmwgfx: major overhaul for their nextgen virt gpu. - i915: runtime D3 on HSW, watermark fixes, power well work, fbc fixes, bdw is no longer prelim. - nouveau: gk110/208 acceleration, more pm groundwork, old overlay support - radeon: dpm rework and clockgating for CIK, pci config reset, big endian fixes - tegra: panel support and DSI support, build as module, prime. - armada, omap, gma500, rcar, exynos, mgag200, cirrus, ast: fixes - msm: hdmi support for mdp5" * 'drm-next' of git://people.freedesktop.org/~airlied/linux: (595 commits) drm/nouveau: resume display if any later suspend bits fail drm/nouveau: fix lock unbalance in nouveau_crtc_page_flip drm/nouveau: implement hooks for needed for drm vblank timestamping support drm/nouveau/disp: add a method to fetch info needed by drm vblank timestamping drm/nv50: fill in crtc mode struct members from crtc_mode_fixup drm/radeon/dce8: workaround for atom BlankCrtc table drm/radeon/DCE4+: clear bios scratch dpms bit (v2) drm/radeon: set si_notify_smc_display_change properly drm/radeon: fix DAC interrupt handling on DCE5+ drm/radeon: clean up active vram sizing drm/radeon: skip async dma init on r6xx drm/radeon/runpm: don't runtime suspend non-PX cards drm/radeon: add ring to fence trace functions drm/radeon: add missing trace point drm/radeon: fix VMID use tracking drm: ast,cirrus,mgag200: use drm_can_sleep drm/gma500: Lock struct_mutex around cursor updates drm/i915: Fix the offset issue for the stolen GEM objects DRM: armada: fix missing DRM_KMS_FB_HELPER select drm/i915: Decouple GPU error reporting from ring initialisation ...
Diffstat (limited to 'drivers/gpu/drm/exynos/exynos_drm_gem.c')
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_gem.c74
1 files changed, 13 insertions, 61 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c
index be59d50d8b16..42d2904d88c7 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
@@ -338,46 +338,22 @@ int exynos_drm_gem_map_offset_ioctl(struct drm_device *dev, void *data,
&args->offset);
}
-static struct drm_file *exynos_drm_find_drm_file(struct drm_device *drm_dev,
- struct file *filp)
-{
- struct drm_file *file_priv;
-
- /* find current process's drm_file from filelist. */
- list_for_each_entry(file_priv, &drm_dev->filelist, lhead)
- if (file_priv->filp == filp)
- return file_priv;
-
- WARN_ON(1);
-
- return ERR_PTR(-EFAULT);
-}
-
-static int exynos_drm_gem_mmap_buffer(struct file *filp,
+int exynos_drm_gem_mmap_buffer(struct file *filp,
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 exynos_drm_gem_buf *buffer;
- struct drm_file *file_priv;
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;
- /* restore it to driver's fops. */
- filp->f_op = fops_get(drm_dev->driver->fops);
-
- file_priv = exynos_drm_find_drm_file(drm_dev, filp);
- if (IS_ERR(file_priv))
- return PTR_ERR(file_priv);
-
- /* restore it to drm_file. */
- filp->private_data = file_priv;
-
update_vm_cache_attr(exynos_gem_obj, vma);
vm_size = vma->vm_end - vma->vm_start;
@@ -411,15 +387,13 @@ static int exynos_drm_gem_mmap_buffer(struct file *filp,
return 0;
}
-static const struct file_operations exynos_drm_gem_fops = {
- .mmap = exynos_drm_gem_mmap_buffer,
-};
-
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)) {
@@ -427,47 +401,25 @@ int exynos_drm_gem_mmap_ioctl(struct drm_device *dev, void *data,
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;
}
- /*
- * We have to use gem object and its fops for specific mmaper,
- * but vm_mmap() can deliver only filp. So we have to change
- * filp->f_op and filp->private_data temporarily, then restore
- * again. So it is important to keep lock until restoration the
- * settings to prevent others from misuse of filp->f_op or
- * filp->private_data.
- */
- mutex_lock(&dev->struct_mutex);
-
- /*
- * Set specific mmper's fops. And it will be restored by
- * exynos_drm_gem_mmap_buffer to dev->driver->fops.
- * This is used to call specific mapper temporarily.
- */
- file_priv->filp->f_op = &exynos_drm_gem_fops;
-
- /*
- * Set gem object to private_data so that specific mmaper
- * can get the gem object. And it will be restored by
- * exynos_drm_gem_mmap_buffer to drm_file.
- */
- file_priv->filp->private_data = obj;
+ exynos_file_priv = file_priv->driver_priv;
+ anon_filp = exynos_file_priv->anon_filp;
+ anon_filp->private_data = obj;
- addr = vm_mmap(file_priv->filp, 0, args->size,
- PROT_READ | PROT_WRITE, MAP_SHARED, 0);
+ 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)) {
- /* check filp->f_op, filp->private_data are restored */
- if (file_priv->filp->f_op == &exynos_drm_gem_fops) {
- file_priv->filp->f_op = fops_get(dev->driver->fops);
- file_priv->filp->private_data = file_priv;
- }
mutex_unlock(&dev->struct_mutex);
return (int)addr;
}