diff options
Diffstat (limited to 'drivers/gpu/drm/drm_agpsupport.c')
| -rw-r--r-- | drivers/gpu/drm/drm_agpsupport.c | 62 | 
1 files changed, 46 insertions, 16 deletions
diff --git a/drivers/gpu/drm/drm_agpsupport.c b/drivers/gpu/drm/drm_agpsupport.c index 252fdb98b73..dde205cef38 100644 --- a/drivers/gpu/drm/drm_agpsupport.c +++ b/drivers/gpu/drm/drm_agpsupport.c @@ -31,7 +31,7 @@   * OTHER DEALINGS IN THE SOFTWARE.   */ -#include "drmP.h" +#include <drm/drmP.h>  #include <linux/module.h>  #include <linux/slab.h> @@ -53,7 +53,7 @@   */  int drm_agp_info(struct drm_device *dev, struct drm_agp_info *info)  { -	DRM_AGP_KERN *kern; +	struct agp_kern_info *kern;  	if (!dev->agp || !dev->agp->acquired)  		return -EINVAL; @@ -198,17 +198,15 @@ int drm_agp_enable_ioctl(struct drm_device *dev, void *data,  int drm_agp_alloc(struct drm_device *dev, struct drm_agp_buffer *request)  {  	struct drm_agp_mem *entry; -	DRM_AGP_MEM *memory; +	struct agp_memory *memory;  	unsigned long pages;  	u32 type;  	if (!dev->agp || !dev->agp->acquired)  		return -EINVAL; -	if (!(entry = kmalloc(sizeof(*entry), GFP_KERNEL))) +	if (!(entry = kzalloc(sizeof(*entry), GFP_KERNEL)))  		return -ENOMEM; -	memset(entry, 0, sizeof(*entry)); -  	pages = (request->size + PAGE_SIZE - 1) / PAGE_SIZE;  	type = (u32) request->type;  	if (!(memory = agp_allocate_memory(dev->agp->bridge, pages, type))) { @@ -393,14 +391,16 @@ int drm_agp_free_ioctl(struct drm_device *dev, void *data,   * Gets the drm_agp_t structure which is made available by the agpgart module   * via the inter_module_* functions. Creates and initializes a drm_agp_head   * structure. + * + * Note that final cleanup of the kmalloced structure is directly done in + * drm_pci_agp_destroy.   */  struct drm_agp_head *drm_agp_init(struct drm_device *dev)  {  	struct drm_agp_head *head = NULL; -	if (!(head = kmalloc(sizeof(*head), GFP_KERNEL))) +	if (!(head = kzalloc(sizeof(*head), GFP_KERNEL)))  		return NULL; -	memset((void *)head, 0, sizeof(*head));  	head->bridge = agp_find_bridge(dev->pdev);  	if (!head->bridge) {  		if (!(head->bridge = agp_backend_acquire(dev->pdev))) { @@ -424,20 +424,56 @@ struct drm_agp_head *drm_agp_init(struct drm_device *dev)  }  /** + * 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 (!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; +} + +/**   * Binds a collection of pages into AGP memory at the given offset, returning   * the AGP memory structure containing them.   *   * No reference is held on the pages during this time -- it is up to the   * caller to handle that.   */ -DRM_AGP_MEM * +struct agp_memory *  drm_agp_bind_pages(struct drm_device *dev,  		   struct page **pages,  		   unsigned long num_pages,  		   uint32_t gtt_offset,  		   u32 type)  { -	DRM_AGP_MEM *mem; +	struct agp_memory *mem;  	int ret, i;  	DRM_DEBUG("\n"); @@ -466,10 +502,4 @@ drm_agp_bind_pages(struct drm_device *dev,  }  EXPORT_SYMBOL(drm_agp_bind_pages); -void drm_agp_chipset_flush(struct drm_device *dev) -{ -	agp_flush_chipset(dev->agp->bridge); -} -EXPORT_SYMBOL(drm_agp_chipset_flush); -  #endif /* __OS_HAS_AGP */  | 
