diff -urpN --exclude-from=/home/davej/.exclude compile-fix/drivers/char/agp/agp.h agpgart/drivers/char/agp/agp.h
--- compile-fix/drivers/char/agp/agp.h	2003-01-15 16:00:20.000000000 -0100
+++ agpgart/drivers/char/agp/agp.h	2003-01-15 15:59:22.000000000 -0100
@@ -32,30 +32,8 @@
 
 extern struct agp_bridge_data agp_bridge;
 
-/* Generic routines. */
-void agp_generic_agp_enable(u32 mode);
-int agp_generic_agp_3_0_enable(u32 mode);
-int agp_generic_create_gatt_table(void);
-int agp_generic_free_gatt_table(void);
-agp_memory *agp_create_memory(int scratch_pages);
-int agp_generic_insert_memory(agp_memory * mem, off_t pg_start, int type);
-int agp_generic_remove_memory(agp_memory * mem, off_t pg_start, int type);
-agp_memory *agp_generic_alloc_by_type(size_t page_count, int type);
-void agp_generic_free_by_type(agp_memory * curr);
-void *agp_generic_alloc_page(void);
-void agp_generic_destroy_page(void *addr);
-int agp_generic_suspend(void);
-void agp_generic_resume(void);
-void agp_free_key(int key);
-int agp_num_entries(void);
-u32 agp_collect_device_status(u32 mode, u32 command);
-void agp_device_command(u32 command, int agp_v3);
-
 #define PFX "agpgart: "
 
-int agp_register_driver (struct pci_dev *dev);
-int agp_unregister_driver(void);
-
 #ifdef CONFIG_SMP
 static void ipi_handler(void *null)
 {
@@ -387,6 +365,11 @@ struct agp_bridge_info {
 	struct agp_device_ids *ids;
 };
 
+struct agp_driver {
+	struct module *owner;
+	struct pci_dev *dev;
+};
+
 extern struct agp_bridge_info ali_agp_bridge_info;
 extern struct agp_bridge_info amd_k8_agp_bridge_info;
 extern struct agp_bridge_info amd_agp_bridge_info;
@@ -395,4 +378,25 @@ extern struct agp_bridge_info sis_agp_br
 extern struct agp_bridge_info via_agp_bridge_info;
 extern struct agp_bridge_info hp_agp_bridge_info;
 
+/* Generic routines. */
+void agp_generic_agp_enable(u32 mode);
+int agp_generic_agp_3_0_enable(u32 mode);
+int agp_generic_create_gatt_table(void);
+int agp_generic_free_gatt_table(void);
+agp_memory *agp_create_memory(int scratch_pages);
+int agp_generic_insert_memory(agp_memory * mem, off_t pg_start, int type);
+int agp_generic_remove_memory(agp_memory * mem, off_t pg_start, int type);
+agp_memory *agp_generic_alloc_by_type(size_t page_count, int type);
+void agp_generic_free_by_type(agp_memory * curr);
+void *agp_generic_alloc_page(void);
+void agp_generic_destroy_page(void *addr);
+int agp_generic_suspend(void);
+void agp_generic_resume(void);
+void agp_free_key(int key);
+int agp_num_entries(void);
+int agp_register_driver (struct agp_driver *drv);
+int agp_unregister_driver(struct agp_driver *drv);
+u32 agp_collect_device_status(u32 mode, u32 command);
+void agp_device_command(u32 command, int agp_v3);
+
 #endif				/* _AGP_BACKEND_PRIV_H */
diff -urpN --exclude-from=/home/davej/.exclude compile-fix/drivers/char/agp/ali-agp.c agpgart/drivers/char/agp/ali-agp.c
--- compile-fix/drivers/char/agp/ali-agp.c	2003-01-15 16:00:20.000000000 -0100
+++ agpgart/drivers/char/agp/ali-agp.c	2003-01-15 15:59:22.000000000 -0100
@@ -336,6 +336,9 @@ static int __init agp_lookup_host_bridge
 	return -ENODEV;
 }
 
