summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/drm_fops.c
diff options
context:
space:
mode:
authorThomas Hellstrom <thellstrom@vmware.com>2009-12-02 18:15:25 (GMT)
committerDave Airlie <airlied@redhat.com>2009-12-03 22:55:46 (GMT)
commit862302ffe422378a5213f558fc5cdf62c37050a9 (patch)
tree13557874eb479023e5a64f12990416045ea60818 /drivers/gpu/drm/drm_fops.c
parent9340d8cfeacd16cef1cbe94527f7baaed7640669 (diff)
downloadlinux-862302ffe422378a5213f558fc5cdf62c37050a9.tar.xz
drm: Add support for drm master_[set|drop] callbacks.
The vmwgfx driver has a per master rw lock around TTM, to guarantee mutual exclusion when needed. This is typically when all evictable buffers are evicted due to 1) vt switch 2) master switch 3) suspend / resume. In the multi-master case, on master switch the new master takes the previously active master lock in write mode, and then evicts all buffers. Any clients to previous masters will then block on that lock when trying to validate a buffer. fbdev also acts as a virtual master wrt this. Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com> Signed-off-by: Jakob Bornecrantz <jakob@vmware.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/drm_fops.c')
-rw-r--r--drivers/gpu/drm/drm_fops.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
index 8ac7fbf..08d14df 100644
--- a/drivers/gpu/drm/drm_fops.c
+++ b/drivers/gpu/drm/drm_fops.c
@@ -300,6 +300,18 @@ static int drm_open_helper(struct inode *inode, struct file *filp,
goto out_free;
}
}
+ mutex_lock(&dev->struct_mutex);
+ if (dev->driver->master_set) {
+ ret = dev->driver->master_set(dev, priv, true);
+ if (ret) {
+ /* drop both references if this fails */
+ drm_master_put(&priv->minor->master);
+ drm_master_put(&priv->master);
+ mutex_unlock(&dev->struct_mutex);
+ goto out_free;
+ }
+ }
+ mutex_unlock(&dev->struct_mutex);
} else {
/* get a reference to the master */
priv->master = drm_master_get(priv->minor->master);
@@ -533,6 +545,8 @@ int drm_release(struct inode *inode, struct file *filp)
if (file_priv->minor->master == file_priv->master) {
/* drop the reference held my the minor */
+ if (dev->driver->master_drop)
+ dev->driver->master_drop(dev, file_priv, true);
drm_master_put(&file_priv->minor->master);
}
}