| From 01442c7bcb90339b0abab3caffce62909f3aab2d Mon Sep 17 00:00:00 2001 |
| From: David Herrmann <dh.herrmann@gmail.com> |
| Date: Sat, 27 Jul 2013 16:37:00 +0200 |
| Subject: 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> |
| (cherry picked from commit 28ec711cd427f8b61f73712a43b8100ba8ca933b) |
| Signed-off-by: Darren Hart <dvhart@linux.intel.com> |
| --- |
| drivers/gpu/drm/drm_agpsupport.c | 51 ++++++++++++++++++++++++++++++++++++++++ |
| drivers/gpu/drm/drm_drv.c | 21 +---------------- |
| drivers/gpu/drm/drm_pci.c | 12 ++++++++++ |
| drivers/gpu/drm/drm_stub.c | 9 ++----- |
| include/drm/drmP.h | 3 +++ |
| 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) |
| } |
| |
| /** |
| + * 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. |
| * |
| diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c |
| index 2ab782cb38a2..2994cd7513e9 100644 |
| --- a/drivers/gpu/drm/drm_drv.c |
| +++ b/drivers/gpu/drm/drm_drv.c |
| @@ -194,27 +194,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); |
| - |
| - if (dev->agp->acquired) |
| - drm_agp_release(dev); |
| + drm_agp_clear(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); |
| diff --git a/drivers/gpu/drm/drm_pci.c b/drivers/gpu/drm/drm_pci.c |
| index 80c0b2b29801..382e5bd699c6 100644 |
| --- a/drivers/gpu/drm/drm_pci.c |
| +++ b/drivers/gpu/drm/drm_pci.c |
| @@ -287,6 +287,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, |
| @@ -295,6 +306,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, |
| }; |
| |
| /** |
| diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c |
| index 577786ce9fbc..31442a45dae0 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) |
| |
| 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); |
| |
| diff --git a/include/drm/drmP.h b/include/drm/drmP.h |
| index 0c4bad10e928..bcaf5575c79c 100644 |
| --- a/include/drm/drmP.h |
| +++ b/include/drm/drmP.h |
| @@ -739,6 +739,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); |
| |
| }; |
| |
| @@ -1482,6 +1483,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); |
| -- |
| 1.8.5.rc3 |
| |