+static struct agp_driver ali_agp_driver = {
+	.owner = THIS_MODULE,
+};
 
 static int __init agp_ali_probe (struct pci_dev *dev, const struct pci_device_id *ent)
 {
@@ -351,7 +354,8 @@ static int __init agp_ali_probe (struct 
 		agp_bridge.capndx = cap_ptr;
 		/* Fill in the mode register */
 		pci_read_config_dword(agp_bridge.dev, agp_bridge.capndx+PCI_AGP_STATUS, &agp_bridge.mode);
-		agp_register_driver(dev);
+		ali_agp_driver.dev = dev;
+		agp_register_driver(&ali_agp_driver);
 		return 0;
 	}
 	return -ENODEV;	
@@ -390,7 +394,7 @@ static int __init agp_ali_init(void)
 
 static void __exit agp_ali_cleanup(void)
 {
-	agp_unregister_driver();
+	agp_unregister_driver(&ali_agp_driver);
 	pci_unregister_driver(&agp_ali_pci_driver);
 }
 
diff -urpN --exclude-from=/home/davej/.exclude compile-fix/drivers/char/agp/amd-k7-agp.c agpgart/drivers/char/agp/amd-k7-agp.c
--- compile-fix/drivers/char/agp/amd-k7-agp.c	2003-01-15 16:00:20.000000000 -0100
+++ agpgart/drivers/char/agp/amd-k7-agp.c	2003-01-15 15:59:22.000000000 -0100
@@ -440,6 +440,10 @@ static int __init agp_lookup_host_bridge
 }
 
 
+static struct agp_driver amd_k7_agp_driver = {
+	.owner = THIS_MODULE,
+};
+
 /* Supported Device Scanning routine */
 
 static int __init agp_amdk7_probe (struct pci_dev *dev, const struct pci_device_id *ent)
@@ -455,7 +459,8 @@ static int __init agp_amdk7_probe (struc
 		agp_bridge.capndx = cap_ptr;
 		/* Fill in the mode register */
 		pci_read_config_dword(agp_bridge.dev, agp_bridge.capndx+PCI_AGP_STATUS, &agp_bridge.mode);
-		agp_register_driver(dev);
+		amd_k7_agp_driver.dev = dev;
+		agp_register_driver(&amd_k7_agp_driver);
 		return 0;
 	}
 	return -ENODEV;
@@ -494,7 +499,7 @@ static int __init agp_amdk7_init(void)
 
 static void __exit agp_amdk7_cleanup(void)
 {
-	agp_unregister_driver();
+	agp_unregister_driver(&amd_k7_agp_driver);
 	pci_unregister_driver(&agp_amdk7_pci_driver);
 }
 
diff -urpN --exclude-from=/home/davej/.exclude compile-fix/drivers/char/agp/amd-k8-agp.c agpgart/drivers/char/agp/amd-k8-agp.c
--- compile-fix/drivers/char/agp/amd-k8-agp.c	2003-01-15 16:00:20.000000000 -0100
+++ agpgart/drivers/char/agp/amd-k8-agp.c	2003-01-15 15:59:22.000000000 -0100
@@ -408,6 +408,9 @@ static int __init amd_8151_setup (struct
 	return 0;
 }
 
