Commit 28ec711c authored by David Herrmann's avatar David Herrmann Committed by Dave Airlie

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: default avatarDavid Herrmann <dh.herrmann@gmail.com>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent 08fcd72b
...@@ -423,6 +423,57 @@ struct drm_agp_head *drm_agp_init(struct drm_device *dev) ...@@ -423,6 +423,57 @@ struct drm_agp_head *drm_agp_init(struct drm_device *dev)
return head; return head;
} }
/**
* drm_agp_clear - Clear AGP resource list
* @dev: DRM device
*
* Iterate over all AGP resources and remove them. But keep the AGP head
* intact so it can still be used. It is safe to call this if AGP is disabled or
* was already removed.
*
* If DRIVER_MODESET is active, nothing is done to protect the modesetting
* resources from getting destroyed. Drivers are responsible of cleaning them up
* during device shutdown.
*/
void drm_agp_clear(struct drm_device *dev)
{
struct drm_agp_mem *entry, *tempe;
if (!drm_core_has_AGP(dev) || !dev->agp)
return;
if (drm_core_check_feature(dev, DRIVER_MODESET))
return;
list_for_each_entry_safe(entry, tempe, &dev->agp->memory, head) {
if (entry->bound)
drm_unbind_agp(entry->memory);
drm_free_agp(entry->memory, entry->pages);
kfree(entry);
}
INIT_LIST_HEAD(&dev->agp->memory);
if (dev->agp->acquired)
drm_agp_release(dev);
dev->agp->acquired = 0;
dev->agp->enabled = 0;
}
/**
* drm_agp_destroy - Destroy AGP head
* @dev: DRM device
*
* Destroy resources that were previously allocated via drm_agp_initp. Caller
* must ensure to clean up all AGP resources before calling this. See
* drm_agp_clear().
*
* Call this to destroy AGP heads allocated via drm_agp_init().
*/
void drm_agp_destroy(struct drm_agp_head *agp)
{
kfree(agp);
}
/** /**
* Binds a collection of pages into AGP memory at the given offset, returning * Binds a collection of pages into AGP memory at the given offset, returning
* the AGP memory structure containing them. * the AGP memory structure containing them.
......
...@@ -195,27 +195,8 @@ int drm_lastclose(struct drm_device * dev) ...@@ -195,27 +195,8 @@ int drm_lastclose(struct drm_device * dev)
mutex_lock(&dev->struct_mutex); mutex_lock(&dev->struct_mutex);
/* Clear AGP information */ drm_agp_clear(dev);
if (drm_core_has_AGP(dev) && dev->agp &&
!drm_core_check_feature(dev, DRIVER_MODESET)) {
struct drm_agp_mem *entry, *tempe;
/* Remove AGP resources, but leave dev->agp
intact until drv_cleanup is called. */
list_for_each_entry_safe(entry, tempe, &dev->agp->memory, head) {
if (entry->bound)
drm_unbind_agp(entry->memory);
drm_free_agp(entry->memory, entry->pages);
kfree(entry);
}
INIT_LIST_HEAD(&dev->agp->memory);
if (dev->agp->acquired)
drm_agp_release(dev);
dev->agp->acquired = 0;
dev->agp->enabled = 0;
}
if (drm_core_check_feature(dev, DRIVER_SG) && dev->sg && if (drm_core_check_feature(dev, DRIVER_SG) && dev->sg &&
!drm_core_check_feature(dev, DRIVER_MODESET)) { !drm_core_check_feature(dev, DRIVER_MODESET)) {
drm_sg_cleanup(dev->sg); drm_sg_cleanup(dev->sg);
......
...@@ -283,6 +283,17 @@ static int drm_pci_agp_init(struct drm_device *dev) ...@@ -283,6 +283,17 @@ static int drm_pci_agp_init(struct drm_device *dev)
return 0; return 0;
} }
static void drm_pci_agp_destroy(struct drm_device *dev)
{
if (drm_core_has_AGP(dev) && dev->agp) {
if (drm_core_has_MTRR(dev))
arch_phys_wc_del(dev->agp->agp_mtrr);
drm_agp_clear(dev);
drm_agp_destroy(dev->agp);
dev->agp = NULL;
}
}
static struct drm_bus drm_pci_bus = { static struct drm_bus drm_pci_bus = {
.bus_type = DRIVER_BUS_PCI, .bus_type = DRIVER_BUS_PCI,
.get_irq = drm_pci_get_irq, .get_irq = drm_pci_get_irq,
...@@ -291,6 +302,7 @@ static struct drm_bus drm_pci_bus = { ...@@ -291,6 +302,7 @@ static struct drm_bus drm_pci_bus = {
.set_unique = drm_pci_set_unique, .set_unique = drm_pci_set_unique,
.irq_by_busid = drm_pci_irq_by_busid, .irq_by_busid = drm_pci_irq_by_busid,
.agp_init = drm_pci_agp_init, .agp_init = drm_pci_agp_init,
.agp_destroy = drm_pci_agp_destroy,
}; };
/** /**
......
...@@ -451,16 +451,11 @@ void drm_put_dev(struct drm_device *dev) ...@@ -451,16 +451,11 @@ void drm_put_dev(struct drm_device *dev)
drm_lastclose(dev); drm_lastclose(dev);
if (drm_core_has_MTRR(dev) && drm_core_has_AGP(dev) && dev->agp)
arch_phys_wc_del(dev->agp->agp_mtrr);
if (dev->driver->unload) if (dev->driver->unload)
dev->driver->unload(dev); dev->driver->unload(dev);
if (drm_core_has_AGP(dev) && dev->agp) { if (dev->driver->bus->agp_destroy)
kfree(dev->agp); dev->driver->bus->agp_destroy(dev);
dev->agp = NULL;
}
drm_vblank_cleanup(dev); drm_vblank_cleanup(dev);
......
...@@ -736,6 +736,7 @@ struct drm_bus { ...@@ -736,6 +736,7 @@ struct drm_bus {
int (*irq_by_busid)(struct drm_device *dev, struct drm_irq_busid *p); int (*irq_by_busid)(struct drm_device *dev, struct drm_irq_busid *p);
/* hooks that are for PCI */ /* hooks that are for PCI */
int (*agp_init)(struct drm_device *dev); int (*agp_init)(struct drm_device *dev);
void (*agp_destroy)(struct drm_device *dev);
}; };
...@@ -1453,6 +1454,8 @@ extern int drm_modeset_ctl(struct drm_device *dev, void *data, ...@@ -1453,6 +1454,8 @@ extern int drm_modeset_ctl(struct drm_device *dev, void *data,
/* AGP/GART support (drm_agpsupport.h) */ /* AGP/GART support (drm_agpsupport.h) */
extern struct drm_agp_head *drm_agp_init(struct drm_device *dev); extern struct drm_agp_head *drm_agp_init(struct drm_device *dev);
extern void drm_agp_destroy(struct drm_agp_head *agp);
extern void drm_agp_clear(struct drm_device *dev);
extern int drm_agp_acquire(struct drm_device *dev); extern int drm_agp_acquire(struct drm_device *dev);
extern int drm_agp_acquire_ioctl(struct drm_device *dev, void *data, extern int drm_agp_acquire_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv); struct drm_file *file_priv);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment