drm: reorganise minor number handling using backported modesetting code.

rips out the head crap and replaces it with an idr and drm_minor structure

Signed-off-by: Dave Airlie <airlied@redhat.com>
diff --git a/drivers/char/drm/drm_drv.c b/drivers/char/drm/drm_drv.c
index 0e7af53..fc54140 100644
--- a/drivers/char/drm/drm_drv.c
+++ b/drivers/char/drm/drm_drv.c
@@ -313,35 +313,36 @@
 	drm_ht_remove(&dev->map_hash);
 	drm_ctxbitmap_cleanup(dev);
 
-	drm_put_head(&dev->primary);
+	drm_put_minor(&dev->primary);
 	if (drm_put_dev(dev))
 		DRM_ERROR("Cannot unload module\n");
 }
 
+int drm_minors_cleanup(int id, void *ptr, void *data)
+{
+	struct drm_minor *minor = ptr;
+	struct drm_device *dev;
+	struct drm_driver *driver = data;
+
+	dev = minor->dev;
+	if (minor->dev->driver != driver)
+		return 0;
+
+	if (minor->type != DRM_MINOR_LEGACY)
+		return 0;
+
+	if (dev)
+		pci_dev_put(dev->pdev);
+	drm_cleanup(dev);
+	return 1;
+}
+
 void drm_exit(struct drm_driver *driver)
 {
-	int i;
-	struct drm_device *dev = NULL;
-	struct drm_head *head;
-
 	DRM_DEBUG("\n");
 
-	for (i = 0; i < drm_cards_limit; i++) {
-		head = drm_heads[i];
-		if (!head)
-			continue;
-		if (!head->dev)
-			continue;
-		if (head->dev->driver != driver)
-			continue;
-		dev = head->dev;
-		if (dev) {
-			/* release the pci driver */
-			if (dev->pdev)
-				pci_dev_put(dev->pdev);
-			drm_cleanup(dev);
-		}
-	}
+	idr_for_each(&drm_minors_idr, &drm_minors_cleanup, driver);
+
 	DRM_INFO("Module unloaded\n");
 }
 
@@ -357,13 +358,7 @@
 {
 	int ret = -ENOMEM;
 
-	drm_cards_limit =
-	    (drm_cards_limit <
-	     DRM_MAX_MINOR + 1 ? drm_cards_limit : DRM_MAX_MINOR + 1);
-	drm_heads =
-	    drm_calloc(drm_cards_limit, sizeof(*drm_heads), DRM_MEM_STUB);
-	if (!drm_heads)
-		goto err_p1;
+	idr_init(&drm_minors_idr);
 
 	if (register_chrdev(DRM_MAJOR, "drm", &drm_stub_fops))
 		goto err_p1;
@@ -391,7 +386,8 @@
 	drm_sysfs_destroy();
 err_p2:
 	unregister_chrdev(DRM_MAJOR, "drm");
-	drm_free(drm_heads, sizeof(*drm_heads) * drm_cards_limit, DRM_MEM_STUB);
+
+	idr_destroy(&drm_minors_idr);
 err_p1:
 	return ret;
 }
@@ -403,7 +399,7 @@
 
 	unregister_chrdev(DRM_MAJOR, "drm");
 
-	drm_free(drm_heads, sizeof(*drm_heads) * drm_cards_limit, DRM_MEM_STUB);
+	idr_destroy(&drm_minors_idr);
 }
 
 module_init(drm_core_init);
@@ -452,7 +448,7 @@
 	      unsigned int cmd, unsigned long arg)
 {
 	struct drm_file *file_priv = filp->private_data;
-	struct drm_device *dev = file_priv->head->dev;
+	struct drm_device *dev = file_priv->minor->dev;
 	struct drm_ioctl_desc *ioctl;
 	drm_ioctl_t *func;
 	unsigned int nr = DRM_IOCTL_NR(cmd);
@@ -465,7 +461,7 @@
 
 	DRM_DEBUG("pid=%d, cmd=0x%02x, nr=0x%02x, dev 0x%lx, auth=%d\n",
 		  task_pid_nr(current), cmd, nr,
-		  (long)old_encode_dev(file_priv->head->device),
+		  (long)old_encode_dev(file_priv->minor->device),
 		  file_priv->authenticated);
 
 	if ((nr >= DRM_CORE_IOCTL_COUNT) &&