+static struct agp_driver amd_k8_agp_driver = {
+	.owner = THIS_MODULE,
+};
 
 static int __init agp_amdk8_probe (struct pci_dev *dev, const struct pci_device_id *ent)
 {
@@ -423,7 +426,8 @@ static int __init agp_amdk8_probe (struc
 	/* Fill in the mode register */
 	pci_read_config_dword(agp_bridge.dev, agp_bridge.capndx+PCI_AGP_STATUS, &agp_bridge.mode);
 	amd_8151_setup(dev);
-	agp_register_driver(dev);
+	amd_k8_agp_driver.dev = dev;
+	agp_register_driver(&amd_k8_agp_driver);
 	return 0;
 }
 
@@ -463,7 +467,7 @@ int __init agp_amdk8_init(void)
 
 static void __exit agp_amdk8_cleanup(void)
 {
-	agp_unregister_driver();
+	agp_unregister_driver(&amd_k8_agp_driver);
 	pci_unregister_driver(&agp_amdk8_pci_driver);
 }
 
diff -urpN --exclude-from=/home/davej/.exclude compile-fix/drivers/char/agp/backend.c agpgart/drivers/char/agp/backend.c
--- compile-fix/drivers/char/agp/backend.c	2003-01-15 16:00:21.000000000 -0100
+++ agpgart/drivers/char/agp/backend.c	2003-01-15 15:59:22.000000000 -0100
@@ -219,36 +219,48 @@ static const drm_agp_t drm_agp = {
 
 static int agp_count=0;
 
-int agp_register_driver (struct pci_dev *dev)
+int agp_register_driver (struct agp_driver *drv)
 {
 	int ret_val;
 
+	if (drv->dev == NULL) {
+		printk (KERN_DEBUG PFX "Erk, registering with no pci_dev!\n");
+		return -EINVAL;
+	}
+
 	if (agp_count==1) {
 		printk (KERN_DEBUG PFX "Only one agpgart device currently supported.\n");
 		return -ENODEV;
 	}
 
-	ret_val = agp_backend_initialize(dev);
-	if (ret_val) {
-		agp_bridge.type = NOT_SUPPORTED;
-		return ret_val;
-	}
+	/* Grab reference on the chipset driver. */
+	if (!try_module_get(drv->owner))
+		return -EINVAL;
+
+	ret_val = agp_backend_initialize(drv->dev);
+	if (ret_val)
+		goto err_out;
+
 	ret_val = agp_frontend_initialize();
-	if (ret_val) {
-		agp_bridge.type = NOT_SUPPORTED;
-		agp_backend_cleanup();
-		return ret_val;
-	}
+	if (ret_val)
+		goto frontend_err;
 
+	/* FIXME: What to do with this? */
 	inter_module_register("drm_agp", THIS_MODULE, &drm_agp);
 
 	pm_register(PM_PCI_DEV, PM_PCI_ID(agp_bridge.dev), agp_power);
-
 	agp_count++;
 	return 0;
+
+frontend_err:
+	agp_backend_cleanup();
+err_out:
+	agp_bridge.type = NOT_SUPPORTED;
+	module_put(drv->owner);
+	return ret_val;
 }
 
-int agp_unregister_driver(void)
+int agp_unregister_driver(struct agp_driver *drv)
 {
 	agp_bridge.type = NOT_SUPPORTED;
 	pm_unregister_all(agp_power);
@@ -256,6 +268,7 @@ int agp_unregister_driver(void)
 	agp_backend_cleanup();
 	inter_module_unregister("drm_agp");
 	agp_count--;
+	module_put(drv->owner);
 	return 0;
 }
 
diff -urpN --exclude-from=/home/davej/.exclude compile-fix/drivers/char/agp/generic.c agpgart/drivers/char/agp/generic.c
--- compile-fix/drivers/char/agp/generic.c	2003-01-15 16:00:21.000000000 -0100
+++ agpgart/drivers/char/agp/generic.c	2003-01-15 15:59:22.000000000 -0100
@@ -116,7 +116,6 @@ void agp_free_memory(agp_memory * curr)
 	agp_free_key(curr->key);
 	vfree(curr->memory);
 	kfree(curr);
-	MOD_DEC_USE_COUNT;
 }
 
 #define ENTRIES_PER_PAGE		(PAGE_SIZE / sizeof(unsigned long))
@@ -138,17 +137,12 @@ agp_memory *agp_allocate_memory(size_t p
 		return new;
 	}
 
-	/* We always increase the module count, since free auto-decrements it */
-	MOD_INC_USE_COUNT;
-
 	scratch_pages = (page_count + ENTRIES_PER_PAGE - 1) / ENTRIES_PER_PAGE;
 
 	new = agp_create_memory(scratch_pages);
 
-	if (new == NULL) {
-		MOD_DEC_USE_COUNT;
+	if (new == NULL)
 		return NULL;
-	}
 
 	for (i = 0; i < page_count; i++) {
 		void *addr = agp_bridge.agp_alloc_page();
diff -urpN --exclude-from=/home/davej/.exclude compile-fix/drivers/char/agp/hp-agp.c agpgart/drivers/char/agp/hp-agp.c
--- compile-fix/drivers/char/agp/hp-agp.c	2003-01-15 16:00:21.000000000 -0100
+++ agpgart/drivers/char/agp/hp-agp.c	2003-01-15 15:59:22.000000000 -0100
@@ -368,10 +368,15 @@ static int __init agp_find_supported_dev
 	return -ENODEV;
 }
 
+static struct agp_driver hp_agp_driver = {
+	.owner = THIS_MODULE;
+};
+
 static int __init agp_hp_probe (struct pci_dev *dev, const struct pci_device_id *ent)
 {
 	if (agp_find_supported_device(dev) == 0) {
-		agp_register_driver(dev);
+		hp_agp_driver.dev = dev;
+		agp_register_driver(&hp_agp_driver);
 		return 0;
 	}
 	return -ENODEV;
@@ -410,7 +415,7 @@ static int __init agp_hp_init(void)
 
 static void __exit agp_hp_cleanup(void)
 {
-	agp_unregister_driver();
+	agp_unregister_driver(&hp_agp_driver);
 	pci_unregister_driver(&agp_hp_pci_driver);
 }
 
diff -urpN --exclude-from=/home/davej/.exclude compile-fix/drivers/char/agp/i460-agp.c agpgart/drivers/char/agp/i460-agp.c
--- compile-fix/drivers/char/agp/i460-agp.c	2003-01-15 16:00:21.000000000 -0100
+++ agpgart/drivers/char/agp/i460-agp.c	2003-01-15 15:59:22.000000000 -0100
@@ -559,6 +559,10 @@ static int __init intel_i460_setup (stru
 	return 0;
 }
 
+static struct agp_driver i460_agp_driver = {
+	.owner = THIS_MODULE;
+};
+
 static int __init agp_intel_i460_probe (struct pci_dev *dev, const struct pci_device_id *ent)
 {
 	u8 cap_ptr = 0;
@@ -570,7 +574,8 @@ static int __init agp_intel_i460_probe (
 	agp_bridge.dev = dev;
 	agp_bridge.capndx = cap_ptr;
 	intel_i460_setup(dev);
-	agp_register_driver(dev);
+	i460_agp_driver.dev = dev;
+	agp_register_driver(&i460_agp_driver);
 	return 0;
 }
 
@@ -607,7 +612,7 @@ static int __init agp_intel_i460_init(vo
 
 static void __exit agp_intel_i460_cleanup(void)
 {
-	agp_unregister_driver();
+	agp_unregister_driver(&i460_agp_driver);
 	pci_unregister_driver(&agp_intel_i460_pci_driver);
 }
 
diff -urpN --exclude-from=/home/davej/.exclude compile-fix/drivers/char/agp/i7x05-agp.c agpgart/drivers/char/agp/i7x05-agp.c
--- compile-fix/drivers/char/agp/i7x05-agp.c	2003-01-15 16:00:21.000000000 -0100
+++ agpgart/drivers/char/agp/i7x05-agp.c	2003-01-15 15:59:22.000000000 -0100
@@ -164,6 +164,9 @@ static int __init agp_lookup_host_bridge
 	return -ENODEV;
 }
 
+static struct agp_driver i7x05_agp_driver = {
+	.owner = THIS_MODULE;
+};
 
 static int __init agp_i7x05_probe (struct pci_dev *dev, const struct pci_device_id *ent)
 {
@@ -178,7 +181,8 @@ static int __init agp_i7x05_probe (struc
 		agp_bridge.capndx = cap_ptr;
 		/* Fill in the mode register */
 		pci_read_config_dword(agp_bridge.dev, agp_bridge.capndx+PCI_AGP_STATUS, &agp_bridge.mode)
-		agp_register_driver(dev);
+		i7x05_agp_driver.dev = dev;
+		agp_register_driver(&i7x05_agp_driver);
 		return 0;
 	}
 	return -ENODEV;
@@ -218,7 +222,7 @@ int __init agp_i7x05_init(void)
 
 static void __exit agp_i7x05_cleanup(void)
 {
-	agp_unregister_driver();
+	agp_unregister_driver(&i7x05_agp_driver);
 	pci_unregister_driver(&agp_i7x05_pci_driver);
 }
 
diff -urpN --exclude-from=/home/davej/.exclude compile-fix/drivers/char/agp/intel-agp.c agpgart/drivers/char/agp/intel-agp.c
--- compile-fix/drivers/char/agp/intel-agp.c	2003-01-15 16:00:21.000000000 -0100
+++ agpgart/drivers/char/agp/intel-agp.c	2003-01-15 15:59:22.000000000 -0100
@@ -195,7 +195,6 @@ static agp_memory *intel_i810_alloc_by_t
 		new->page_count = pg_count;
 		new->num_scratch_pages = 0;
 		vfree(new->memory);
-		MOD_INC_USE_COUNT;
 		return new;
 	}
 	if(type == AGP_PHYS_MEMORY) {
@@ -212,7 +211,6 @@ static agp_memory *intel_i810_alloc_by_t
 		if (new == NULL)
 			return NULL;
 
-		MOD_INC_USE_COUNT;
 		addr = agp_bridge.agp_alloc_page();
 
 		if (addr == NULL) {
@@ -238,7 +236,6 @@ static void intel_i810_free_by_type(agp_
 		vfree(curr->memory);
 	}
 	kfree(curr);
-	MOD_DEC_USE_COUNT;
 }
 
 static unsigned long intel_i810_mask_memory(unsigned long addr, int type)
@@ -507,7 +504,6 @@ static agp_memory *intel_i830_alloc_by_t
 
 		if (nw == NULL) return(NULL);
 
-		MOD_INC_USE_COUNT;
 		addr = agp_bridge.agp_alloc_page();
 		if (addr == NULL) {
 			/* free this structure */
@@ -1429,11 +1425,15 @@ static int __init agp_find_supported_dev
 	return agp_lookup_host_bridge(dev);
 }
 
+static struct agp_driver intel_agp_driver = {
+	.owner = THIS_MODULE,
+};
 
 static int __init agp_intel_probe (struct pci_dev *dev, const struct pci_device_id *ent)
 {
 	if (agp_find_supported_device(dev) == 0) {
-		agp_register_driver(dev);
+		intel_agp_driver.dev = dev;	
+		agp_register_driver(&intel_agp_driver);
 		return 0;
 	}
 	return -ENODEV;	
@@ -1479,7 +1479,7 @@ int __init agp_intel_init(void)
 
 static void __exit agp_intel_cleanup(void)
 {
-	agp_unregister_driver();
+	agp_unregister_driver(&intel_agp_driver);
 	pci_unregister_driver(&agp_intel_pci_driver);
 }
 
diff -urpN --exclude-from=/home/davej/.exclude compile-fix/drivers/char/agp/sis-agp.c agpgart/drivers/char/agp/sis-agp.c
--- compile-fix/drivers/char/agp/sis-agp.c	2003-01-15 16:00:21.000000000 -0100
+++ agpgart/drivers/char/agp/sis-agp.c	2003-01-15 15:59:22.000000000 -0100
@@ -221,6 +221,9 @@ static int __init agp_lookup_host_bridge
 	return -ENODEV;
 }
 
+static struct agp_driver sis_agp_driver = {
+	.owner = THIS_MODULE,
+};
 
 static int __init agp_sis_probe (struct pci_dev *dev, const struct pci_device_id *ent)
 {
@@ -236,7 +239,8 @@ static int __init agp_sis_probe (struct 
 		agp_bridge.capndx = cap_ptr;
 		/* Fill in the mode register */
 		pci_read_config_dword(agp_bridge.dev, agp_bridge.capndx+PCI_AGP_STATUS, &agp_bridge.mode);
-		agp_register_driver(dev);
+		sis_agp_driver.dev = dev;
+		agp_register_driver(&sis_agp_driver);
 		return 0;
 	}
 	return -ENODEV;
@@ -275,7 +279,7 @@ static int __init agp_sis_init(void)
 
 static void __exit agp_sis_cleanup(void)
 {
-	agp_unregister_driver();
+	agp_unregister_driver(&sis_agp_driver);
 	pci_unregister_driver(&agp_sis_pci_driver);
 }
 
diff -urpN --exclude-from=/home/davej/.exclude compile-fix/drivers/char/agp/sworks-agp.c agpgart/drivers/char/agp/sworks-agp.c
--- compile-fix/drivers/char/agp/sworks-agp.c	2003-01-15 16:00:21.000000000 -0100
+++ agpgart/drivers/char/agp/sworks-agp.c	2003-01-15 15:59:22.000000000 -0100
@@ -525,11 +525,15 @@ static int __init agp_find_supported_dev
 	return -ENODEV;
 }
 
+static struct agp_driver serverworks_agp_driver = {
+	.owner = THIS_MODULE,
+};
 
 static int __init agp_serverworks_probe (struct pci_dev *dev, const struct pci_device_id *ent)
 {
 	if (agp_find_supported_device(dev) == 0) {
-		agp_register_driver(dev);
+		serverworks_agp_driver.dev = dev;
+		agp_register_driver(&serverworks_agp_driver);
 		return 0;
 	}
 	return -ENODEV;	
@@ -568,7 +572,7 @@ static int __init agp_serverworks_init(v
 
 static void __exit agp_serverworks_cleanup(void)
 {
-	agp_unregister_driver();
+	agp_unregister_driver(&serverworks_agp_driver);
 	pci_unregister_driver(&agp_serverworks_pci_driver);
 }
 
diff -urpN --exclude-from=/home/davej/.exclude compile-fix/drivers/char/agp/via-agp.c agpgart/drivers/char/agp/via-agp.c
--- compile-fix/drivers/char/agp/via-agp.c	2003-01-15 16:00:21.000000000 -0100
+++ agpgart/drivers/char/agp/via-agp.c	2003-01-15 15:59:22.000000000 -0100
@@ -244,6 +244,9 @@ static int __init agp_lookup_host_bridge
 	return -ENODEV;
 }
 
+static struct agp_driver via_agp_driver = {
+	.owner = THIS_MODULE,
+};
 
 static int __init agp_via_probe (struct pci_dev *dev, const struct pci_device_id *ent)
 {
@@ -259,7 +262,8 @@ static int __init agp_via_probe (struct 
 		agp_bridge.capndx = cap_ptr;
 		/* Fill in the mode register */
 		pci_read_config_dword(agp_bridge.dev, agp_bridge.capndx+PCI_AGP_STATUS, &agp_bridge.mode);
-		agp_register_driver(dev);
+		via_agp_driver.dev = dev;
+		agp_register_driver(&via_agp_driver);
 		return 0;
 	}
 	return -ENODEV;	
@@ -298,7 +302,7 @@ static int __init agp_via_init(void)
 
 static void __exit agp_via_cleanup(void)
 {
-	agp_unregister_driver();
+	agp_unregister_driver(&via_agp_driver);
 	pci_unregister_driver(&agp_via_pci_driver);
 }
 
diff -urpN --exclude-from=/home/davej/.exclude compile-fix/drivers/char/agp/via-kt400.c agpgart/drivers/char/agp/via-kt400.c
--- compile-fix/drivers/char/agp/via-kt400.c	2003-01-15 16:00:21.000000000 -0100
+++ agpgart/drivers/char/agp/via-kt400.c	2003-01-15 15:59:22.000000000 -0100
@@ -100,6 +100,9 @@ static void __init via_kt400_enable(u32 
 		printk (KERN_INFO PFX "agp_generic_agp_3_0_enable() failed\n");
 }
 
+static struct agp_driver via_kt400_agp_driver = {
+	.owner = THIS_MODULE,
+};
 
 static int __init agp_via_probe (struct pci_dev *dev, const struct pci_device_id *ent)
 {
@@ -149,7 +152,8 @@ static int __init agp_via_probe (struct 
 	/* Fill in the mode register */
 	pci_read_config_dword(agp_bridge.dev, agp_bridge.capndx+PCI_AGP_STATUS, &agp_bridge.mode);
 
-	agp_register_driver(dev);
+	via_kt400_agp_driver.dev = dev;
+	agp_register_driver(&via_kt400_agp_driver);
 	return 0;
 }
 
@@ -186,7 +190,7 @@ static int __init agp_via_init(void)
 
 static void __exit agp_via_cleanup(void)
 {
-	agp_unregister_driver();
+	agp_unregister_driver(&via_kt400_agp_driver);
 	pci_unregister_driver(&agp_via_pci_driver);
 }