diff options
author | Dave Airlie <airlied@redhat.com> | 2008-11-27 22:43:47 -0500 |
---|---|---|
committer | Dave Airlie <airlied@linux.ie> | 2008-12-29 02:47:21 -0500 |
commit | e7f7ab45ebcb54fd5f814ea15ea079e079662f67 (patch) | |
tree | 53e8206501c0b7a00831ea084b52664f7899d1c0 /drivers/gpu/drm/drm_drv.c | |
parent | 4a6908a3a050aacc9c3a2f36b276b46c0629ad91 (diff) |
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>
Diffstat (limited to 'drivers/gpu/drm/drm_drv.c')
-rw-r--r-- | drivers/gpu/drm/drm_drv.c | 25 |
1 files changed, 5 insertions, 20 deletions
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 996097acb5e7..3cb87a932b33 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c | |||
@@ -263,6 +263,8 @@ int drm_init(struct drm_driver *driver) | |||
263 | 263 | ||
264 | DRM_DEBUG("\n"); | 264 | DRM_DEBUG("\n"); |
265 | 265 | ||
266 | INIT_LIST_HEAD(&driver->device_list); | ||
267 | |||
266 | for (i = 0; driver->pci_driver.id_table[i].vendor != 0; i++) { | 268 | for (i = 0; driver->pci_driver.id_table[i].vendor != 0; i++) { |
267 | pid = (struct pci_device_id *)&driver->pci_driver.id_table[i]; | 269 | pid = (struct pci_device_id *)&driver->pci_driver.id_table[i]; |
268 | 270 | ||
@@ -334,30 +336,13 @@ static void drm_cleanup(struct drm_device * dev) | |||
334 | DRM_ERROR("Cannot unload module\n"); | 336 | DRM_ERROR("Cannot unload module\n"); |
335 | } | 337 | } |
336 | 338 | ||
337 | static int drm_minors_cleanup(int id, void *ptr, void *data) | ||
338 | { | ||
339 | struct drm_minor *minor = ptr; | ||
340 | struct drm_device *dev; | ||
341 | struct drm_driver *driver = data; | ||
342 | |||
343 | dev = minor->dev; | ||
344 | if (minor->dev->driver != driver) | ||
345 | return 0; | ||
346 | |||
347 | if (minor->type != DRM_MINOR_LEGACY) | ||
348 | return 0; | ||
349 | |||
350 | if (dev) | ||
351 | pci_dev_put(dev->pdev); | ||
352 | drm_cleanup(dev); | ||
353 | return 1; | ||
354 | } | ||
355 | |||
356 | void drm_exit(struct drm_driver *driver) | 339 | void drm_exit(struct drm_driver *driver) |
357 | { | 340 | { |
341 | struct drm_device *dev, *tmp; | ||
358 | DRM_DEBUG("\n"); | 342 | DRM_DEBUG("\n"); |
359 | 343 | ||
360 | idr_for_each(&drm_minors_idr, &drm_minors_cleanup, driver); | 344 | list_for_each_entry_safe(dev, tmp, &driver->device_list, driver_item) |
345 | drm_cleanup(dev); | ||
361 | 346 | ||
362 | DRM_INFO("Module unloaded\n"); | 347 | DRM_INFO("Module unloaded\n"); |
363 | } | 348 | } |