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>
This commit is contained in:
committed by
Dave Airlie
parent
08fcd72b14
commit
28ec711cd4
@@ -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)
|
|||||||
|
|
||||||
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)
|
|||||||
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 = {
|
|||||||
.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)
|
|||||||
|
|
||||||
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 {
|
|||||||
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,
|
|||||||
|
|
||||||
/* 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);
|
||||||
|
Reference in New Issue
Block a user