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 | |
| 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>
| -rw-r--r-- | drivers/gpu/drm/drm_drv.c | 25 | ||||
| -rw-r--r-- | drivers/gpu/drm/drm_stub.c | 2 | ||||
| -rw-r--r-- | include/drm/drmP.h | 3 |
3 files changed, 10 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 | } |
diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c index 66c96ec66672..849c0a9fe7fd 100644 --- a/drivers/gpu/drm/drm_stub.c +++ b/drivers/gpu/drm/drm_stub.c | |||
| @@ -270,6 +270,8 @@ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent, | |||
| 270 | if ((ret = drm_get_minor(dev, &dev->primary, DRM_MINOR_LEGACY))) | 270 | if ((ret = drm_get_minor(dev, &dev->primary, DRM_MINOR_LEGACY))) |
| 271 | goto err_g2; | 271 | goto err_g2; |
| 272 | 272 | ||
| 273 | list_add_tail(&dev->driver_item, &driver->device_list); | ||
| 274 | |||
| 273 | DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n", | 275 | DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n", |
| 274 | driver->name, driver->major, driver->minor, driver->patchlevel, | 276 | driver->name, driver->major, driver->minor, driver->patchlevel, |
| 275 | driver->date, dev->primary->index); | 277 | driver->date, dev->primary->index); |
diff --git a/include/drm/drmP.h b/include/drm/drmP.h index d5e8e5c89548..08b8539e7b3c 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h | |||
| @@ -737,6 +737,8 @@ struct drm_driver { | |||
| 737 | int num_ioctls; | 737 | int num_ioctls; |
| 738 | struct file_operations fops; | 738 | struct file_operations fops; |
| 739 | struct pci_driver pci_driver; | 739 | struct pci_driver pci_driver; |
| 740 | /* List of devices hanging off this driver */ | ||
| 741 | struct list_head device_list; | ||
| 740 | }; | 742 | }; |
| 741 | 743 | ||
| 742 | #define DRM_MINOR_UNASSIGNED 0 | 744 | #define DRM_MINOR_UNASSIGNED 0 |
| @@ -759,6 +761,7 @@ struct drm_minor { | |||
| 759 | * may contain multiple heads. | 761 | * may contain multiple heads. |
| 760 | */ | 762 | */ |
| 761 | struct drm_device { | 763 | struct drm_device { |
| 764 | struct list_head driver_item; /**< list of devices per driver */ | ||
| 762 | char *unique; /**< Unique identifier: e.g., busid */ | 765 | char *unique; /**< Unique identifier: e.g., busid */ |
| 763 | int unique_len; /**< Length of unique field */ | 766 | int unique_len; /**< Length of unique field */ |
| 764 | char *devname; /**< For /proc/interrupts */ | 767 | char *devname; /**< For /proc/interrupts */ |
