aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Herrmann <dh.herrmann@gmail.com>2013-07-27 10:37:00 -0400
committerDave Airlie <airlied@redhat.com>2013-08-06 20:14:24 -0400
commit28ec711cd427f8b61f73712a43b8100ba8ca933b (patch)
tree1ceebcff67e41b55b570869984a15d62523aa8a7
parent08fcd72b14e440feb748ddc33e7057716116a74a (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.c51
-rw-r--r--drivers/gpu/drm/drm_drv.c21
-rw-r--r--drivers/gpu/drm/drm_pci.c12
-rw-r--r--drivers/gpu/drm/drm_stub.c9
-rw-r--r--include/drm/drmP.h3
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 */
438void 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 */
472void 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
286static 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
286static struct drm_bus drm_pci_bus = { 297static 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) */
1455extern struct drm_agp_head *drm_agp_init(struct drm_device *dev); 1456extern struct drm_agp_head *drm_agp_init(struct drm_device *dev);
1457extern void drm_agp_destroy(struct drm_agp_head *agp);
1458extern void drm_agp_clear(struct drm_device *dev);
1456extern int drm_agp_acquire(struct drm_device *dev); 1459extern int drm_agp_acquire(struct drm_device *dev);
1457extern int drm_agp_acquire_ioctl(struct drm_device *dev, void *data, 1460extern int drm_agp_acquire_ioctl(struct drm_device *dev, void *data,
1458 struct drm_file *file_priv); 1461 struct drm_file *file_priv);