diff options
author | David Herrmann <dh.herrmann@gmail.com> | 2013-07-27 10:37:00 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2013-08-06 20:14:24 -0400 |
commit | 28ec711cd427f8b61f73712a43b8100ba8ca933b (patch) | |
tree | 1ceebcff67e41b55b570869984a15d62523aa8a7 | |
parent | 08fcd72b14e440feb748ddc33e7057716116a74a (diff) |
drm/agp: move AGP cleanup paths to drm_agpsupport.c
Introduce two new helpers, drm_agp_clear() and drm_agp_destroy() which
clear all AGP mappings and destroy the AGP head. This allows to reduce the
AGP code in core DRM and move it all to drm_agpsupport.c.
Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
-rw-r--r-- | drivers/gpu/drm/drm_agpsupport.c | 51 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_drv.c | 21 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_pci.c | 12 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_stub.c | 9 | ||||
-rw-r--r-- | include/drm/drmP.h | 3 |
5 files changed, 69 insertions, 27 deletions
diff --git a/drivers/gpu/drm/drm_agpsupport.c b/drivers/gpu/drm/drm_agpsupport.c index 3d8fed179797..e301d653d97e 100644 --- a/drivers/gpu/drm/drm_agpsupport.c +++ b/drivers/gpu/drm/drm_agpsupport.c | |||
@@ -424,6 +424,57 @@ struct drm_agp_head *drm_agp_init(struct drm_device *dev) | |||
424 | } | 424 | } |
425 | 425 | ||
426 | /** | 426 | /** |
427 | * drm_agp_clear - Clear AGP resource list | ||
428 | * @dev: DRM device | ||
429 | * | ||
430 | * Iterate over all AGP resources and remove them. But keep the AGP head | ||
431 | * intact so it can still be used. It is safe to call this if AGP is disabled or | ||
432 | * was already removed. | ||
433 | * | ||
434 | * If DRIVER_MODESET is active, nothing is done to protect the modesetting | ||
435 | * resources from getting destroyed. Drivers are responsible of cleaning them up | ||
436 | * during device shutdown. | ||
437 | */ | ||
438 | void drm_agp_clear(struct drm_device *dev) | ||
439 | { | ||
440 | struct drm_agp_mem *entry, *tempe; | ||
441 | |||
442 | if (!drm_core_has_AGP(dev) || !dev->agp) | ||
443 | return; | ||
444 | if (drm_core_check_feature(dev, DRIVER_MODESET)) | ||
445 | return; | ||
446 | |||
447 | list_for_each_entry_safe(entry, tempe, &dev->agp->memory, head) { | ||
448 | if (entry->bound) | ||
449 | drm_unbind_agp(entry->memory); | ||
450 | drm_free_agp(entry->memory, entry->pages); | ||
451 | kfree(entry); | ||
452 | } | ||
453 | INIT_LIST_HEAD(&dev->agp->memory); | ||
454 | |||
455 | if (dev->agp->acquired) | ||
456 | drm_agp_release(dev); | ||
457 | |||
458 | dev->agp->acquired = 0; | ||
459 | dev->agp->enabled = 0; | ||
460 | } | ||
461 | |||
462 | /** | ||
463 | * drm_agp_destroy - Destroy AGP head | ||
464 | * @dev: DRM device | ||
465 | * | ||
466 | * Destroy resources that were previously allocated via drm_agp_initp. Caller | ||
467 | * must ensure to clean up all AGP resources before calling this. See | ||
468 | * drm_agp_clear(). | ||
469 | * | ||
470 | * Call this to destroy AGP heads allocated via drm_agp_init(). | ||
471 | */ | ||
472 | void drm_agp_destroy(struct drm_agp_head *agp) | ||
473 | { | ||
474 | kfree(agp); | ||
475 | } | ||
476 | |||
477 | /** | ||
427 | * Binds a collection of pages into AGP memory at the given offset, returning | 478 | * Binds a collection of pages into AGP memory at the given offset, returning |
428 | * the AGP memory structure containing them. | 479 | * the AGP memory structure containing them. |
429 | * | 480 | * |
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 36103d1660d1..dddd79988ffc 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c | |||
@@ -195,27 +195,8 @@ int drm_lastclose(struct drm_device * dev) | |||
195 | 195 | ||
196 | mutex_lock(&dev->struct_mutex); | 196 | mutex_lock(&dev->struct_mutex); |
197 | 197 | ||
198 | /* Clear AGP information */ | 198 | drm_agp_clear(dev); |
199 | if (drm_core_has_AGP(dev) && dev->agp && | ||
200 | !drm_core_check_feature(dev, DRIVER_MODESET)) { | ||
201 | struct drm_agp_mem *entry, *tempe; | ||
202 | |||
203 | /* Remove AGP resources, but leave dev->agp | ||
204 | intact until drv_cleanup is called. */ | ||
205 | list_for_each_entry_safe(entry, tempe, &dev->agp->memory, head) { | ||
206 | if (entry->bound) | ||
207 | drm_unbind_agp(entry->memory); | ||
208 | drm_free_agp(entry->memory, entry->pages); | ||
209 | kfree(entry); | ||
210 | } | ||
211 | INIT_LIST_HEAD(&dev->agp->memory); | ||
212 | |||
213 | if (dev->agp->acquired) | ||
214 | drm_agp_release(dev); | ||
215 | 199 | ||
216 | dev->agp->acquired = 0; | ||
217 | dev->agp->enabled = 0; | ||
218 | } | ||
219 | if (drm_core_check_feature(dev, DRIVER_SG) && dev->sg && | 200 | if (drm_core_check_feature(dev, DRIVER_SG) && dev->sg && |
220 | !drm_core_check_feature(dev, DRIVER_MODESET)) { | 201 | !drm_core_check_feature(dev, DRIVER_MODESET)) { |
221 | drm_sg_cleanup(dev->sg); | 202 | drm_sg_cleanup(dev->sg); |
diff --git a/drivers/gpu/drm/drm_pci.c b/drivers/gpu/drm/drm_pci.c index a7b46ff80b0f..0f54ad8a9ced 100644 --- a/drivers/gpu/drm/drm_pci.c +++ b/drivers/gpu/drm/drm_pci.c | |||
@@ -283,6 +283,17 @@ static int drm_pci_agp_init(struct drm_device *dev) | |||
283 | return 0; | 283 | return 0; |
284 | } | 284 | } |
285 | 285 | ||
286 | static void drm_pci_agp_destroy(struct drm_device *dev) | ||
287 | { | ||
288 | if (drm_core_has_AGP(dev) && dev->agp) { | ||
289 | if (drm_core_has_MTRR(dev)) | ||
290 | arch_phys_wc_del(dev->agp->agp_mtrr); | ||
291 | drm_agp_clear(dev); | ||
292 | drm_agp_destroy(dev->agp); | ||
293 | dev->agp = NULL; | ||
294 | } | ||
295 | } | ||
296 | |||
286 | static struct drm_bus drm_pci_bus = { | 297 | static struct drm_bus drm_pci_bus = { |
287 | .bus_type = DRIVER_BUS_PCI, | 298 | .bus_type = DRIVER_BUS_PCI, |
288 | .get_irq = drm_pci_get_irq, | 299 | .get_irq = drm_pci_get_irq, |
@@ -291,6 +302,7 @@ static struct drm_bus drm_pci_bus = { | |||
291 | .set_unique = drm_pci_set_unique, | 302 | .set_unique = drm_pci_set_unique, |
292 | .irq_by_busid = drm_pci_irq_by_busid, | 303 | .irq_by_busid = drm_pci_irq_by_busid, |
293 | .agp_init = drm_pci_agp_init, | 304 | .agp_init = drm_pci_agp_init, |
305 | .agp_destroy = drm_pci_agp_destroy, | ||
294 | }; | 306 | }; |
295 | 307 | ||
296 | /** | 308 | /** |
diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c index 327ca19cda85..d663f7d66dab 100644 --- a/drivers/gpu/drm/drm_stub.c +++ b/drivers/gpu/drm/drm_stub.c | |||
@@ -451,16 +451,11 @@ void drm_put_dev(struct drm_device *dev) | |||
451 | 451 | ||
452 | drm_lastclose(dev); | 452 | drm_lastclose(dev); |
453 | 453 | ||
454 | if (drm_core_has_MTRR(dev) && drm_core_has_AGP(dev) && dev->agp) | ||
455 | arch_phys_wc_del(dev->agp->agp_mtrr); | ||
456 | |||
457 | if (dev->driver->unload) | 454 | if (dev->driver->unload) |
458 | dev->driver->unload(dev); | 455 | dev->driver->unload(dev); |
459 | 456 | ||
460 | if (drm_core_has_AGP(dev) && dev->agp) { | 457 | if (dev->driver->bus->agp_destroy) |
461 | kfree(dev->agp); | 458 | dev->driver->bus->agp_destroy(dev); |
462 | dev->agp = NULL; | ||
463 | } | ||
464 | 459 | ||
465 | drm_vblank_cleanup(dev); | 460 | drm_vblank_cleanup(dev); |
466 | 461 | ||
diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 1a4eba627e79..fba547368a20 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h | |||
@@ -736,6 +736,7 @@ struct drm_bus { | |||
736 | int (*irq_by_busid)(struct drm_device *dev, struct drm_irq_busid *p); | 736 | int (*irq_by_busid)(struct drm_device *dev, struct drm_irq_busid *p); |
737 | /* hooks that are for PCI */ | 737 | /* hooks that are for PCI */ |
738 | int (*agp_init)(struct drm_device *dev); | 738 | int (*agp_init)(struct drm_device *dev); |
739 | void (*agp_destroy)(struct drm_device *dev); | ||
739 | 740 | ||
740 | }; | 741 | }; |
741 | 742 | ||
@@ -1453,6 +1454,8 @@ extern int drm_modeset_ctl(struct drm_device *dev, void *data, | |||
1453 | 1454 | ||
1454 | /* AGP/GART support (drm_agpsupport.h) */ | 1455 | /* AGP/GART support (drm_agpsupport.h) */ |
1455 | extern struct drm_agp_head *drm_agp_init(struct drm_device *dev); | 1456 | extern struct drm_agp_head *drm_agp_init(struct drm_device *dev); |
1457 | extern void drm_agp_destroy(struct drm_agp_head *agp); | ||
1458 | extern void drm_agp_clear(struct drm_device *dev); | ||
1456 | extern int drm_agp_acquire(struct drm_device *dev); | 1459 | extern int drm_agp_acquire(struct drm_device *dev); |
1457 | extern int drm_agp_acquire_ioctl(struct drm_device *dev, void *data, | 1460 | extern int drm_agp_acquire_ioctl(struct drm_device *dev, void *data, |
1458 | struct drm_file *file_priv); | 1461 | struct drm_file *file_priv); |