X-Git-Url: http://git.cascardo.info/?a=blobdiff_plain;f=drivers%2Fgpu%2Fdrm%2Fdrm_fops.c;h=323c238fcac70426f947977649ccd38442693e03;hb=586efded6b8beb932e9a356f351b0c681503358f;hp=64121f567234369bf40189a2f40846832cafaf30;hpb=2cca45574007b4a77fa5f63ea45d664510cec22a;p=cascardo%2Flinux.git diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c index 64121f567234..323c238fcac7 100644 --- a/drivers/gpu/drm/drm_fops.c +++ b/drivers/gpu/drm/drm_fops.c @@ -40,6 +40,7 @@ #include #include "drm_legacy.h" #include "drm_internal.h" +#include "drm_crtc_internal.h" /* from BKL pushdown */ DEFINE_MUTEX(drm_global_mutex); @@ -167,60 +168,6 @@ static int drm_cpu_valid(void) return 1; } -/* - * drm_new_set_master - Allocate a new master object and become master for the - * associated master realm. - * - * @dev: The associated device. - * @fpriv: File private identifying the client. - * - * This function must be called with dev::struct_mutex held. - * Returns negative error code on failure. Zero on success. - */ -int drm_new_set_master(struct drm_device *dev, struct drm_file *fpriv) -{ - struct drm_master *old_master; - int ret; - - lockdep_assert_held_once(&dev->master_mutex); - - /* create a new master */ - fpriv->minor->master = drm_master_create(fpriv->minor); - if (!fpriv->minor->master) - return -ENOMEM; - - /* take another reference for the copy in the local file priv */ - old_master = fpriv->master; - fpriv->master = drm_master_get(fpriv->minor->master); - - if (dev->driver->master_create) { - ret = dev->driver->master_create(dev, fpriv->master); - if (ret) - goto out_err; - } - if (dev->driver->master_set) { - ret = dev->driver->master_set(dev, fpriv, true); - if (ret) - goto out_err; - } - - fpriv->is_master = 1; - fpriv->allowed_master = 1; - fpriv->authenticated = 1; - if (old_master) - drm_master_put(&old_master); - - return 0; - -out_err: - /* drop both references and restore old master on failure */ - drm_master_put(&fpriv->minor->master); - drm_master_put(&fpriv->master); - fpriv->master = old_master; - - return ret; -} - /* * Called whenever a process opens /dev/drm. * @@ -283,19 +230,11 @@ static int drm_open_helper(struct file *filp, struct drm_minor *minor) goto out_prime_destroy; } - /* if there is no current master make this fd it, but do not create - * any master object for render clients */ - mutex_lock(&dev->master_mutex); - if (drm_is_primary_client(priv) && !priv->minor->master) { - /* create a new master */ - ret = drm_new_set_master(dev, priv); + if (drm_is_primary_client(priv)) { + ret = drm_master_open(priv); if (ret) goto out_close; - } else if (drm_is_primary_client(priv)) { - /* get a reference to the master */ - priv->master = drm_master_get(priv->minor->master); } - mutex_unlock(&dev->master_mutex); mutex_lock(&dev->filelist_mutex); list_add(&priv->lhead, &dev->filelist); @@ -324,7 +263,6 @@ static int drm_open_helper(struct file *filp, struct drm_minor *minor) return 0; out_close: - mutex_unlock(&dev->master_mutex); if (dev->driver->postclose) dev->driver->postclose(dev, priv); out_prime_destroy: @@ -338,18 +276,6 @@ out_prime_destroy: return ret; } -static void drm_master_release(struct drm_device *dev, struct file *filp) -{ - struct drm_file *file_priv = filp->private_data; - - if (drm_legacy_i_have_hw_lock(dev, file_priv)) { - DRM_DEBUG("File %p released, freeing lock for context %d\n", - filp, _DRM_LOCKING_CONTEXT(file_priv->master->lock.hw_lock->lock)); - drm_legacy_lock_free(&file_priv->master->lock, - _DRM_LOCKING_CONTEXT(file_priv->master->lock.hw_lock->lock)); - } -} - static void drm_events_release(struct drm_file *file_priv) { struct drm_device *dev = file_priv->minor->dev; @@ -451,11 +377,6 @@ int drm_release(struct inode *inode, struct file *filp) list_del(&file_priv->lhead); mutex_unlock(&dev->filelist_mutex); - mutex_lock(&dev->struct_mutex); - if (file_priv->magic) - idr_remove(&file_priv->master->magic_map, file_priv->magic); - mutex_unlock(&dev->struct_mutex); - if (dev->driver->preclose) dev->driver->preclose(dev, file_priv); @@ -468,9 +389,8 @@ int drm_release(struct inode *inode, struct file *filp) (long)old_encode_dev(file_priv->minor->kdev->devt), dev->open_count); - /* if the master has gone away we can't do anything with the lock */ - if (file_priv->minor->master) - drm_master_release(dev, filp); + if (!drm_core_check_feature(dev, DRIVER_MODESET)) + drm_legacy_lock_release(dev, filp); if (drm_core_check_feature(dev, DRIVER_HAVE_DMA)) drm_legacy_reclaim_buffers(dev, file_priv); @@ -487,43 +407,12 @@ int drm_release(struct inode *inode, struct file *filp) drm_legacy_ctxbitmap_flush(dev, file_priv); - mutex_lock(&dev->master_mutex); - - if (file_priv->is_master) { - struct drm_master *master = file_priv->master; - - /* - * Since the master is disappearing, so is the - * possibility to lock. - */ - mutex_lock(&dev->struct_mutex); - if (master->lock.hw_lock) { - if (dev->sigdata.lock == master->lock.hw_lock) - dev->sigdata.lock = NULL; - master->lock.hw_lock = NULL; - master->lock.file_priv = NULL; - wake_up_interruptible_all(&master->lock.lock_queue); - } - mutex_unlock(&dev->struct_mutex); - - 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); - } - } - - /* drop the master reference held by the file priv */ - if (file_priv->master) - drm_master_put(&file_priv->master); - file_priv->is_master = 0; - mutex_unlock(&dev->master_mutex); + if (drm_is_primary_client(file_priv)) + drm_master_release(file_priv); if (dev->driver->postclose) dev->driver->postclose(dev, file_priv); - if (drm_core_check_feature(dev, DRIVER_PRIME)) drm_prime_destroy_file_private(&file_priv->prime); @@ -797,6 +686,12 @@ void drm_send_event_locked(struct drm_device *dev, struct drm_pending_event *e) { assert_spin_locked(&dev->event_lock); + if (e->completion) { + /* ->completion might disappear as soon as it signalled. */ + complete_all(e->completion); + e->completion = NULL; + } + if (e->fence) { fence_signal(e->fence); fence_put(e->fence);