From: Michael Werner <werner@mrcoffee.engr.sgi.com>

This patch adds drm support for new multiple agp bridge agpgart api.

Signed-off-by: Mike Werner <werner@sgi.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 25-akpm/drivers/char/drm/drmP.h           |    9 +++++----
 25-akpm/drivers/char/drm/drm_agpsupport.c |   28 ++++++++++++++++------------
 25-akpm/drivers/char/drm/drm_drv.c        |    2 +-
 25-akpm/drivers/char/drm/drm_memory.c     |    4 ++--
 25-akpm/drivers/char/drm/drm_stub.c       |    2 +-
 5 files changed, 25 insertions(+), 20 deletions(-)

diff -puN drivers/char/drm/drm_agpsupport.c~drm-add-support-for-new-multiple-agp-bridge-agpgart-api drivers/char/drm/drm_agpsupport.c
--- 25/drivers/char/drm/drm_agpsupport.c~drm-add-support-for-new-multiple-agp-bridge-agpgart-api	Tue Jan  4 16:28:33 2005
+++ 25-akpm/drivers/char/drm/drm_agpsupport.c	Tue Jan  4 16:28:33 2005
@@ -92,14 +92,13 @@ int drm_agp_acquire(struct inode *inode,
 {
 	drm_file_t	 *priv	 = filp->private_data;
 	drm_device_t	 *dev	 = priv->dev;
-	int              retcode;
 
 	if (!dev->agp)
 		return -ENODEV;
 	if (dev->agp->acquired)
 		return -EBUSY;
-	if ((retcode = agp_backend_acquire()))
-		return retcode;
+	if (!(dev->agp->bridge = agp_backend_acquire(dev->pdev)))
+		return -ENODEV;
 	dev->agp->acquired = 1;
 	return 0;
 }
@@ -123,7 +122,7 @@ int drm_agp_release(struct inode *inode,
 
 	if (!dev->agp || !dev->agp->acquired)
 		return -EINVAL;
-	agp_backend_release();
+	agp_backend_release(dev->agp->bridge);
 	dev->agp->acquired = 0;
 	return 0;
 
@@ -134,9 +133,9 @@ int drm_agp_release(struct inode *inode,
  *
  * Calls agp_backend_release().
  */
-void drm_agp_do_release(void)
+void drm_agp_do_release(drm_device_t *dev)
 {
-  agp_backend_release();
+  agp_backend_release(dev->agp->bridge);
 }
 
 /**
@@ -165,7 +164,7 @@ int drm_agp_enable(struct inode *inode, 
 		return -EFAULT;
 
 	dev->agp->mode    = mode.mode;
-	agp_enable(mode.mode);
+	agp_enable(dev->agp->bridge, mode.mode);
 	dev->agp->base    = dev->agp->agp_info.aper_base;
 	dev->agp->enabled = 1;
 	return 0;
@@ -207,7 +206,7 @@ int drm_agp_alloc(struct inode *inode, s
 	pages = (request.size + PAGE_SIZE - 1) / PAGE_SIZE;
 	type = (u32) request.type;
 
-	if (!(memory = drm_alloc_agp(pages, type))) {
+	if (!(memory = drm_alloc_agp(dev->agp->bridge, pages, type))) {
 		drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
 		return -ENOMEM;
 	}
@@ -381,14 +380,19 @@ int drm_agp_free(struct inode *inode, st
  * \return pointer to a drm_agp_head structure.
  *
  */
-drm_agp_head_t *drm_agp_init(void)
+drm_agp_head_t *drm_agp_init(drm_device_t *dev)
 {
 	drm_agp_head_t *head         = NULL;
 
 	if (!(head = drm_alloc(sizeof(*head), DRM_MEM_AGPLISTS)))
 		return NULL;
 	memset((void *)head, 0, sizeof(*head));
-	agp_copy_info(&head->agp_info);
+	if (!(head->bridge = agp_backend_acquire(dev->pdev))) {
+		drm_free(head, sizeof(*head), DRM_MEM_AGPLISTS);
+		return NULL;
+	}
+	agp_copy_info(head->bridge, &head->agp_info);
+	agp_backend_release(head->bridge);
 	if (head->agp_info.chipset == NOT_SUPPORTED) {
 		drm_free(head, sizeof(*head), DRM_MEM_AGPLISTS);
 		return NULL;
@@ -406,9 +410,9 @@ drm_agp_head_t *drm_agp_init(void)
 }
 
 /** Calls agp_allocate_memory() */
-DRM_AGP_MEM *drm_agp_allocate_memory(size_t pages, u32 type)
+DRM_AGP_MEM *drm_agp_allocate_memory(struct agp_bridge_data *bridge, size_t pages, u32 type)
 {
-	return agp_allocate_memory(pages, type);
+	return agp_allocate_memory(bridge, pages, type);
 }
 
 /** Calls agp_free_memory() */
diff -puN drivers/char/drm/drm_drv.c~drm-add-support-for-new-multiple-agp-bridge-agpgart-api drivers/char/drm/drm_drv.c
--- 25/drivers/char/drm/drm_drv.c~drm-add-support-for-new-multiple-agp-bridge-agpgart-api	Tue Jan  4 16:28:33 2005
+++ 25-akpm/drivers/char/drm/drm_drv.c	Tue Jan  4 16:28:33 2005
@@ -185,7 +185,7 @@ int drm_takedown( drm_device_t *dev )
 		}
 		dev->agp->memory = NULL;
 
-		if ( dev->agp->acquired ) drm_agp_do_release();
+		if ( dev->agp->acquired ) drm_agp_do_release(dev);
 
 		dev->agp->acquired = 0;
 		dev->agp->enabled  = 0;
diff -puN drivers/char/drm/drm_memory.c~drm-add-support-for-new-multiple-agp-bridge-agpgart-api drivers/char/drm/drm_memory.c
--- 25/drivers/char/drm/drm_memory.c~drm-add-support-for-new-multiple-agp-bridge-agpgart-api	Tue Jan  4 16:28:33 2005
+++ 25-akpm/drivers/char/drm/drm_memory.c	Tue Jan  4 16:28:33 2005
@@ -155,9 +155,9 @@ void drm_free_pages(unsigned long addres
 
 #if __OS_HAS_AGP
 /** Wrapper around agp_allocate_memory() */
-DRM_AGP_MEM *drm_alloc_agp(int pages, u32 type)
+DRM_AGP_MEM *drm_alloc_agp(struct agp_bridge_data *bridge, int pages, u32 type)
 {
-	return drm_agp_allocate_memory(pages, type);
+	return drm_agp_allocate_memory(bridge, pages, type);
 }
 
 /** Wrapper around agp_free_memory() */
diff -puN drivers/char/drm/drmP.h~drm-add-support-for-new-multiple-agp-bridge-agpgart-api drivers/char/drm/drmP.h
--- 25/drivers/char/drm/drmP.h~drm-add-support-for-new-multiple-agp-bridge-agpgart-api	Tue Jan  4 16:28:33 2005
+++ 25-akpm/drivers/char/drm/drmP.h	Tue Jan  4 16:28:33 2005
@@ -497,6 +497,7 @@ typedef struct drm_agp_head {
 	DRM_AGP_KERN       agp_info;	/**< AGP device information */
 	drm_agp_mem_t      *memory;	/**< memory entries */
 	unsigned long      mode;	/**< AGP mode */
+	struct agp_bridge_data  *bridge;
 	int                enabled;	/**< whether the AGP bus as been enabled */
 	int                acquired;	/**< whether the AGP device has been acquired */
 	unsigned long      base;
@@ -807,7 +808,7 @@ extern void	     *drm_ioremap_nocache(un
 					   drm_device_t *dev);
 extern void	     drm_ioremapfree(void *pt, unsigned long size, drm_device_t *dev);
 
-extern DRM_AGP_MEM   *drm_alloc_agp(int pages, u32 type);
+extern DRM_AGP_MEM   *drm_alloc_agp(struct agp_bridge_data *bridge, int pages, u32 type);
 extern int           drm_free_agp(DRM_AGP_MEM *handle, int pages);
 extern int           drm_bind_agp(DRM_AGP_MEM *handle, unsigned int start);
 extern int           drm_unbind_agp(DRM_AGP_MEM *handle);
@@ -930,10 +931,10 @@ extern int           drm_vblank_wait(drm
 extern void          drm_vbl_send_signals( drm_device_t *dev );
 
 				/* AGP/GART support (drm_agpsupport.h) */
-extern drm_agp_head_t *drm_agp_init(void);
+extern drm_agp_head_t *drm_agp_init(drm_device_t *dev);
 extern int            drm_agp_acquire(struct inode *inode, struct file *filp,
 				       unsigned int cmd, unsigned long arg);
-extern void           drm_agp_do_release(void);
+extern void           drm_agp_do_release(drm_device_t *dev);
 extern int            drm_agp_release(struct inode *inode, struct file *filp,
 				       unsigned int cmd, unsigned long arg);
 extern int            drm_agp_enable(struct inode *inode, struct file *filp,
@@ -948,7 +949,7 @@ extern int            drm_agp_unbind(str
 				      unsigned int cmd, unsigned long arg);
 extern int            drm_agp_bind(struct inode *inode, struct file *filp,
 				    unsigned int cmd, unsigned long arg);
-extern DRM_AGP_MEM    *drm_agp_allocate_memory(size_t pages, u32 type);
+extern DRM_AGP_MEM    *drm_agp_allocate_memory(struct agp_bridge_data *bridge, size_t pages, u32 type);
 extern int            drm_agp_free_memory(DRM_AGP_MEM *handle);
 extern int            drm_agp_bind_memory(DRM_AGP_MEM *handle, off_t start);
 extern int            drm_agp_unbind_memory(DRM_AGP_MEM *handle);
diff -puN drivers/char/drm/drm_stub.c~drm-add-support-for-new-multiple-agp-bridge-agpgart-api drivers/char/drm/drm_stub.c
--- 25/drivers/char/drm/drm_stub.c~drm-add-support-for-new-multiple-agp-bridge-agpgart-api	Tue Jan  4 16:28:33 2005
+++ 25-akpm/drivers/char/drm/drm_stub.c	Tue Jan  4 16:28:33 2005
@@ -91,7 +91,7 @@ static int drm_fill_in_dev(drm_device_t 
 			goto error_out_unreg;
 
 	if (drm_core_has_AGP(dev)) {
-		dev->agp = drm_agp_init();
+		dev->agp = drm_agp_init(dev);
 		if (drm_core_check_feature(dev, DRIVER_REQUIRE_AGP) && (dev->agp == NULL)) {
 			DRM_ERROR( "Cannot initialize the agpgart module.\n" );
 			retcode = -EINVAL;
_