}
 }
 
+static void drm_minor_alloc_release(struct drm_device *dev, void *data)
+{
+       struct drm_minor *minor = data;
+       unsigned long flags;
+
+       put_device(minor->kdev);
+
+       spin_lock_irqsave(&drm_minor_lock, flags);
+       idr_remove(&drm_minors_idr, minor->index);
+       spin_unlock_irqrestore(&drm_minor_lock, flags);
+}
+
 static int drm_minor_alloc(struct drm_device *dev, unsigned int type)
 {
        struct drm_minor *minor;
        unsigned long flags;
        int r;
 
-       minor = kzalloc(sizeof(*minor), GFP_KERNEL);
+       minor = drmm_kzalloc(dev, sizeof(*minor), GFP_KERNEL);
        if (!minor)
                return -ENOMEM;
 
        idr_preload_end();
 
        if (r < 0)
-               goto err_free;
+               return r;
 
        minor->index = r;
 
+       r = drmm_add_action_or_reset(dev, drm_minor_alloc_release, minor);
+       if (r)
+               return r;
+
        minor->kdev = drm_sysfs_minor_alloc(minor);
-       if (IS_ERR(minor->kdev)) {
-               r = PTR_ERR(minor->kdev);
-               goto err_index;
-       }
+       if (IS_ERR(minor->kdev))
+               return PTR_ERR(minor->kdev);
 
        *drm_minor_get_slot(dev, type) = minor;
        return 0;
-
-err_index:
-       spin_lock_irqsave(&drm_minor_lock, flags);
-       idr_remove(&drm_minors_idr, minor->index);
-       spin_unlock_irqrestore(&drm_minor_lock, flags);
-err_free:
-       kfree(minor);
-       return r;
-}
-
-static void drm_minor_free(struct drm_device *dev, unsigned int type)
-{
-       struct drm_minor **slot, *minor;
-       unsigned long flags;
-
-       slot = drm_minor_get_slot(dev, type);
-       minor = *slot;
-       if (!minor)
-               return;
-
-       put_device(minor->kdev);
-
-       spin_lock_irqsave(&drm_minor_lock, flags);
-       idr_remove(&drm_minors_idr, minor->index);
-       spin_unlock_irqrestore(&drm_minor_lock, flags);
-
-       kfree(minor);
-       *slot = NULL;
 }
 
 static int drm_minor_register(struct drm_device *dev, unsigned int type)
        if (drm_core_check_feature(dev, DRIVER_RENDER)) {
                ret = drm_minor_alloc(dev, DRM_MINOR_RENDER);
                if (ret)
-                       goto err_minors;
+                       goto err;
        }
 
        ret = drm_minor_alloc(dev, DRM_MINOR_PRIMARY);
        if (ret)
-               goto err_minors;
+               goto err;
 
        ret = drm_legacy_create_map_hash(dev);
        if (ret)
-               goto err_minors;
+               goto err;
 
        drm_legacy_ctxbitmap_init(dev);
 
                ret = drm_gem_init(dev);
                if (ret) {
                        DRM_ERROR("Cannot initialize graphics execution manager (GEM)\n");
-                       goto err_ctxbitmap;
+                       goto err;
                }
        }
 
 err_setunique:
        if (drm_core_check_feature(dev, DRIVER_GEM))
                drm_gem_destroy(dev);
-err_ctxbitmap:
-err_minors:
-       drm_minor_free(dev, DRM_MINOR_PRIMARY);
-       drm_minor_free(dev, DRM_MINOR_RENDER);
 err:
        drm_managed_release(dev);
 
 
        if (drm_core_check_feature(dev, DRIVER_GEM))
                drm_gem_destroy(dev);
-
-       drm_minor_free(dev, DRM_MINOR_PRIMARY);
-       drm_minor_free(dev, DRM_MINOR_RENDER);
 }
 EXPORT_SYMBOL(drm_dev_fini);
 
 
                                   drmres_release_t action,
                                   void *data, const char *name);
 
-void drmm_add_final_kfree(struct drm_device *dev, void *parent);
+#define drmm_add_action_or_reset(dev, action, data) \
+       __drmm_add_action_or_reset(dev, action, data, #action)
+
+int __must_check __drmm_add_action_or_reset(struct drm_device *dev,
+                                           drmres_release_t action,
+                                           void *data, const char *name);
+
+void drmm_add_final_kfree(struct drm_device *dev, void *container);
 
 void *drmm_kmalloc(struct drm_device *dev, size_t size, gfp_t gfp) __malloc;
 static inline void *drmm_kzalloc(struct drm_device *dev, size_t size, gfp_t gfp)