summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/drm_stub.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/drm_stub.c')
-rw-r--r--drivers/gpu/drm/drm_stub.c81
1 files changed, 48 insertions, 33 deletions
diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c
index 26055abf94ee..c200136a5d8e 100644
--- a/drivers/gpu/drm/drm_stub.c
+++ b/drivers/gpu/drm/drm_stub.c
@@ -255,16 +255,20 @@ int drm_dropmaster_ioctl(struct drm_device *dev, void *data,
}
/**
- * Get a secondary minor number.
+ * drm_get_minor - Allocate and register new DRM minor
+ * @dev: DRM device
+ * @minor: Pointer to where new minor is stored
+ * @type: Type of minor
*
- * \param dev device data structure
- * \param sec-minor structure to hold the assigned minor
- * \return negative number on failure.
+ * Allocate a new minor of the given type and register it. A pointer to the new
+ * minor is returned in @minor.
+ * Caller must hold the global DRM mutex.
*
- * Search an empty entry and initialize it to the given parameters. This
- * routines assigns minor numbers to secondary heads of multi-headed cards
+ * RETURNS:
+ * 0 on success, negative error code on failure.
*/
-int drm_get_minor(struct drm_device *dev, struct drm_minor **minor, int type)
+static int drm_get_minor(struct drm_device *dev, struct drm_minor **minor,
+ int type)
{
struct drm_minor *new_minor;
int ret;
@@ -321,37 +325,48 @@ err_idr:
*minor = NULL;
return ret;
}
-EXPORT_SYMBOL(drm_get_minor);
/**
- * Put a secondary minor number.
+ * drm_unplug_minor - Unplug DRM minor
+ * @minor: Minor to unplug
*
- * \param sec_minor - structure to be released
- * \return always zero
+ * Unplugs the given DRM minor but keeps the object. So after this returns,
+ * minor->dev is still valid so existing open-files can still access it to get
+ * device information from their drm_file ojects.
+ * If the minor is already unplugged or if @minor is NULL, nothing is done.
+ * The global DRM mutex must be held by the caller.
*/
-int drm_put_minor(struct drm_minor **minor_p)
+static void drm_unplug_minor(struct drm_minor *minor)
{
- struct drm_minor *minor = *minor_p;
-
- DRM_DEBUG("release secondary minor %d\n", minor->index);
+ if (!minor || !device_is_registered(minor->kdev))
+ return;
#if defined(CONFIG_DEBUG_FS)
drm_debugfs_cleanup(minor);
#endif
drm_sysfs_device_remove(minor);
-
idr_remove(&drm_minors_idr, minor->index);
-
- kfree(minor);
- *minor_p = NULL;
- return 0;
}
-EXPORT_SYMBOL(drm_put_minor);
-static void drm_unplug_minor(struct drm_minor *minor)
+/**
+ * drm_put_minor - Destroy DRM minor
+ * @minor: Minor to destroy
+ *
+ * This calls drm_unplug_minor() on the given minor and then frees it. Nothing
+ * is done if @minor is NULL. It is fine to call this on already unplugged
+ * minors.
+ * The global DRM mutex must be held by the caller.
+ */
+static void drm_put_minor(struct drm_minor *minor)
{
- drm_sysfs_device_remove(minor);
+ if (!minor)
+ return;
+
+ DRM_DEBUG("release secondary minor %d\n", minor->index);
+
+ drm_unplug_minor(minor);
+ kfree(minor);
}
/**
@@ -472,6 +487,10 @@ EXPORT_SYMBOL(drm_dev_alloc);
*/
void drm_dev_free(struct drm_device *dev)
{
+ drm_put_minor(dev->control);
+ drm_put_minor(dev->render);
+ drm_put_minor(dev->primary);
+
if (dev->driver->driver_features & DRIVER_GEM)
drm_gem_destroy(dev);
@@ -547,13 +566,11 @@ err_unload:
if (dev->driver->unload)
dev->driver->unload(dev);
err_primary_node:
- drm_put_minor(&dev->primary);
+ drm_put_minor(dev->primary);
err_render_node:
- if (dev->render)
- drm_put_minor(&dev->render);
+ drm_put_minor(dev->render);
err_control_node:
- if (dev->control)
- drm_put_minor(&dev->control);
+ drm_put_minor(dev->control);
err_agp:
if (dev->driver->bus->agp_destroy)
dev->driver->bus->agp_destroy(dev);
@@ -588,11 +605,9 @@ void drm_dev_unregister(struct drm_device *dev)
list_for_each_entry_safe(r_list, list_temp, &dev->maplist, head)
drm_rmmap(dev, r_list->map);
- if (dev->control)
- drm_put_minor(&dev->control);
- if (dev->render)
- drm_put_minor(&dev->render);
- drm_put_minor(&dev->primary);
+ drm_unplug_minor(dev->control);
+ drm_unplug_minor(dev->render);
+ drm_unplug_minor(dev->primary);
list_del(&dev->driver_item);
}