drm: cleanup exit path for module unload

The current sub-module unload exit path is a mess, it tries
to abuse the idr. Just keep a list of devices per driver struct
and free them in-order on rmmod.

Signed-off-by: Dave Airlie <airlied@redhat.com>
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 996097a..3cb87a9 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -263,6 +263,8 @@
 
 	DRM_DEBUG("\n");
 
+	INIT_LIST_HEAD(&driver->device_list);
+
 	for (i = 0; driver->pci_driver.id_table[i].vendor != 0; i++) {
 		pid = (struct pci_device_id *)&driver->pci_driver.id_table[i];
 
@@ -334,30 +336,13 @@
 		DRM_ERROR("Cannot unload module\n");
 }
 
-static 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)
 {
+	struct drm_device *dev, *tmp;
 	DRM_DEBUG("\n");
 
-	idr_for_each(&drm_minors_idr, &drm_minors_cleanup, driver);
+	list_for_each_entry_safe(dev, tmp, &driver->device_list, driver_item)
+		drm_cleanup(dev);
 
 	DRM_INFO("Module unloaded\n");
 }
diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c
index 66c96ec..849c0a9 100644
--- a/drivers/gpu/drm/drm_stub.c
+++ b/drivers/gpu/drm/drm_stub.c
@@ -270,6 +270,8 @@
 	if ((ret = drm_get_minor(dev, &dev->primary, DRM_MINOR_LEGACY)))
 		goto err_g2;
 
+	list_add_tail(&dev->driver_item, &driver->device_list);
+
 	DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n",
 		 driver->name, driver->major, driver->minor, driver->patchlevel,
 		 driver->date, dev->primary->index);