aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/drm_fops.c14
-rw-r--r--drivers/gpu/drm/drm_stub.c11
-rw-r--r--include/drm/drmP.h9
3 files changed, 34 insertions, 0 deletions
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
index 8ac7fbf6b2b7..08d14df3bb42 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,
300 goto out_free; 300 goto out_free;
301 } 301 }
302 } 302 }
303 mutex_lock(&dev->struct_mutex);
304 if (dev->driver->master_set) {
305 ret = dev->driver->master_set(dev, priv, true);
306 if (ret) {
307 /* drop both references if this fails */
308 drm_master_put(&priv->minor->master);
309 drm_master_put(&priv->master);
310 mutex_unlock(&dev->struct_mutex);
311 goto out_free;
312 }
313 }
314 mutex_unlock(&dev->struct_mutex);
303 } else { 315 } else {
304 /* get a reference to the master */ 316 /* get a reference to the master */
305 priv->master = drm_master_get(priv->minor->master); 317 priv->master = drm_master_get(priv->minor->master);
@@ -533,6 +545,8 @@ int drm_release(struct inode *inode, struct file *filp)
533 545
534 if (file_priv->minor->master == file_priv->master) { 546 if (file_priv->minor->master == file_priv->master) {
535 /* drop the reference held my the minor */ 547 /* drop the reference held my the minor */
548 if (dev->driver->master_drop)
549 dev->driver->master_drop(dev, file_priv, true);
536 drm_master_put(&file_priv->minor->master); 550 drm_master_put(&file_priv->minor->master);
537 } 551 }
538 } 552 }
diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c
index adb864dfef3e..2c1b52847e9e 100644
--- a/drivers/gpu/drm/drm_stub.c
+++ b/drivers/gpu/drm/drm_stub.c
@@ -174,6 +174,8 @@ void drm_master_put(struct drm_master **master)
174int drm_setmaster_ioctl(struct drm_device *dev, void *data, 174int drm_setmaster_ioctl(struct drm_device *dev, void *data,
175 struct drm_file *file_priv) 175 struct drm_file *file_priv)
176{ 176{
177 int ret = 0;
178
177 if (file_priv->is_master) 179 if (file_priv->is_master)
178 return 0; 180 return 0;
179 181
@@ -188,6 +190,13 @@ int drm_setmaster_ioctl(struct drm_device *dev, void *data,
188 mutex_lock(&dev->struct_mutex); 190 mutex_lock(&dev->struct_mutex);
189 file_priv->minor->master = drm_master_get(file_priv->master); 191 file_priv->minor->master = drm_master_get(file_priv->master);
190 file_priv->is_master = 1; 192 file_priv->is_master = 1;
193 if (dev->driver->master_set) {
194 ret = dev->driver->master_set(dev, file_priv, false);
195 if (unlikely(ret != 0)) {
196 file_priv->is_master = 0;
197 drm_master_put(&file_priv->minor->master);
198 }
199 }
191 mutex_unlock(&dev->struct_mutex); 200 mutex_unlock(&dev->struct_mutex);
192 } 201 }
193 202
@@ -204,6 +213,8 @@ int drm_dropmaster_ioctl(struct drm_device *dev, void *data,
204 return -EINVAL; 213 return -EINVAL;
205 214
206 mutex_lock(&dev->struct_mutex); 215 mutex_lock(&dev->struct_mutex);
216 if (dev->driver->master_drop)
217 dev->driver->master_drop(dev, file_priv, false);
207 drm_master_put(&file_priv->minor->master); 218 drm_master_put(&file_priv->minor->master);
208 file_priv->is_master = 0; 219 file_priv->is_master = 0;
209 mutex_unlock(&dev->struct_mutex); 220 mutex_unlock(&dev->struct_mutex);
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index 1b72a526ba64..770772c014aa 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -774,6 +774,15 @@ struct drm_driver {
774 /* Master routines */ 774 /* Master routines */
775 int (*master_create)(struct drm_device *dev, struct drm_master *master); 775 int (*master_create)(struct drm_device *dev, struct drm_master *master);
776 void (*master_destroy)(struct drm_device *dev, struct drm_master *master); 776 void (*master_destroy)(struct drm_device *dev, struct drm_master *master);
777 /**
778 * master_set is called whenever the minor master is set.
779 * master_drop is called whenever the minor master is dropped.
780 */
781
782 int (*master_set)(struct drm_device *dev, struct drm_file *file_priv,
783 bool from_open);
784 void (*master_drop)(struct drm_device *dev, struct drm_file *file_priv,
785 bool from_release);
777 786
778 int (*proc_init)(struct drm_minor *minor); 787 int (*proc_init)(struct drm_minor *minor);
779 void (*proc_cleanup)(struct drm_minor *minor); 788 void (*proc_cleanup)(struct drm_minor *minor);