Merge branch 'drm-minor' into drm-next
authorDavid Herrmann <dh.herrmann@gmail.com>
Sun, 16 Mar 2014 12:13:51 +0000 (13:13 +0100)
committerDavid Herrmann <dh.herrmann@gmail.com>
Sun, 16 Mar 2014 12:13:51 +0000 (13:13 +0100)
Fix minor conflicts with drm-anon:
 - allocation/free order
 - drm_device header cleanups

1  2 
drivers/gpu/drm/drm_fops.c
drivers/gpu/drm/drm_stub.c
include/drm/drmP.h

index 147a84d9da9b807f8825cefa0513a574395678d7,8f46fe273ba30be8d778f38bf8ce4b7699e44a8c..9b02f126fb0d9ac1e76a08f573dac7d7f2212fa7
@@@ -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) {
        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);
index 04c25cedd4c19df74ffe80ac3945cbe361cde8b9,c23eaf6442ff95b15c02164805e18de8769fdbdb..dc2c6095d850ea1b285893666ec2565baab9e371
@@@ -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);
  }
index 3227b716ffdf0cd3324805d4d515c83019b76c7f,538079030be04551da6c678dbf4e833007adb11b..99a17c8a1293ba39c31bff496df7638a4f318099
@@@ -1098,6 -1100,19 +1100,19 @@@ struct drm_device 
        char *devname;                  /**< For /proc/interrupts */
        int if_version;                 /**< Highest interface version set */
  
 -      struct address_space *dev_mapping;      /**< Private addr-space just for the device */
+       /** \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 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 */