From: David Herrmann <dh.herrmann@gmail.com>
Date: Sun, 16 Mar 2014 12:13:51 +0000 (+0100)
Subject: Merge branch 'drm-minor' into drm-next
X-Git-Url: http://git.cdn.openwrt.org/?a=commitdiff_plain;h=07b48c3ac539828d744f0562da1f24e8a234d06e;p=openwrt%2Fstaging%2Fblogic.git

Merge branch 'drm-minor' into drm-next

Fix minor conflicts with drm-anon:
 - allocation/free order
 - drm_device header cleanups
---

07b48c3ac539828d744f0562da1f24e8a234d06e
diff --cc drivers/gpu/drm/drm_fops.c
index 147a84d9da9b,8f46fe273ba3..9b02f126fb0d
--- a/drivers/gpu/drm/drm_fops.c
+++ b/drivers/gpu/drm/drm_fops.c
@@@ -79,29 -79,32 +79,23 @@@ static int drm_setup(struct drm_device 
   */
  int drm_open(struct inode *inode, struct file *filp)
  {
- 	struct drm_device *dev = NULL;
- 	int minor_id = iminor(inode);
+ 	struct drm_device *dev;
  	struct drm_minor *minor;
- 	int retcode = 0;
+ 	int retcode;
  	int need_setup = 0;
 -	struct address_space *old_mapping;
 -	struct address_space *old_imapping;
  
- 	minor = idr_find(&drm_minors_idr, minor_id);
- 	if (!minor)
- 		return -ENODEV;
- 
- 	if (!(dev = minor->dev))
- 		return -ENODEV;
- 
- 	if (drm_device_is_unplugged(dev))
- 		return -ENODEV;
+ 	minor = drm_minor_acquire(iminor(inode));
+ 	if (IS_ERR(minor))
+ 		return PTR_ERR(minor);
  
+ 	dev = minor->dev;
  	if (!dev->open_count++)
  		need_setup = 1;
 -	mutex_lock(&dev->struct_mutex);
 -	old_imapping = inode->i_mapping;
 -	old_mapping = dev->dev_mapping;
 -	if (old_mapping == NULL)
 -		dev->dev_mapping = &inode->i_data;
 -	/* ihold ensures nobody can remove inode with our i_data */
 -	ihold(container_of(dev->dev_mapping, struct inode, i_data));
 -	inode->i_mapping = dev->dev_mapping;
 -	filp->f_mapping = dev->dev_mapping;
 -	mutex_unlock(&dev->struct_mutex);
 +
 +	/* share address_space across all char-devs of a single device */
 +	filp->f_mapping = dev->anon_inode->i_mapping;
  
- 	retcode = drm_open_helper(inode, filp, dev);
+ 	retcode = drm_open_helper(inode, filp, minor);
  	if (retcode)
  		goto err_undo;
  	if (need_setup) {
@@@ -112,7 -115,14 +106,8 @@@
  	return 0;
  
  err_undo:
 -	mutex_lock(&dev->struct_mutex);
 -	filp->f_mapping = old_imapping;
 -	inode->i_mapping = old_imapping;
 -	iput(container_of(dev->dev_mapping, struct inode, i_data));
 -	dev->dev_mapping = old_mapping;
 -	mutex_unlock(&dev->struct_mutex);
  	dev->open_count--;
+ 	drm_minor_release(minor);
  	return retcode;
  }
  EXPORT_SYMBOL(drm_open);
diff --cc drivers/gpu/drm/drm_stub.c
index 04c25cedd4c1,c23eaf6442ff..dc2c6095d850
--- a/drivers/gpu/drm/drm_stub.c
+++ b/drivers/gpu/drm/drm_stub.c
@@@ -526,15 -499,24 +573,31 @@@ struct drm_device *drm_dev_alloc(struc
  	mutex_init(&dev->struct_mutex);
  	mutex_init(&dev->ctxlist_mutex);
  
 +	dev->anon_inode = drm_fs_inode_new();
 +	if (IS_ERR(dev->anon_inode)) {
 +		ret = PTR_ERR(dev->anon_inode);
 +		DRM_ERROR("Cannot allocate anonymous inode: %d\n", ret);
 +		goto err_free;
 +	}
 +
+ 	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
+ 		ret = drm_minor_alloc(dev, DRM_MINOR_CONTROL);
+ 		if (ret)
+ 			goto err_minors;
+ 	}
+ 
+ 	if (drm_core_check_feature(dev, DRIVER_RENDER) && drm_rnodes) {
+ 		ret = drm_minor_alloc(dev, DRM_MINOR_RENDER);
+ 		if (ret)
+ 			goto err_minors;
+ 	}
+ 
+ 	ret = drm_minor_alloc(dev, DRM_MINOR_LEGACY);
+ 	if (ret)
+ 		goto err_minors;
+ 
  	if (drm_ht_create(&dev->map_hash, 12))
- 		goto err_inode;
+ 		goto err_minors;
  
  	ret = drm_ctxbitmap_init(dev);
  	if (ret) {
@@@ -556,9 -538,10 +619,12 @@@ err_ctxbitmap
  	drm_ctxbitmap_cleanup(dev);
  err_ht:
  	drm_ht_remove(&dev->map_hash);
- err_inode:
+ err_minors:
+ 	drm_minor_free(dev, DRM_MINOR_LEGACY);
+ 	drm_minor_free(dev, DRM_MINOR_RENDER);
+ 	drm_minor_free(dev, DRM_MINOR_CONTROL);
 +	drm_fs_inode_free(dev->anon_inode);
 +err_free:
  	kfree(dev);
  	return NULL;
  }
@@@ -585,8 -556,11 +639,12 @@@ static void drm_dev_release(struct kre
  
  	drm_ctxbitmap_cleanup(dev);
  	drm_ht_remove(&dev->map_hash);
 +	drm_fs_inode_free(dev->anon_inode);
  
+ 	drm_minor_free(dev, DRM_MINOR_LEGACY);
+ 	drm_minor_free(dev, DRM_MINOR_RENDER);
+ 	drm_minor_free(dev, DRM_MINOR_CONTROL);
+ 
  	kfree(dev->devname);
  	kfree(dev);
  }
diff --cc include/drm/drmP.h
index 3227b716ffdf,538079030be0..99a17c8a1293
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@@ -1098,6 -1100,19 +1100,19 @@@ struct drm_device 
  	char *devname;			/**< For /proc/interrupts */
  	int if_version;			/**< Highest interface version set */
  
+ 	/** \name Lifetime Management */
+ 	/*@{ */
+ 	struct kref ref;		/**< Object ref-count */
+ 	struct device *dev;		/**< Device structure of bus-device */
+ 	struct drm_driver *driver;	/**< DRM driver managing the device */
+ 	void *dev_private;		/**< DRM driver private data */
 -	struct address_space *dev_mapping;	/**< Private addr-space just for the device */
+ 	struct drm_minor *control;		/**< Control node */
+ 	struct drm_minor *primary;		/**< Primary node */
+ 	struct drm_minor *render;		/**< Render node */
+ 	atomic_t unplugged;			/**< Flag whether dev is dead */
++	struct inode *anon_inode;		/**< inode for private address-space */
+ 	/*@} */
+ 
  	/** \name Locks */
  	/*@{ */
  	spinlock_t count_lock;		/**< For inuse, drm_device::open_count, drm_device::buf_use */