From cc471a361fc7058df4fb8d15d9c9a8b5cdd3dd77 Mon Sep 17 00:00:00 2001 From: David Airlie Date: Fri, 13 Apr 2007 14:33:52 +1000 Subject: i915/drm: clean up a lot of the i915/drm startup/teardown sequences When the kernel driver is loaded it sets up a lot of stuff.. it tears down the same stuff on unload. This add a new map type called DRM_DRIVER which means the driver will clean the mapping up and fix up the map cleaner --- linux-core/drm_bufs.c | 3 ++- linux-core/drm_drv.c | 30 ++++++++++++++---------------- linux-core/drm_stub.c | 1 - linux-core/i915_drv.c | 1 - 4 files changed, 16 insertions(+), 19 deletions(-) (limited to 'linux-core') diff --git a/linux-core/drm_bufs.c b/linux-core/drm_bufs.c index 8793ba0e..1ba53c8f 100644 --- a/linux-core/drm_bufs.c +++ b/linux-core/drm_bufs.c @@ -57,7 +57,7 @@ static drm_map_list_t *drm_find_matching_map(drm_device_t *dev, drm_map_list_t *entry = list_entry(list, drm_map_list_t, head); if (entry->map && map->type == entry->map->type && ((entry->map->offset == map->offset) || - (map->type == _DRM_SHM && map->flags==_DRM_CONTAINS_LOCK))) { + ((map->type == _DRM_SHM) && (map->flags&_DRM_CONTAINS_LOCK)))) { return entry; } } @@ -417,6 +417,7 @@ int drm_rmmap_locked(drm_device_t *dev, drm_local_map_t *map) break; case _DRM_SHM: vfree(map->handle); + dev->sigdata.lock = dev->lock.hw_lock = NULL; /* SHM removed */ break; case _DRM_AGP: case _DRM_SCATTER_GATHER: diff --git a/linux-core/drm_drv.c b/linux-core/drm_drv.c index b7a7aded..7bb8c659 100644 --- a/linux-core/drm_drv.c +++ b/linux-core/drm_drv.c @@ -147,7 +147,7 @@ static drm_ioctl_desc_t drm_ioctls[] = { int drm_lastclose(drm_device_t * dev) { drm_magic_entry_t *pt, *next; - drm_map_list_t *r_list; + drm_map_list_t *r_list, *r_list_tmp; drm_vma_entry_t *vma, *vma_next; int i; @@ -238,10 +238,9 @@ int drm_lastclose(drm_device_t * dev) } if (dev->maplist) { - while (!list_empty(&dev->maplist->head)) { - struct list_head *list = dev->maplist->head.next; - r_list = list_entry(list, drm_map_list_t, head); - drm_rmmap_locked(dev, r_list->map); + list_for_each_entry_safe(r_list, r_list_tmp, &dev->maplist->head, head) { + if (!(r_list->map->flags & _DRM_DRIVER)) + drm_rmmap_locked(dev, r_list->map); } } @@ -265,8 +264,7 @@ int drm_lastclose(drm_device_t * dev) if (drm_core_check_feature(dev, DRIVER_HAVE_DMA)) drm_dma_takedown(dev); - if (dev->lock.hw_lock) { - dev->sigdata.lock = dev->lock.hw_lock = NULL; /* SHM removed */ + if (dev->lock.filp) { dev->lock.filp = NULL; wake_up_interruptible(&dev->lock.lock_queue); } @@ -377,14 +375,6 @@ static void drm_cleanup(drm_device_t * dev) drm_lastclose(dev); drm_fence_manager_takedown(dev); - if (dev->maplist) { - drm_free(dev->maplist, sizeof(*dev->maplist), DRM_MEM_MAPS); - dev->maplist = NULL; - drm_ht_remove(&dev->map_hash); - drm_mm_takedown(&dev->offset_manager); - drm_ht_remove(&dev->object_hash); - } - if (!drm_fb_loaded) pci_disable_device(dev->pdev); @@ -399,7 +389,7 @@ static void drm_cleanup(drm_device_t * dev) DRM_DEBUG("mtrr_del=%d\n", retval); } - drm_bo_driver_finish(dev); + // drm_bo_driver_finish(dev); if (drm_core_has_AGP(dev) && dev->agp) { drm_free(dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS); @@ -408,6 +398,14 @@ static void drm_cleanup(drm_device_t * dev) if (dev->driver->unload) dev->driver->unload(dev); + if (dev->maplist) { + drm_free(dev->maplist, sizeof(*dev->maplist), DRM_MEM_MAPS); + dev->maplist = NULL; + drm_ht_remove(&dev->map_hash); + drm_mm_takedown(&dev->offset_manager); + drm_ht_remove(&dev->object_hash); + } + drm_put_head(&dev->primary); if (drm_put_dev(dev)) DRM_ERROR("Cannot unload module\n"); diff --git a/linux-core/drm_stub.c b/linux-core/drm_stub.c index 13652ebd..417e5095 100644 --- a/linux-core/drm_stub.c +++ b/linux-core/drm_stub.c @@ -132,7 +132,6 @@ static int drm_fill_in_dev(drm_device_t * dev, struct pci_dev *pdev, } } - if (dev->driver->load) if ((retcode = dev->driver->load(dev, ent->driver_data))) goto error_out_unreg; diff --git a/linux-core/i915_drv.c b/linux-core/i915_drv.c index b9e624f9..50ff9771 100644 --- a/linux-core/i915_drv.c +++ b/linux-core/i915_drv.c @@ -80,7 +80,6 @@ static struct drm_driver driver = { DRIVER_IRQ_VBL2, .load = i915_driver_load, .unload = i915_driver_unload, - .firstopen = i915_driver_firstopen, .lastclose = i915_driver_lastclose, .preclose = i915_driver_preclose, .device_is_agp = i915_driver_device_is_agp, -- cgit v1.2.3