Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+51 −0
Original line number Diff line number Diff line
@@ -423,6 +423,57 @@ struct drm_agp_head *drm_agp_init(struct drm_device *dev)
	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
 * the AGP memory structure containing them.
+1 −20
Original line number Diff line number Diff line
@@ -195,27 +195,8 @@ int drm_lastclose(struct drm_device * dev)

	mutex_lock(&dev->struct_mutex);

	/* Clear AGP information */
	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);
	drm_agp_clear(dev);

		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 &&
	    !drm_core_check_feature(dev, DRIVER_MODESET)) {
		drm_sg_cleanup(dev->sg);
+12 −0
Original line number Diff line number Diff line
@@ -283,6 +283,17 @@ static int drm_pci_agp_init(struct drm_device *dev)
	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 = {
	.bus_type = DRIVER_BUS_PCI,
	.get_irq = drm_pci_get_irq,
@@ -291,6 +302,7 @@ static struct drm_bus drm_pci_bus = {
	.set_unique = drm_pci_set_unique,
	.irq_by_busid = drm_pci_irq_by_busid,
	.agp_init = drm_pci_agp_init,
	.agp_destroy = drm_pci_agp_destroy,
};

/**
+2 −7
Original line number Diff line number Diff line
@@ -451,16 +451,11 @@ void drm_put_dev(struct drm_device *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)
		dev->driver->unload(dev);

	if (drm_core_has_AGP(dev) && dev->agp) {
		kfree(dev->agp);
		dev->agp = NULL;
	}
	if (dev->driver->bus->agp_destroy)
		dev->driver->bus->agp_destroy(dev);

	drm_vblank_cleanup(dev);

+3 −0
Original line number Diff line number Diff line
@@ -736,6 +736,7 @@ struct drm_bus {
	int (*irq_by_busid)(struct drm_device *dev, struct drm_irq_busid *p);
	/* hooks that are for PCI */
	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) */
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_ioctl(struct drm_device *dev, void *data,
				 struct drm_file *file_priv);