diff options
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/gpu/drm/drm_drv.c | 4 | ||||
| -rw-r--r-- | drivers/gpu/drm/drm_fops.c | 8 | ||||
| -rw-r--r-- | drivers/gpu/drm/drm_gem.c | 3 | ||||
| -rw-r--r-- | drivers/gpu/drm/drm_stub.c | 23 | ||||
| -rw-r--r-- | drivers/gpu/drm/drm_vm.c | 3 | 
5 files changed, 41 insertions, 0 deletions
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index d166bd08040..0b65fbc8a63 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -390,6 +390,10 @@ long drm_ioctl(struct file *filp,  	unsigned int usize, asize;  	dev = file_priv->minor->dev; + +	if (drm_device_is_unplugged(dev)) +		return -ENODEV; +  	atomic_inc(&dev->ioctl_count);  	atomic_inc(&dev->counts[_DRM_STAT_IOCTLS]);  	++file_priv->ioctl_count; diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c index 6263b014759..7348a3dab25 100644 --- a/drivers/gpu/drm/drm_fops.c +++ b/drivers/gpu/drm/drm_fops.c @@ -133,6 +133,9 @@ int drm_open(struct inode *inode, struct file *filp)  	if (!(dev = minor->dev))  		return -ENODEV; +	if (drm_device_is_unplugged(dev)) +		return -ENODEV; +  	retcode = drm_open_helper(inode, filp, dev);  	if (!retcode) {  		atomic_inc(&dev->counts[_DRM_STAT_OPENS]); @@ -181,6 +184,9 @@ int drm_stub_open(struct inode *inode, struct file *filp)  	if (!(dev = minor->dev))  		goto out; +	if (drm_device_is_unplugged(dev)) +		goto out; +  	old_fops = filp->f_op;  	filp->f_op = fops_get(dev->driver->fops);  	if (filp->f_op == NULL) { @@ -579,6 +585,8 @@ int drm_release(struct inode *inode, struct file *filp)  			retcode = -EBUSY;  		} else  			retcode = drm_lastclose(dev); +		if (drm_device_is_unplugged(dev)) +			drm_put_dev(dev);  	}  	mutex_unlock(&drm_global_mutex); diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c index 3ebe3c8f58b..0ef358e5324 100644 --- a/drivers/gpu/drm/drm_gem.c +++ b/drivers/gpu/drm/drm_gem.c @@ -661,6 +661,9 @@ int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma)  	struct drm_hash_item *hash;  	int ret = 0; +	if (drm_device_is_unplugged(dev)) +		return -ENODEV; +  	mutex_lock(&dev->struct_mutex);  	if (drm_ht_find_item(&mm->offset_hash, vma->vm_pgoff, &hash)) { diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c index 6d7b083c5b7..bbd40eaf982 100644 --- a/drivers/gpu/drm/drm_stub.c +++ b/drivers/gpu/drm/drm_stub.c @@ -429,6 +429,11 @@ int drm_put_minor(struct drm_minor **minor_p)  	return 0;  } +static void drm_unplug_minor(struct drm_minor *minor) +{ +	drm_sysfs_device_remove(minor); +} +  /**   * Called via drm_exit() at module unload time or when pci device is   * unplugged. @@ -492,3 +497,21 @@ void drm_put_dev(struct drm_device *dev)  	kfree(dev);  }  EXPORT_SYMBOL(drm_put_dev); + +void drm_unplug_dev(struct drm_device *dev) +{ +	/* for a USB device */ +	if (drm_core_check_feature(dev, DRIVER_MODESET)) +		drm_unplug_minor(dev->control); +	drm_unplug_minor(dev->primary); + +	mutex_lock(&drm_global_mutex); + +	drm_device_set_unplugged(dev); + +	if (dev->open_count == 0) { +		drm_put_dev(dev); +	} +	mutex_unlock(&drm_global_mutex); +} +EXPORT_SYMBOL(drm_unplug_dev); diff --git a/drivers/gpu/drm/drm_vm.c b/drivers/gpu/drm/drm_vm.c index 55cd6156781..14956181834 100644 --- a/drivers/gpu/drm/drm_vm.c +++ b/drivers/gpu/drm/drm_vm.c @@ -680,6 +680,9 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)  	struct drm_device *dev = priv->minor->dev;  	int ret; +	if (drm_device_is_unplugged(dev)) +		return -ENODEV; +  	mutex_lock(&dev->struct_mutex);  	ret = drm_mmap_locked(filp, vma);  	mutex_unlock(&dev->struct_mutex);  |