From: David Herrmann Date: Sun, 16 Mar 2014 12:13:51 +0000 (+0100) Subject: Merge branch 'drm-minor' into drm-next X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=07b48c3ac539828d744f0562da1f24e8a234d06e;p=linux-beck.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 */