summary refs log tree commit diff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/char/drm/drmP.h31
-rw-r--r--drivers/char/drm/drm_drv.c29
-rw-r--r--drivers/char/drm/drm_fops.c35
-rw-r--r--drivers/char/drm/drm_ioctl.c12
-rw-r--r--drivers/char/drm/drm_stub.c15
-rw-r--r--drivers/char/drm/i810_dma.c18
-rw-r--r--drivers/char/drm/i810_drv.c59
-rw-r--r--drivers/char/drm/i810_drv.h10
-rw-r--r--drivers/char/drm/i830_dma.c18
-rw-r--r--drivers/char/drm/i830_drv.c56
-rw-r--r--drivers/char/drm/i830_drv.h8
-rw-r--r--drivers/char/drm/i915_dma.c16
-rw-r--r--drivers/char/drm/i915_drv.c54
-rw-r--r--drivers/char/drm/i915_drv.h5
-rw-r--r--drivers/char/drm/mga_dma.c14
-rw-r--r--drivers/char/drm/mga_drv.c56
-rw-r--r--drivers/char/drm/mga_drv.h6
-rw-r--r--drivers/char/drm/r128_drv.c48
-rw-r--r--drivers/char/drm/r128_drv.h4
-rw-r--r--drivers/char/drm/r128_state.c4
-rw-r--r--drivers/char/drm/radeon_cp.c9
-rw-r--r--drivers/char/drm/radeon_drv.c57
-rw-r--r--drivers/char/drm/radeon_drv.h17
-rw-r--r--drivers/char/drm/radeon_state.c8
-rw-r--r--drivers/char/drm/savage_bci.c44
-rw-r--r--drivers/char/drm/savage_drv.c50
-rw-r--r--drivers/char/drm/savage_drv.h6
-rw-r--r--drivers/char/drm/sis_drv.c42
-rw-r--r--drivers/char/drm/tdfx_drv.c42
-rw-r--r--drivers/char/drm/via_drv.c41
30 files changed, 330 insertions, 484 deletions
diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h
index 3dc3c9d79ae4..d842cce11448 100644
--- a/drivers/char/drm/drmP.h
+++ b/drivers/char/drm/drmP.h
@@ -544,16 +544,14 @@ typedef struct ati_pcigart_info {
 struct drm_device;
 
 struct drm_driver {
-	int (*preinit) (struct drm_device *, unsigned long flags);
-	void (*prerelease) (struct drm_device *, struct file * filp);
-	void (*pretakedown) (struct drm_device *);
-	int (*postcleanup) (struct drm_device *);
-	int (*presetup) (struct drm_device *);
-	int (*postsetup) (struct drm_device *);
+	int (*load) (struct drm_device *, unsigned long flags);
+	int (*firstopen) (struct drm_device *);
+	int (*open) (struct drm_device *, drm_file_t *);
+	void (*preclose) (struct drm_device *, struct file * filp);
+	void (*postclose) (struct drm_device *, drm_file_t *);
+	void (*lastclose) (struct drm_device *);
+	int (*unload) (struct drm_device *);
 	int (*dma_ioctl) (DRM_IOCTL_ARGS);
-	int (*open_helper) (struct drm_device *, drm_file_t *);
-	void (*free_filp_priv) (struct drm_device *, drm_file_t *);
-	void (*release) (struct drm_device *, struct file * filp);
 	void (*dma_ready) (struct drm_device *);
 	int (*dma_quiescent) (struct drm_device *);
 	int (*context_ctor) (struct drm_device * dev, int context);
@@ -579,16 +577,25 @@ struct drm_driver {
 
 	/* these have to be filled in */
 
-	int (*postinit) (struct drm_device *, unsigned long flags);
-	 irqreturn_t(*irq_handler) (DRM_IRQ_ARGS);
+	irqreturn_t(*irq_handler) (DRM_IRQ_ARGS);
 	void (*irq_preinstall) (struct drm_device * dev);
 	void (*irq_postinstall) (struct drm_device * dev);
 	void (*irq_uninstall) (struct drm_device * dev);
 	void (*reclaim_buffers) (struct drm_device * dev, struct file * filp);
+	void (*reclaim_buffers_locked) (struct drm_device *drv,
+					struct file *filp);
 	unsigned long (*get_map_ofs) (drm_map_t * map);
 	unsigned long (*get_reg_ofs) (struct drm_device * dev);
 	void (*set_version) (struct drm_device * dev, drm_set_version_t * sv);
 	int (*version) (drm_version_t * version);
+
+	int major;
+	int minor;
+	int patchlevel;
+	char *name;
+	char *desc;
+	char *date;
+
 	u32 driver_features;
 	int dev_priv_size;
 	drm_ioctl_desc_t *ioctls;
@@ -772,7 +779,7 @@ extern int drm_ioctl(struct inode *inode, struct file *filp,
 		     unsigned int cmd, unsigned long arg);
 extern long drm_compat_ioctl(struct file *filp,
 			     unsigned int cmd, unsigned long arg);
-extern int drm_takedown(drm_device_t * dev);
+extern int drm_lastclose(drm_device_t *dev);
 
 				/* Device support (drm_fops.h) */
 extern int drm_open(struct inode *inode, struct file *filp);
diff --git a/drivers/char/drm/drm_drv.c b/drivers/char/drm/drm_drv.c
index 4dff7554eb08..d8ff84bdc3e7 100644
--- a/drivers/char/drm/drm_drv.c
+++ b/drivers/char/drm/drm_drv.c
@@ -129,7 +129,7 @@ static drm_ioctl_desc_t drm_ioctls[] = {
  *
  * \sa drm_device
  */
-int drm_takedown(drm_device_t * dev)
+int drm_lastclose(drm_device_t * dev)
 {
 	drm_magic_entry_t *pt, *next;
 	drm_map_list_t *r_list;
@@ -138,9 +138,9 @@ int drm_takedown(drm_device_t * dev)
 
 	DRM_DEBUG("\n");
 
-	if (dev->driver->pretakedown)
-		dev->driver->pretakedown(dev);
-	DRM_DEBUG("driver pretakedown completed\n");
+	if (dev->driver->lastclose)
+		dev->driver->lastclose(dev);
+	DRM_DEBUG("driver lastclose completed\n");
 
 	if (dev->unique) {
 		drm_free(dev->unique, strlen(dev->unique) + 1, DRM_MEM_DRIVER);
@@ -233,7 +233,7 @@ int drm_takedown(drm_device_t * dev)
 	}
 	up(&dev->struct_sem);
 
-	DRM_DEBUG("takedown completed\n");
+	DRM_DEBUG("lastclose completed\n");
 	return 0;
 }
 
@@ -281,7 +281,7 @@ EXPORT_SYMBOL(drm_init);
 /**
  * Called via cleanup_module() at module unload time.
  *
- * Cleans up all DRM device, calling takedown().
+ * Cleans up all DRM device, calling drm_lastclose().
  *
  * \sa drm_init
  */
@@ -294,7 +294,7 @@ static void drm_cleanup(drm_device_t * dev)
 		return;
 	}
 
-	drm_takedown(dev);
+	drm_lastclose(dev);
 
 	if (dev->maplist) {
 		drm_free(dev->maplist, sizeof(*dev->maplist), DRM_MEM_MAPS);
@@ -317,8 +317,8 @@ static void drm_cleanup(drm_device_t * dev)
 		dev->agp = NULL;
 	}
 
-	if (dev->driver->postcleanup)
-		dev->driver->postcleanup(dev);
+	if (dev->driver->unload)
+		dev->driver->unload(dev);
 
 	drm_put_head(&dev->primary);
 	if (drm_put_dev(dev))
@@ -432,14 +432,17 @@ static int drm_version(struct inode *inode, struct file *filp,
 	drm_device_t *dev = priv->head->dev;
 	drm_version_t __user *argp = (void __user *)arg;
 	drm_version_t version;
-	int ret;
+	int len;
 
 	if (copy_from_user(&version, argp, sizeof(version)))
 		return -EFAULT;
 
-	/* version is a required function to return the personality module version */
-	if ((ret = dev->driver->version(&version)))
-		return ret;
+	version.version_major = dev->driver->major;
+	version.version_minor = dev->driver->minor;
+	version.version_patchlevel = dev->driver->patchlevel;
+	DRM_COPY(version.name, dev->driver->name);
+	DRM_COPY(version.date, dev->driver->date);
+	DRM_COPY(version.desc, dev->driver->desc);
 
 	if (copy_to_user(argp, &version, sizeof(version)))
 		return -EFAULT;
diff --git a/drivers/char/drm/drm_fops.c b/drivers/char/drm/drm_fops.c
index bf0a740122bf..f57f7d1a281e 100644
--- a/drivers/char/drm/drm_fops.c
+++ b/drivers/char/drm/drm_fops.c
@@ -45,8 +45,8 @@ static int drm_setup(drm_device_t * dev)
 	int i;
 	int ret;
 
-	if (dev->driver->presetup) {
-		ret = dev->driver->presetup(dev);
+	if (dev->driver->firstopen) {
+		ret = dev->driver->firstopen(dev);
 		if (ret != 0)
 			return ret;
 	}
@@ -109,8 +109,6 @@ static int drm_setup(drm_device_t * dev)
 	 * drm_select_queue fails between the time the interrupt is
 	 * initialized and the time the queues are initialized.
 	 */
-	if (dev->driver->postsetup)
-		dev->driver->postsetup(dev);
 
 	return 0;
 }
@@ -167,7 +165,7 @@ EXPORT_SYMBOL(drm_open);
  * If the hardware lock is held then free it, and take it again for the kernel
  * context since it's necessary to reclaim buffers. Unlink the file private
  * data from its list and free it. Decreases the open count and if it reaches
- * zero calls takedown().
+ * zero calls drm_lastclose().
  */
 int drm_release(struct inode *inode, struct file *filp)
 {
@@ -180,8 +178,8 @@ int drm_release(struct inode *inode, struct file *filp)
 
 	DRM_DEBUG("open_count = %d\n", dev->open_count);
 
-	if (dev->driver->prerelease)
-		dev->driver->prerelease(dev, filp);
+	if (dev->driver->preclose)
+		dev->driver->preclose(dev, filp);
 
 	/* ========================================================
 	 * Begin inline drm_release
@@ -197,8 +195,8 @@ int drm_release(struct inode *inode, struct file *filp)
 		DRM_DEBUG("File %p released, freeing lock for context %d\n",
 			  filp, _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock));
 
-		if (dev->driver->release)
-			dev->driver->release(dev, filp);
+		if (dev->driver->reclaim_buffers_locked)
+			dev->driver->reclaim_buffers_locked(dev, filp);
 
 		drm_lock_free(dev, &dev->lock.hw_lock->lock,
 			      _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock));
@@ -207,7 +205,7 @@ int drm_release(struct inode *inode, struct file *filp)
 		   hardware at this point, possibly
 		   processed via a callback to the X
 		   server. */
-	} else if (dev->driver->release && priv->lock_count
+	} else if (dev->driver->reclaim_buffers_locked && priv->lock_count
 		   && dev->lock.hw_lock) {
 		/* The lock is required to reclaim buffers */
 		DECLARE_WAITQUEUE(entry, current);
@@ -237,15 +235,14 @@ int drm_release(struct inode *inode, struct file *filp)
 		__set_current_state(TASK_RUNNING);
 		remove_wait_queue(&dev->lock.lock_queue, &entry);
 		if (!retcode) {
-			if (dev->driver->release)
-				dev->driver->release(dev, filp);
+			dev->driver->reclaim_buffers_locked(dev, filp);
 			drm_lock_free(dev, &dev->lock.hw_lock->lock,
 				      DRM_KERNEL_CONTEXT);
 		}
 	}
 
-	if (drm_core_check_feature(dev, DRIVER_HAVE_DMA)
-	    && !dev->driver->release) {
+	if (drm_core_check_feature(dev, DRIVER_HAVE_DMA) &&
+	    !dev->driver->reclaim_buffers_locked) {
 		dev->driver->reclaim_buffers(dev, filp);
 	}
 
@@ -292,8 +289,8 @@ int drm_release(struct inode *inode, struct file *filp)
 	}
 	up(&dev->struct_sem);
 
-	if (dev->driver->free_filp_priv)
-		dev->driver->free_filp_priv(dev, priv);
+	if (dev->driver->postclose)
+		dev->driver->postclose(dev, priv);
 
 	drm_free(priv, sizeof(*priv), DRM_MEM_FILES);
 
@@ -313,7 +310,7 @@ int drm_release(struct inode *inode, struct file *filp)
 		}
 		spin_unlock(&dev->count_lock);
 		unlock_kernel();
-		return drm_takedown(dev);
+		return drm_lastclose(dev);
 	}
 	spin_unlock(&dev->count_lock);
 
@@ -363,8 +360,8 @@ static int drm_open_helper(struct inode *inode, struct file *filp,
 	priv->authenticated = capable(CAP_SYS_ADMIN);
 	priv->lock_count = 0;
 
-	if (dev->driver->open_helper) {
-		ret = dev->driver->open_helper(dev, priv);
+	if (dev->driver->open) {
+		ret = dev->driver->open(dev, priv);
 		if (ret < 0)
 			goto out_free;
 	}
diff --git a/drivers/char/drm/drm_ioctl.c b/drivers/char/drm/drm_ioctl.c
index 9b0feba6b063..a654ac17a900 100644
--- a/drivers/char/drm/drm_ioctl.c
+++ b/drivers/char/drm/drm_ioctl.c
@@ -325,17 +325,13 @@ int drm_setversion(DRM_IOCTL_ARGS)
 	drm_set_version_t retv;
 	int if_version;
 	drm_set_version_t __user *argp = (void __user *)data;
-	drm_version_t version;
 
 	DRM_COPY_FROM_USER_IOCTL(sv, argp, sizeof(sv));
 
-	memset(&version, 0, sizeof(version));
-
-	dev->driver->version(&version);
 	retv.drm_di_major = DRM_IF_MAJOR;
 	retv.drm_di_minor = DRM_IF_MINOR;
-	retv.drm_dd_major = version.version_major;
-	retv.drm_dd_minor = version.version_minor;
+	retv.drm_dd_major = dev->driver->major;
+	retv.drm_dd_minor = dev->driver->minor;
 
 	DRM_COPY_TO_USER_IOCTL(argp, retv, sizeof(sv));
 
@@ -354,9 +350,9 @@ int drm_setversion(DRM_IOCTL_ARGS)
 	}
 
 	if (sv.drm_dd_major != -1) {
-		if (sv.drm_dd_major != version.version_major ||
+		if (sv.drm_dd_major != dev->driver->major ||
 		    sv.drm_dd_minor < 0
-		    || sv.drm_dd_minor > version.version_minor)
+		    || sv.drm_dd_minor > dev->driver->minor)
 			return EINVAL;
 
 		if (dev->driver->set_version)
diff --git a/drivers/char/drm/drm_stub.c b/drivers/char/drm/drm_stub.c
index 60b6f8e8bf69..8568a6b373a0 100644
--- a/drivers/char/drm/drm_stub.c
+++ b/drivers/char/drm/drm_stub.c
@@ -93,8 +93,8 @@ static int drm_fill_in_dev(drm_device_t * dev, struct pci_dev *pdev,
 
 	dev->driver = driver;
 
-	if (dev->driver->preinit)
-		if ((retcode = dev->driver->preinit(dev, ent->driver_data)))
+	if (dev->driver->load)
+		if ((retcode = dev->driver->load(dev, ent->driver_data)))
 			goto error_out_unreg;
 
 	if (drm_core_has_AGP(dev)) {
@@ -124,7 +124,7 @@ static int drm_fill_in_dev(drm_device_t * dev, struct pci_dev *pdev,
 	return 0;
 
       error_out_unreg:
-	drm_takedown(dev);
+	drm_lastclose(dev);
 	return retcode;
 }
 
@@ -258,11 +258,10 @@ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
 	}
 	if ((ret = drm_get_head(dev, &dev->primary)))
 		goto err_g1;
-
-	/* postinit is a required function to display the signon banner */
-	/* drivers add secondary heads here if needed */
-	if ((ret = dev->driver->postinit(dev, ent->driver_data)))
-		goto err_g1;
+	
+	DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n",
+		 driver->name, driver->major, driver->minor, driver->patchlevel,
+		 driver->date, dev->primary.minor);
 
 	return 0;
 
diff --git a/drivers/char/drm/i810_dma.c b/drivers/char/drm/i810_dma.c
index dba502373da1..c3178a89615d 100644
--- a/drivers/char/drm/i810_dma.c
+++ b/drivers/char/drm/i810_dma.c
@@ -1319,12 +1319,24 @@ static int i810_flip_bufs(struct inode *inode, struct file *filp,
 	return 0;
 }
 
-void i810_driver_pretakedown(drm_device_t * dev)
+int i810_driver_load(drm_device_t *dev, unsigned long flags)
+{
+	/* i810 has 4 more counters */
+	dev->counters += 4;
+	dev->types[6] = _DRM_STAT_IRQ;
+	dev->types[7] = _DRM_STAT_PRIMARY;
+	dev->types[8] = _DRM_STAT_SECONDARY;
+	dev->types[9] = _DRM_STAT_DMA;
+
+	return 0;
+}
+
+void i810_driver_lastclose(drm_device_t * dev)
 {
 	i810_dma_cleanup(dev);
 }
 
-void i810_driver_prerelease(drm_device_t * dev, DRMFILE filp)
+void i810_driver_preclose(drm_device_t * dev, DRMFILE filp)
 {
 	if (dev->dev_private) {
 		drm_i810_private_t *dev_priv = dev->dev_private;
@@ -1334,7 +1346,7 @@ void i810_driver_prerelease(drm_device_t * dev, DRMFILE filp)
 	}
 }
 
-void i810_driver_release(drm_device_t * dev, struct file *filp)
+void i810_driver_reclaim_buffers_locked(drm_device_t * dev, struct file *filp)
 {
 	i810_reclaim_buffers(dev, filp);
 }
diff --git a/drivers/char/drm/i810_drv.c b/drivers/char/drm/i810_drv.c
index 070cef6c2b46..e73b731c3be9 100644
--- a/drivers/char/drm/i810_drv.c
+++ b/drivers/char/drm/i810_drv.c
@@ -38,38 +38,6 @@
 
 #include "drm_pciids.h"
 
-static int postinit(struct drm_device *dev, unsigned long flags)
-{
-	/* i810 has 4 more counters */
-	dev->counters += 4;
-	dev->types[6] = _DRM_STAT_IRQ;
-	dev->types[7] = _DRM_STAT_PRIMARY;
-	dev->types[8] = _DRM_STAT_SECONDARY;
-	dev->types[9] = _DRM_STAT_DMA;
-
-	DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n",
-		 DRIVER_NAME,
-		 DRIVER_MAJOR,
-		 DRIVER_MINOR,
-		 DRIVER_PATCHLEVEL,
-		 DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev)
-	    );
-	return 0;
-}
-
-static int version(drm_version_t * version)
-{
-	int len;
-
-	version->version_major = DRIVER_MAJOR;
-	version->version_minor = DRIVER_MINOR;
-	version->version_patchlevel = DRIVER_PATCHLEVEL;
-	DRM_COPY(version->name, DRIVER_NAME);
-	DRM_COPY(version->date, DRIVER_DATE);
-	DRM_COPY(version->desc, DRIVER_DESC);
-	return 0;
-}
-
 static struct pci_device_id pciidlist[] = {
 	i810_PCI_IDS
 };
@@ -79,16 +47,15 @@ static struct drm_driver driver = {
 	    DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR |
 	    DRIVER_HAVE_DMA | DRIVER_DMA_QUEUE,
 	.dev_priv_size = sizeof(drm_i810_buf_priv_t),
-	.pretakedown = i810_driver_pretakedown,
-	.prerelease = i810_driver_prerelease,
+	.load = i810_driver_load,
+	.lastclose = i810_driver_lastclose,
+	.preclose = i810_driver_preclose,
 	.device_is_agp = i810_driver_device_is_agp,
-	.release = i810_driver_release,
+	.reclaim_buffers_locked = i810_driver_reclaim_buffers_locked,
 	.dma_quiescent = i810_driver_dma_quiescent,
 	.reclaim_buffers = i810_reclaim_buffers,
 	.get_map_ofs = drm_core_get_map_ofs,
 	.get_reg_ofs = drm_core_get_reg_ofs,
-	.postinit = postinit,
-	.version = version,
 	.ioctls = i810_ioctls,
 	.fops = {
 		 .owner = THIS_MODULE,
@@ -98,13 +65,19 @@ static struct drm_driver driver = {
 		 .mmap = drm_mmap,
 		 .poll = drm_poll,
 		 .fasync = drm_fasync,
-		 }
-	,
+	},
+
 	.pci_driver = {
-		       .name = DRIVER_NAME,
-		       .id_table = pciidlist,
-		       }
-	,
+		 .name = DRIVER_NAME,
+		 .id_table = pciidlist,
+	},
+
+	.name = DRIVER_NAME,
+	.desc = DRIVER_DESC,
+	.date = DRIVER_DATE,
+	.major = DRIVER_MAJOR,
+	.minor = DRIVER_MINOR,
+	.patchlevel = DRIVER_PATCHLEVEL,
 };
 
 static int __init i810_init(void)
diff --git a/drivers/char/drm/i810_drv.h b/drivers/char/drm/i810_drv.h
index c78f36aaa2f0..a18b80d91920 100644
--- a/drivers/char/drm/i810_drv.h
+++ b/drivers/char/drm/i810_drv.h
@@ -116,9 +116,13 @@ typedef struct drm_i810_private {
 extern void i810_reclaim_buffers(drm_device_t * dev, struct file *filp);
 
 extern int i810_driver_dma_quiescent(drm_device_t * dev);
-extern void i810_driver_release(drm_device_t * dev, struct file *filp);
-extern void i810_driver_pretakedown(drm_device_t * dev);
-extern void i810_driver_prerelease(drm_device_t * dev, DRMFILE filp);
+extern void i810_driver_reclaim_buffers_locked(drm_device_t * dev,
+					       struct file *filp);
+extern int i810_driver_load(struct drm_device *, unsigned long flags);
+extern void i810_driver_lastclose(drm_device_t * dev);
+extern void i810_driver_preclose(drm_device_t * dev, DRMFILE filp);
+extern void i810_driver_reclaim_buffers_locked(drm_device_t * dev,
+					       struct file *filp);
 extern int i810_driver_device_is_agp(drm_device_t * dev);
 
 extern drm_ioctl_desc_t i810_ioctls[];
diff --git a/drivers/char/drm/i830_dma.c b/drivers/char/drm/i830_dma.c
index dc94f1914425..01dfdb944e1f 100644
--- a/drivers/char/drm/i830_dma.c
+++ b/drivers/char/drm/i830_dma.c
@@ -1517,12 +1517,24 @@ static int i830_setparam(struct inode *inode, struct file *filp,
 	return 0;
 }
 
-void i830_driver_pretakedown(drm_device_t * dev)
+int i830_driver_load(drm_device_t *dev, unsigned long flags)
+{
+	/* i830 has 4 more counters */
+	dev->counters += 4;
+	dev->types[6] = _DRM_STAT_IRQ;
+	dev->types[7] = _DRM_STAT_PRIMARY;
+	dev->types[8] = _DRM_STAT_SECONDARY;
+	dev->types[9] = _DRM_STAT_DMA;
+
+	return 0;
+}
+
+void i830_driver_lastclose(drm_device_t * dev)
 {
 	i830_dma_cleanup(dev);
 }
 
-void i830_driver_prerelease(drm_device_t * dev, DRMFILE filp)
+void i830_driver_preclose(drm_device_t * dev, DRMFILE filp)
 {
 	if (dev->dev_private) {
 		drm_i830_private_t *dev_priv = dev->dev_private;
@@ -1532,7 +1544,7 @@ void i830_driver_prerelease(drm_device_t * dev, DRMFILE filp)
 	}
 }
 
-void i830_driver_release(drm_device_t * dev, struct file *filp)
+void i830_driver_reclaim_buffers_locked(drm_device_t * dev, struct file *filp)
 {
 	i830_reclaim_buffers(dev, filp);
 }
diff --git a/drivers/char/drm/i830_drv.c b/drivers/char/drm/i830_drv.c
index acd821e8fe4d..49fd2816de95 100644
--- a/drivers/char/drm/i830_drv.c
+++ b/drivers/char/drm/i830_drv.c
@@ -40,37 +40,6 @@
 
 #include "drm_pciids.h"
 
-static int postinit(struct drm_device *dev, unsigned long flags)
-{
-	dev->counters += 4;
-	dev->types[6] = _DRM_STAT_IRQ;
-	dev->types[7] = _DRM_STAT_PRIMARY;
-	dev->types[8] = _DRM_STAT_SECONDARY;
-	dev->types[9] = _DRM_STAT_DMA;
-
-	DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n",
-		 DRIVER_NAME,
-		 DRIVER_MAJOR,
-		 DRIVER_MINOR,
-		 DRIVER_PATCHLEVEL,
-		 DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev)
-	    );
-	return 0;
-}
-
-static int version(drm_version_t * version)
-{
-	int len;
-
-	version->version_major = DRIVER_MAJOR;
-	version->version_minor = DRIVER_MINOR;
-	version->version_patchlevel = DRIVER_PATCHLEVEL;
-	DRM_COPY(version->name, DRIVER_NAME);
-	DRM_COPY(version->date, DRIVER_DATE);
-	DRM_COPY(version->desc, DRIVER_DESC);
-	return 0;
-}
-
 static struct pci_device_id pciidlist[] = {
 	i830_PCI_IDS
 };
@@ -83,10 +52,11 @@ static struct drm_driver driver = {
 	.driver_features |= DRIVER_HAVE_IRQ | DRIVER_SHARED_IRQ,
 #endif
 	.dev_priv_size = sizeof(drm_i830_buf_priv_t),
-	.pretakedown = i830_driver_pretakedown,
-	.prerelease = i830_driver_prerelease,
+	.load = i830_driver_load,
+	.lastclose = i830_driver_lastclose,
+	.preclose = i830_driver_preclose,
 	.device_is_agp = i830_driver_device_is_agp,
-	.release = i830_driver_release,
+	.reclaim_buffers_locked = i830_driver_reclaim_buffers_locked,
 	.dma_quiescent = i830_driver_dma_quiescent,
 	.reclaim_buffers = i830_reclaim_buffers,
 	.get_map_ofs = drm_core_get_map_ofs,
@@ -97,8 +67,6 @@ static struct drm_driver driver = {
 	.irq_uninstall = i830_driver_irq_uninstall,
 	.irq_handler = i830_driver_irq_handler,
 #endif
-	.postinit = postinit,
-	.version = version,
 	.ioctls = i830_ioctls,
 	.fops = {
 		 .owner = THIS_MODULE,
@@ -108,13 +76,19 @@ static struct drm_driver driver = {
 		 .mmap = drm_mmap,
 		 .poll = drm_poll,
 		 .fasync = drm_fasync,
-		 }
-	,
+	},
+
 	.pci_driver = {
-		       .name = DRIVER_NAME,
-		       .id_table = pciidlist,
-		       }
+		 .name = DRIVER_NAME,
+		 .id_table = pciidlist,
+	},
 
+	.name = DRIVER_NAME,
+	.desc = DRIVER_DESC,
+	.date = DRIVER_DATE,
+	.major = DRIVER_MAJOR,
+	.minor = DRIVER_MINOR,
+	.patchlevel = DRIVER_PATCHLEVEL,
 };
 
 static int __init i830_init(void)
diff --git a/drivers/char/drm/i830_drv.h b/drivers/char/drm/i830_drv.h
index bc4bd49fb0cc..bf9075b576bd 100644
--- a/drivers/char/drm/i830_drv.h
+++ b/drivers/char/drm/i830_drv.h
@@ -136,10 +136,12 @@ extern irqreturn_t i830_driver_irq_handler(DRM_IRQ_ARGS);
 extern void i830_driver_irq_preinstall(drm_device_t * dev);
 extern void i830_driver_irq_postinstall(drm_device_t * dev);
 extern void i830_driver_irq_uninstall(drm_device_t * dev);
-extern void i830_driver_pretakedown(drm_device_t * dev);
-extern void i830_driver_release(drm_device_t * dev, struct file *filp);
+extern int i830_driver_load(struct drm_device *, unsigned long flags);
+extern void i830_driver_preclose(drm_device_t * dev, DRMFILE filp);
+extern void i830_driver_lastclose(drm_device_t * dev);
+extern void i830_driver_reclaim_buffers_locked(drm_device_t * dev,
+					       struct file *filp);
 extern int i830_driver_dma_quiescent(drm_device_t * dev);
-extern void i830_driver_prerelease(drm_device_t * dev, DRMFILE filp);
 extern int i830_driver_device_is_agp(drm_device_t * dev);
 
 #define I830_READ(reg)          DRM_READ32(dev_priv->mmio_map, reg)
diff --git a/drivers/char/drm/i915_dma.c b/drivers/char/drm/i915_dma.c
index f3aa0c370127..9ef3be31a812 100644
--- a/drivers/char/drm/i915_dma.c
+++ b/drivers/char/drm/i915_dma.c
@@ -699,7 +699,19 @@ static int i915_setparam(DRM_IOCTL_ARGS)
 	return 0;
 }
 
-void i915_driver_pretakedown(drm_device_t * dev)
+int i915_driver_load(drm_device_t *dev, unsigned long flags)
+{
+	/* i915 has 4 more counters */
+	dev->counters += 4;
+	dev->types[6] = _DRM_STAT_IRQ;
+	dev->types[7] = _DRM_STAT_PRIMARY;
+	dev->types[8] = _DRM_STAT_SECONDARY;
+	dev->types[9] = _DRM_STAT_DMA;
+
+	return 0;
+}
+
+void i915_driver_lastclose(drm_device_t * dev)
 {
 	if (dev->dev_private) {
 		drm_i915_private_t *dev_priv = dev->dev_private;
@@ -708,7 +720,7 @@ void i915_driver_pretakedown(drm_device_t * dev)
 	i915_dma_cleanup(dev);
 }
 
-void i915_driver_prerelease(drm_device_t * dev, DRMFILE filp)
+void i915_driver_preclose(drm_device_t * dev, DRMFILE filp)
 {
 	if (dev->dev_private) {
 		drm_i915_private_t *dev_priv = dev->dev_private;
diff --git a/drivers/char/drm/i915_drv.c b/drivers/char/drm/i915_drv.c
index 0508240f4e3b..32b7f8bb420d 100644
--- a/drivers/char/drm/i915_drv.c
+++ b/drivers/char/drm/i915_drv.c
@@ -34,37 +34,6 @@
 
 #include "drm_pciids.h"
 
-static int postinit(struct drm_device *dev, unsigned long flags)
-{
-	dev->counters += 4;
-	dev->types[6] = _DRM_STAT_IRQ;
-	dev->types[7] = _DRM_STAT_PRIMARY;
-	dev->types[8] = _DRM_STAT_SECONDARY;
-	dev->types[9] = _DRM_STAT_DMA;
-
-	DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n",
-		 DRIVER_NAME,
-		 DRIVER_MAJOR,
-		 DRIVER_MINOR,
-		 DRIVER_PATCHLEVEL,
-		 DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev)
-	    );
-	return 0;
-}
-
-static int version(drm_version_t * version)
-{
-	int len;
-
-	version->version_major = DRIVER_MAJOR;
-	version->version_minor = DRIVER_MINOR;
-	version->version_patchlevel = DRIVER_PATCHLEVEL;
-	DRM_COPY(version->name, DRIVER_NAME);
-	DRM_COPY(version->date, DRIVER_DATE);
-	DRM_COPY(version->desc, DRIVER_DESC);
-	return 0;
-}
-
 static struct pci_device_id pciidlist[] = {
 	i915_PCI_IDS
 };
@@ -73,8 +42,9 @@ static struct drm_driver driver = {
 	.driver_features =
 	    DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR |
 	    DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED,
-	.pretakedown = i915_driver_pretakedown,
-	.prerelease = i915_driver_prerelease,
+	.load = i915_driver_load,
+	.lastclose = i915_driver_lastclose,
+	.preclose = i915_driver_preclose,
 	.device_is_agp = i915_driver_device_is_agp,
 	.irq_preinstall = i915_driver_irq_preinstall,
 	.irq_postinstall = i915_driver_irq_postinstall,
@@ -83,8 +53,6 @@ static struct drm_driver driver = {
 	.reclaim_buffers = drm_core_reclaim_buffers,
 	.get_map_ofs = drm_core_get_map_ofs,
 	.get_reg_ofs = drm_core_get_reg_ofs,
-	.postinit = postinit,
-	.version = version,
 	.ioctls = i915_ioctls,
 	.fops = {
 		 .owner = THIS_MODULE,
@@ -97,11 +65,19 @@ static struct drm_driver driver = {
 #ifdef CONFIG_COMPAT
 		 .compat_ioctl = i915_compat_ioctl,
 #endif
-		 },
+	},
+
 	.pci_driver = {
-		       .name = DRIVER_NAME,
-		       .id_table = pciidlist,
-		       }
+		 .name = DRIVER_NAME,
+		 .id_table = pciidlist,
+	},
+	
+	.name = DRIVER_NAME,
+	.desc = DRIVER_DESC,
+	.date = DRIVER_DATE,
+	.major = DRIVER_MAJOR,
+	.minor = DRIVER_MINOR,
+	.patchlevel = DRIVER_PATCHLEVEL,
 };
 
 static int __init i915_init(void)
diff --git a/drivers/char/drm/i915_drv.h b/drivers/char/drm/i915_drv.h
index 17e457c73dc7..cd4f5227d0ea 100644
--- a/drivers/char/drm/i915_drv.h
+++ b/drivers/char/drm/i915_drv.h
@@ -104,8 +104,9 @@ extern int i915_max_ioctl;
 
 				/* i915_dma.c */
 extern void i915_kernel_lost_context(drm_device_t * dev);
-extern void i915_driver_pretakedown(drm_device_t * dev);
-extern void i915_driver_prerelease(drm_device_t * dev, DRMFILE filp);
+extern int i915_driver_load(struct drm_device *, unsigned long flags);
+extern void i915_driver_lastclose(drm_device_t * dev);
+extern void i915_driver_preclose(drm_device_t * dev, DRMFILE filp);
 extern int i915_driver_device_is_agp(drm_device_t * dev);
 
 /* i915_irq.c */
diff --git a/drivers/char/drm/mga_dma.c b/drivers/char/drm/mga_dma.c
index 70dc7f64b7b9..9b09d786b158 100644
--- a/drivers/char/drm/mga_dma.c
+++ b/drivers/char/drm/mga_dma.c
@@ -391,7 +391,7 @@ int mga_freelist_put(drm_device_t * dev, drm_buf_t * buf)
  * DMA initialization, cleanup
  */
 
-int mga_driver_preinit(drm_device_t * dev, unsigned long flags)
+int mga_driver_load(drm_device_t * dev, unsigned long flags)
 {
 	drm_mga_private_t *dev_priv;
 
@@ -405,6 +405,14 @@ int mga_driver_preinit(drm_device_t * dev, unsigned long flags)
 	dev_priv->usec_timeout = MGA_DEFAULT_USEC_TIMEOUT;
 	dev_priv->chipset = flags;
 
+	dev_priv->mmio_base = drm_get_resource_start(dev, 1);
+	dev_priv->mmio_size = drm_get_resource_len(dev, 1);
+
+	dev->counters += 3;
+	dev->types[6] = _DRM_STAT_IRQ;
+	dev->types[7] = _DRM_STAT_PRIMARY;
+	dev->types[8] = _DRM_STAT_SECONDARY;
+
 	return 0;
 }
 
@@ -1118,7 +1126,7 @@ int mga_dma_buffers(DRM_IOCTL_ARGS)
 /**
  * Called just before the module is unloaded.
  */
-int mga_driver_postcleanup(drm_device_t * dev)
+int mga_driver_unload(drm_device_t * dev)
 {
 	drm_free(dev->dev_private, sizeof(drm_mga_private_t), DRM_MEM_DRIVER);
 	dev->dev_private = NULL;
@@ -1129,7 +1137,7 @@ int mga_driver_postcleanup(drm_device_t * dev)
 /**
  * Called when the last opener of the device is closed.
  */
-void mga_driver_pretakedown(drm_device_t * dev)
+void mga_driver_lastclose(drm_device_t * dev)
 {
 	mga_do_cleanup_dma(dev);
 }
diff --git a/drivers/char/drm/mga_drv.c b/drivers/char/drm/mga_drv.c
index 0cc7c305a7f6..eae2f91994ec 100644
--- a/drivers/char/drm/mga_drv.c
+++ b/drivers/char/drm/mga_drv.c
@@ -38,41 +38,6 @@
 #include "drm_pciids.h"
 
 static int mga_driver_device_is_agp(drm_device_t * dev);
-static int postinit(struct drm_device *dev, unsigned long flags)
-{
-	drm_mga_private_t *const dev_priv =
-	    (drm_mga_private_t *) dev->dev_private;
-
-	dev_priv->mmio_base = pci_resource_start(dev->pdev, 1);
-	dev_priv->mmio_size = pci_resource_len(dev->pdev, 1);
-
-	dev->counters += 3;
-	dev->types[6] = _DRM_STAT_IRQ;
-	dev->types[7] = _DRM_STAT_PRIMARY;
-	dev->types[8] = _DRM_STAT_SECONDARY;
-
-	DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n",
-		 DRIVER_NAME,
-		 DRIVER_MAJOR,
-		 DRIVER_MINOR,
-		 DRIVER_PATCHLEVEL,
-		 DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev)
-	    );
-	return 0;
-}
-
-static int version(drm_version_t * version)
-{
-	int len;
-
-	version->version_major = DRIVER_MAJOR;
-	version->version_minor = DRIVER_MINOR;
-	version->version_patchlevel = DRIVER_PATCHLEVEL;
-	DRM_COPY(version->name, DRIVER_NAME);
-	DRM_COPY(version->date, DRIVER_DATE);
-	DRM_COPY(version->desc, DRIVER_DESC);
-	return 0;
-}
 
 static struct pci_device_id pciidlist[] = {
 	mga_PCI_IDS
@@ -83,9 +48,9 @@ static struct drm_driver driver = {
 	    DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR |
 	    DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED |
 	    DRIVER_IRQ_VBL,
-	.preinit = mga_driver_preinit,
-	.postcleanup = mga_driver_postcleanup,
-	.pretakedown = mga_driver_pretakedown,
+	.load = mga_driver_load,
+	.unload = mga_driver_unload,
+	.lastclose = mga_driver_lastclose,
 	.dma_quiescent = mga_driver_dma_quiescent,
 	.device_is_agp = mga_driver_device_is_agp,
 	.vblank_wait = mga_driver_vblank_wait,
@@ -96,8 +61,6 @@ static struct drm_driver driver = {
 	.reclaim_buffers = drm_core_reclaim_buffers,
 	.get_map_ofs = drm_core_get_map_ofs,
 	.get_reg_ofs = drm_core_get_reg_ofs,
-	.postinit = postinit,
-	.version = version,
 	.ioctls = mga_ioctls,
 	.dma_ioctl = mga_dma_buffers,
 	.fops = {
@@ -113,9 +76,16 @@ static struct drm_driver driver = {
 #endif
 		 },
 	.pci_driver = {
-		       .name = DRIVER_NAME,
-		       .id_table = pciidlist,
-		       }
+		 .name = DRIVER_NAME,
+		 .id_table = pciidlist,
+	},
+
+	.name = DRIVER_NAME,
+	.desc = DRIVER_DESC,
+	.date = DRIVER_DATE,
+	.major = DRIVER_MAJOR,
+	.minor = DRIVER_MINOR,
+	.patchlevel = DRIVER_PATCHLEVEL,
 };
 
 static int __init mga_init(void)
diff --git a/drivers/char/drm/mga_drv.h b/drivers/char/drm/mga_drv.h
index 461728e6a58a..137bfdd5e92b 100644
--- a/drivers/char/drm/mga_drv.h
+++ b/drivers/char/drm/mga_drv.h
@@ -152,14 +152,14 @@ extern drm_ioctl_desc_t mga_ioctls[];
 extern int mga_max_ioctl;
 
 				/* mga_dma.c */
-extern int mga_driver_preinit(drm_device_t * dev, unsigned long flags);
 extern int mga_dma_bootstrap(DRM_IOCTL_ARGS);
 extern int mga_dma_init(DRM_IOCTL_ARGS);
 extern int mga_dma_flush(DRM_IOCTL_ARGS);
 extern int mga_dma_reset(DRM_IOCTL_ARGS);
 extern int mga_dma_buffers(DRM_IOCTL_ARGS);
-extern int mga_driver_postcleanup(drm_device_t * dev);
-extern void mga_driver_pretakedown(drm_device_t * dev);
+extern int mga_driver_load(drm_device_t *dev, unsigned long flags);
+extern int mga_driver_unload(drm_device_t * dev);
+extern void mga_driver_lastclose(drm_device_t * dev);
 extern int mga_driver_dma_quiescent(drm_device_t * dev);
 
 extern int mga_do_wait_for_idle(drm_mga_private_t * dev_priv);
diff --git a/drivers/char/drm/r128_drv.c b/drivers/char/drm/r128_drv.c
index 1661e7351402..e20450ae220e 100644
--- a/drivers/char/drm/r128_drv.c
+++ b/drivers/char/drm/r128_drv.c
@@ -37,31 +37,6 @@
 
 #include "drm_pciids.h"
 
-static int postinit(struct drm_device *dev, unsigned long flags)
-{
-	DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n",
-		 DRIVER_NAME,
-		 DRIVER_MAJOR,
-		 DRIVER_MINOR,
-		 DRIVER_PATCHLEVEL,
-		 DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev)
-	    );
-	return 0;
-}
-
-static int version(drm_version_t * version)
-{
-	int len;
-
-	version->version_major = DRIVER_MAJOR;
-	version->version_minor = DRIVER_MINOR;
-	version->version_patchlevel = DRIVER_PATCHLEVEL;
-	DRM_COPY(version->name, DRIVER_NAME);
-	DRM_COPY(version->date, DRIVER_DATE);
-	DRM_COPY(version->desc, DRIVER_DESC);
-	return 0;
-}
-
 static struct pci_device_id pciidlist[] = {
 	r128_PCI_IDS
 };
@@ -72,8 +47,8 @@ static struct drm_driver driver = {
 	    DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED |
 	    DRIVER_IRQ_VBL,
 	.dev_priv_size = sizeof(drm_r128_buf_priv_t),
-	.prerelease = r128_driver_prerelease,
-	.pretakedown = r128_driver_pretakedown,
+	.preclose = r128_driver_preclose,
+	.lastclose = r128_driver_lastclose,
 	.vblank_wait = r128_driver_vblank_wait,
 	.irq_preinstall = r128_driver_irq_preinstall,
 	.irq_postinstall = r128_driver_irq_postinstall,
@@ -82,8 +57,6 @@ static struct drm_driver driver = {
 	.reclaim_buffers = drm_core_reclaim_buffers,
 	.get_map_ofs = drm_core_get_map_ofs,
 	.get_reg_ofs = drm_core_get_reg_ofs,
-	.postinit = postinit,
-	.version = version,
 	.ioctls = r128_ioctls,
 	.dma_ioctl = r128_cce_buffers,
 	.fops = {
@@ -97,12 +70,19 @@ static struct drm_driver driver = {
 #ifdef CONFIG_COMPAT
 		 .compat_ioctl = r128_compat_ioctl,
 #endif
-		 }
-	,
+	},
+
 	.pci_driver = {
-		       .name = DRIVER_NAME,
-		       .id_table = pciidlist,
-		       }
+		 .name = DRIVER_NAME,
+		 .id_table = pciidlist,
+	},
+
+	.name = DRIVER_NAME,
+	.desc = DRIVER_DESC,
+	.date = DRIVER_DATE,
+	.major = DRIVER_MAJOR,
+	.minor = DRIVER_MINOR,
+	.patchlevel = DRIVER_PATCHLEVEL,
 };
 
 static int __init r128_init(void)
diff --git a/drivers/char/drm/r128_drv.h b/drivers/char/drm/r128_drv.h
index 5c79e40eb88f..9a779bad3da3 100644
--- a/drivers/char/drm/r128_drv.h
+++ b/drivers/char/drm/r128_drv.h
@@ -154,8 +154,8 @@ extern irqreturn_t r128_driver_irq_handler(DRM_IRQ_ARGS);
 extern void r128_driver_irq_preinstall(drm_device_t * dev);
 extern void r128_driver_irq_postinstall(drm_device_t * dev);
 extern void r128_driver_irq_uninstall(drm_device_t * dev);
-extern void r128_driver_pretakedown(drm_device_t * dev);
-extern void r128_driver_prerelease(drm_device_t * dev, DRMFILE filp);
+extern void r128_driver_lastclose(drm_device_t * dev);
+extern void r128_driver_preclose(drm_device_t * dev, DRMFILE filp);
 
 extern long r128_compat_ioctl(struct file *filp, unsigned int cmd,
 			      unsigned long arg);
diff --git a/drivers/char/drm/r128_state.c b/drivers/char/drm/r128_state.c
index 14479cc08a57..1f04e3372206 100644
--- a/drivers/char/drm/r128_state.c
+++ b/drivers/char/drm/r128_state.c
@@ -1674,7 +1674,7 @@ static int r128_getparam(DRM_IOCTL_ARGS)
 	return 0;
 }
 
-void r128_driver_prerelease(drm_device_t * dev, DRMFILE filp)
+void r128_driver_preclose(drm_device_t * dev, DRMFILE filp)
 {
 	if (dev->dev_private) {
 		drm_r128_private_t *dev_priv = dev->dev_private;
@@ -1684,7 +1684,7 @@ void r128_driver_prerelease(drm_device_t * dev, DRMFILE filp)
 	}
 }
 
-void r128_driver_pretakedown(drm_device_t * dev)
+void r128_driver_lastclose(drm_device_t * dev)
 {
 	r128_do_cleanup_cce(dev);
 }
diff --git a/drivers/char/drm/radeon_cp.c b/drivers/char/drm/radeon_cp.c
index 03839ea31092..dc3a15a1819a 100644
--- a/drivers/char/drm/radeon_cp.c
+++ b/drivers/char/drm/radeon_cp.c
@@ -2103,7 +2103,7 @@ int radeon_cp_buffers(DRM_IOCTL_ARGS)
 	return ret;
 }
 
-int radeon_driver_preinit(struct drm_device *dev, unsigned long flags)
+int radeon_driver_load(struct drm_device *dev, unsigned long flags)
 {
 	drm_radeon_private_t *dev_priv;
 	int ret = 0;
@@ -2140,7 +2140,10 @@ int radeon_driver_preinit(struct drm_device *dev, unsigned long flags)
 	return ret;
 }
 
-int radeon_presetup(struct drm_device *dev)
+/* Create mappings for registers and framebuffer so userland doesn't necessarily
+ * have to find them.
+ */
+int radeon_driver_firstopen(struct drm_device *dev)
 {
 	int ret;
 	drm_local_map_t *map;
@@ -2161,7 +2164,7 @@ int radeon_presetup(struct drm_device *dev)
 	return 0;
 }
 
-int radeon_driver_postcleanup(struct drm_device *dev)
+int radeon_driver_unload(struct drm_device *dev)
 {
 	drm_radeon_private_t *dev_priv = dev->dev_private;
 
diff --git a/drivers/char/drm/radeon_drv.c b/drivers/char/drm/radeon_drv.c
index ee49670d8162..999d74512362 100644
--- a/drivers/char/drm/radeon_drv.c
+++ b/drivers/char/drm/radeon_drv.c
@@ -42,30 +42,6 @@ int radeon_no_wb;
 MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers\n");
 module_param_named(no_wb, radeon_no_wb, int, 0444);
 
-static int postinit(struct drm_device *dev, unsigned long flags)
-{
-	DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n",
-		 DRIVER_NAME,
-		 DRIVER_MAJOR,
-		 DRIVER_MINOR,
-		 DRIVER_PATCHLEVEL,
-		 DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev)
-	    );
-	return 0;
-}
-
-static int version(drm_version_t * version)
-{
-	int len;
-
-	version->version_major = DRIVER_MAJOR;
-	version->version_minor = DRIVER_MINOR;
-	version->version_patchlevel = DRIVER_PATCHLEVEL;
-	DRM_COPY(version->name, DRIVER_NAME);
-	DRM_COPY(version->date, DRIVER_DATE);
-	DRM_COPY(version->desc, DRIVER_DESC);
-	return 0;
-}
 
 static struct pci_device_id pciidlist[] = {
 	radeon_PCI_IDS
@@ -77,23 +53,21 @@ static struct drm_driver driver = {
 	    DRIVER_HAVE_IRQ | DRIVER_HAVE_DMA | DRIVER_IRQ_SHARED |
 	    DRIVER_IRQ_VBL,
 	.dev_priv_size = sizeof(drm_radeon_buf_priv_t),
-	.preinit = radeon_driver_preinit,
-	.presetup = radeon_presetup,
-	.postcleanup = radeon_driver_postcleanup,
-	.prerelease = radeon_driver_prerelease,
-	.pretakedown = radeon_driver_pretakedown,
-	.open_helper = radeon_driver_open_helper,
+	.load = radeon_driver_load,
+	.firstopen = radeon_driver_firstopen,
+	.open = radeon_driver_open,
+	.preclose = radeon_driver_preclose,
+	.postclose = radeon_driver_postclose,
+	.lastclose = radeon_driver_lastclose,
+	.unload = radeon_driver_unload,
 	.vblank_wait = radeon_driver_vblank_wait,
 	.irq_preinstall = radeon_driver_irq_preinstall,
 	.irq_postinstall = radeon_driver_irq_postinstall,
 	.irq_uninstall = radeon_driver_irq_uninstall,
 	.irq_handler = radeon_driver_irq_handler,
-	.free_filp_priv = radeon_driver_free_filp_priv,
 	.reclaim_buffers = drm_core_reclaim_buffers,
 	.get_map_ofs = drm_core_get_map_ofs,
 	.get_reg_ofs = drm_core_get_reg_ofs,
-	.postinit = postinit,
-	.version = version,
 	.ioctls = radeon_ioctls,
 	.dma_ioctl = radeon_cp_buffers,
 	.fops = {
@@ -107,12 +81,19 @@ static struct drm_driver driver = {
 #ifdef CONFIG_COMPAT
 		 .compat_ioctl = radeon_compat_ioctl,
 #endif
-		 }
-	,
+	},
+
 	.pci_driver = {
-		       .name = DRIVER_NAME,
-		       .id_table = pciidlist,
-		       }
+		 .name = DRIVER_NAME,
+		 .id_table = pciidlist,
+	},
+
+	.name = DRIVER_NAME,
+	.desc = DRIVER_DESC,
+	.date = DRIVER_DATE,
+	.major = DRIVER_MAJOR,
+	.minor = DRIVER_MINOR,
+	.patchlevel = DRIVER_PATCHLEVEL,
 };
 
 static int __init radeon_init(void)
diff --git a/drivers/char/drm/radeon_drv.h b/drivers/char/drm/radeon_drv.h
index 120ee5a8ebcc..3a91d5fc597e 100644
--- a/drivers/char/drm/radeon_drv.h
+++ b/drivers/char/drm/radeon_drv.h
@@ -331,17 +331,14 @@ extern irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS);
 extern void radeon_driver_irq_preinstall(drm_device_t * dev);
 extern void radeon_driver_irq_postinstall(drm_device_t * dev);
 extern void radeon_driver_irq_uninstall(drm_device_t * dev);
-extern void radeon_driver_prerelease(drm_device_t * dev, DRMFILE filp);
-extern void radeon_driver_pretakedown(drm_device_t * dev);
-extern int radeon_driver_open_helper(drm_device_t * dev,
-				     drm_file_t * filp_priv);
-extern void radeon_driver_free_filp_priv(drm_device_t * dev,
-					 drm_file_t * filp_priv);
-
-extern int radeon_preinit(struct drm_device *dev, unsigned long flags);
-extern int radeon_postinit(struct drm_device *dev, unsigned long flags);
-extern int radeon_postcleanup(struct drm_device *dev);
 
+extern int radeon_driver_load(struct drm_device *dev, unsigned long flags);
+extern int radeon_driver_unload(struct drm_device *dev);
+extern int radeon_driver_firstopen(struct drm_device *dev);
+extern void radeon_driver_preclose(drm_device_t * dev, DRMFILE filp);
+extern void radeon_driver_postclose(drm_device_t * dev, drm_file_t * filp);
+extern void radeon_driver_lastclose(drm_device_t * dev);
+extern int radeon_driver_open(drm_device_t * dev, drm_file_t * filp_priv);
 extern long radeon_compat_ioctl(struct file *filp, unsigned int cmd,
 				unsigned long arg);
 
diff --git a/drivers/char/drm/radeon_state.c b/drivers/char/drm/radeon_state.c
index 231ac1438c69..717f546cc448 100644
--- a/drivers/char/drm/radeon_state.c
+++ b/drivers/char/drm/radeon_state.c
@@ -3069,7 +3069,7 @@ static int radeon_cp_setparam(DRM_IOCTL_ARGS)
  *
  * DRM infrastructure takes care of reclaiming dma buffers.
  */
-void radeon_driver_prerelease(drm_device_t * dev, DRMFILE filp)
+void radeon_driver_preclose(drm_device_t * dev, DRMFILE filp)
 {
 	if (dev->dev_private) {
 		drm_radeon_private_t *dev_priv = dev->dev_private;
@@ -3082,12 +3082,12 @@ void radeon_driver_prerelease(drm_device_t * dev, DRMFILE filp)
 	}
 }
 
-void radeon_driver_pretakedown(drm_device_t * dev)
+void radeon_driver_lastclose(drm_device_t * dev)
 {
 	radeon_do_release(dev);
 }
 
-int radeon_driver_open_helper(drm_device_t * dev, drm_file_t * filp_priv)
+int radeon_driver_open(drm_device_t * dev, drm_file_t * filp_priv)
 {
 	drm_radeon_private_t *dev_priv = dev->dev_private;
 	struct drm_radeon_driver_file_fields *radeon_priv;
@@ -3107,7 +3107,7 @@ int radeon_driver_open_helper(drm_device_t * dev, drm_file_t * filp_priv)
 	return 0;
 }
 
-void radeon_driver_free_filp_priv(drm_device_t * dev, drm_file_t * filp_priv)
+void radeon_driver_postclose(drm_device_t * dev, drm_file_t * filp_priv)
 {
 	struct drm_radeon_driver_file_fields *radeon_priv =
 	    filp_priv->driver_priv;
diff --git a/drivers/char/drm/savage_bci.c b/drivers/char/drm/savage_bci.c
index 6d10515795cc..c3101702a1fe 100644
--- a/drivers/char/drm/savage_bci.c
+++ b/drivers/char/drm/savage_bci.c
@@ -533,16 +533,32 @@ static void savage_fake_dma_flush(drm_savage_private_t * dev_priv)
 	dev_priv->first_dma_page = dev_priv->current_dma_page = 0;
 }
 
+int savage_driver_load(drm_device_t *dev, unsigned long chipset)
+{
+	drm_savage_private_t *dev_priv;
+
+	dev_priv = drm_alloc(sizeof(drm_savage_private_t), DRM_MEM_DRIVER);
+	if (dev_priv == NULL)
+		return DRM_ERR(ENOMEM);
+
+	memset(dev_priv, 0, sizeof(drm_savage_private_t));
+	dev->dev_private = (void *)dev_priv;
+
+	dev_priv->chipset = (enum savage_family)chipset;
+
+	return 0;
+}
+
+
 /*
  * Initalize mappings. On Savage4 and SavageIX the alignment
  * and size of the aperture is not suitable for automatic MTRR setup
- * in drm_addmap. Therefore we do it manually before the maps are
- * initialized. We also need to take care of deleting the MTRRs in
- * postcleanup.
+ * in drm_addmap. Therefore we add them manually before the maps are
+ * initialized, and tear them down on last close.
  */
-int savage_preinit(drm_device_t * dev, unsigned long chipset)
+int savage_driver_firstopen(drm_device_t *dev)
 {
-	drm_savage_private_t *dev_priv;
+	drm_savage_private_t *dev_priv = dev->dev_private;
 	unsigned long mmio_base, fb_base, fb_size, aperture_base;
 	/* fb_rsrc and aper_rsrc aren't really used currently, but still exist
 	 * in case we decide we need information on the BAR for BSD in the
@@ -551,14 +567,6 @@ int savage_preinit(drm_device_t * dev, unsigned long chipset)
 	unsigned int fb_rsrc, aper_rsrc;
 	int ret = 0;
 
-	dev_priv = drm_alloc(sizeof(drm_savage_private_t), DRM_MEM_DRIVER);
-	if (dev_priv == NULL)
-		return DRM_ERR(ENOMEM);
-
-	memset(dev_priv, 0, sizeof(drm_savage_private_t));
-	dev->dev_private = (void *)dev_priv;
-	dev_priv->chipset = (enum savage_family)chipset;
-
 	dev_priv->mtrr[0].handle = -1;
 	dev_priv->mtrr[1].handle = -1;
 	dev_priv->mtrr[2].handle = -1;
@@ -595,7 +603,8 @@ int savage_preinit(drm_device_t * dev, unsigned long chipset)
 			DRM_ERROR("strange pci_resource_len %08lx\n",
 				  drm_get_resource_len(dev, 0));
 		}
-	} else if (chipset != S3_SUPERSAVAGE && chipset != S3_SAVAGE2000) {
+	} else if (dev_priv->chipset != S3_SUPERSAVAGE &&
+		   dev_priv->chipset != S3_SAVAGE2000) {
 		mmio_base = drm_get_resource_start(dev, 0);
 		fb_rsrc = 1;
 		fb_base = drm_get_resource_start(dev, 1);
@@ -648,7 +657,7 @@ int savage_preinit(drm_device_t * dev, unsigned long chipset)
 /*
  * Delete MTRRs and free device-private data.
  */
-int savage_postcleanup(drm_device_t * dev)
+void savage_driver_lastclose(drm_device_t *dev)
 {
 	drm_savage_private_t *dev_priv = dev->dev_private;
 	int i;
@@ -658,6 +667,11 @@ int savage_postcleanup(drm_device_t * dev)
 			mtrr_del(dev_priv->mtrr[i].handle,
 				 dev_priv->mtrr[i].base,
 				 dev_priv->mtrr[i].size);
+}
+
+int savage_driver_unload(drm_device_t *dev)
+{
+	drm_savage_private_t *dev_priv = dev->dev_private;
 
 	drm_free(dev_priv, sizeof(drm_savage_private_t), DRM_MEM_DRIVER);
 
diff --git a/drivers/char/drm/savage_drv.c b/drivers/char/drm/savage_drv.c
index 22d799cde41c..aa6c0d1a82f8 100644
--- a/drivers/char/drm/savage_drv.c
+++ b/drivers/char/drm/savage_drv.c
@@ -30,31 +30,6 @@
 
 #include "drm_pciids.h"
 
-static int postinit(struct drm_device *dev, unsigned long flags)
-{
-	DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n",
-		 DRIVER_NAME,
-		 DRIVER_MAJOR,
-		 DRIVER_MINOR,
-		 DRIVER_PATCHLEVEL,
-		 DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev)
-	    );
-	return 0;
-}
-
-static int version(drm_version_t * version)
-{
-	int len;
-
-	version->version_major = DRIVER_MAJOR;
-	version->version_minor = DRIVER_MINOR;
-	version->version_patchlevel = DRIVER_PATCHLEVEL;
-	DRM_COPY(version->name, DRIVER_NAME);
-	DRM_COPY(version->date, DRIVER_DATE);
-	DRM_COPY(version->desc, DRIVER_DESC);
-	return 0;
-}
-
 static struct pci_device_id pciidlist[] = {
 	savage_PCI_IDS
 };
@@ -63,13 +38,13 @@ static struct drm_driver driver = {
 	.driver_features =
 	    DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_DMA | DRIVER_PCI_DMA,
 	.dev_priv_size = sizeof(drm_savage_buf_priv_t),
-	.preinit = savage_preinit,
-	.postinit = postinit,
-	.postcleanup = savage_postcleanup,
+	.load = savage_driver_load,
+	.firstopen = savage_driver_firstopen,
+	.lastclose = savage_driver_lastclose,
+	.unload = savage_driver_unload,
 	.reclaim_buffers = savage_reclaim_buffers,
 	.get_map_ofs = drm_core_get_map_ofs,
 	.get_reg_ofs = drm_core_get_reg_ofs,
-	.version = version,
 	.ioctls = savage_ioctls,
 	.dma_ioctl = savage_bci_buffers,
 	.fops = {
@@ -80,12 +55,19 @@ static struct drm_driver driver = {
 		 .mmap = drm_mmap,
 		 .poll = drm_poll,
 		 .fasync = drm_fasync,
-		 }
-	,
+	},
+
 	.pci_driver = {
-		       .name = DRIVER_NAME,
-		       .id_table = pciidlist,
-		       }
+		 .name = DRIVER_NAME,
+		 .id_table = pciidlist,
+	},
+
+	.name = DRIVER_NAME,
+	.desc = DRIVER_DESC,
+	.date = DRIVER_DATE,
+	.major = DRIVER_MAJOR,
+	.minor = DRIVER_MINOR,
+	.patchlevel = DRIVER_PATCHLEVEL,
 };
 
 static int __init savage_init(void)
diff --git a/drivers/char/drm/savage_drv.h b/drivers/char/drm/savage_drv.h
index a4b0fa998a95..2f73558fb9cf 100644
--- a/drivers/char/drm/savage_drv.h
+++ b/drivers/char/drm/savage_drv.h
@@ -208,8 +208,10 @@ extern void savage_dma_reset(drm_savage_private_t * dev_priv);
 extern void savage_dma_wait(drm_savage_private_t * dev_priv, unsigned int page);
 extern uint32_t *savage_dma_alloc(drm_savage_private_t * dev_priv,
 				  unsigned int n);
-extern int savage_preinit(drm_device_t * dev, unsigned long chipset);
-extern int savage_postcleanup(drm_device_t * dev);
+extern int savage_driver_load(drm_device_t *dev, unsigned long chipset);
+extern int savage_driver_firstopen(drm_device_t *dev);
+extern void savage_driver_lastclose(drm_device_t *dev);
+extern int savage_driver_unload(drm_device_t *dev);
 extern int savage_do_cleanup_bci(drm_device_t * dev);
 extern void savage_reclaim_buffers(drm_device_t * dev, DRMFILE filp);
 
diff --git a/drivers/char/drm/sis_drv.c b/drivers/char/drm/sis_drv.c
index 3cef10643a8f..6f6d7d613ede 100644
--- a/drivers/char/drm/sis_drv.c
+++ b/drivers/char/drm/sis_drv.c
@@ -32,31 +32,6 @@
 
 #include "drm_pciids.h"
 
-static int postinit(struct drm_device *dev, unsigned long flags)
-{
-	DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n",
-		 DRIVER_NAME,
-		 DRIVER_MAJOR,
-		 DRIVER_MINOR,
-		 DRIVER_PATCHLEVEL,
-		 DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev)
-	    );
-	return 0;
-}
-
-static int version(drm_version_t * version)
-{
-	int len;
-
-	version->version_major = DRIVER_MAJOR;
-	version->version_minor = DRIVER_MINOR;
-	version->version_patchlevel = DRIVER_PATCHLEVEL;
-	DRM_COPY(version->name, DRIVER_NAME);
-	DRM_COPY(version->date, DRIVER_DATE);
-	DRM_COPY(version->desc, DRIVER_DESC);
-	return 0;
-}
-
 static struct pci_device_id pciidlist[] = {
 	sisdrv_PCI_IDS
 };
@@ -68,8 +43,6 @@ static struct drm_driver driver = {
 	.reclaim_buffers = drm_core_reclaim_buffers,
 	.get_map_ofs = drm_core_get_map_ofs,
 	.get_reg_ofs = drm_core_get_reg_ofs,
-	.postinit = postinit,
-	.version = version,
 	.ioctls = sis_ioctls,
 	.fops = {
 		 .owner = THIS_MODULE,
@@ -79,11 +52,18 @@ static struct drm_driver driver = {
 		 .mmap = drm_mmap,
 		 .poll = drm_poll,
 		 .fasync = drm_fasync,
-		 },
+	},
 	.pci_driver = {
-		       .name = DRIVER_NAME,
-		       .id_table = pciidlist,
-		       }
+		 .name = DRIVER_NAME,
+		 .id_table = pciidlist,
+	},
+
+	.name = DRIVER_NAME,
+	.desc = DRIVER_DESC,
+	.date = DRIVER_DATE,
+	.major = DRIVER_MAJOR,
+	.minor = DRIVER_MINOR,
+	.patchlevel = DRIVER_PATCHLEVEL,
 };
 
 static int __init sis_init(void)
diff --git a/drivers/char/drm/tdfx_drv.c b/drivers/char/drm/tdfx_drv.c
index c275cbb6e9ce..baa4416032a8 100644
--- a/drivers/char/drm/tdfx_drv.c
+++ b/drivers/char/drm/tdfx_drv.c
@@ -36,31 +36,6 @@
 
 #include "drm_pciids.h"
 
-static int postinit(struct drm_device *dev, unsigned long flags)
-{
-	DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n",
-		 DRIVER_NAME,
-		 DRIVER_MAJOR,
-		 DRIVER_MINOR,
-		 DRIVER_PATCHLEVEL,
-		 DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev)
-	    );
-	return 0;
-}
-
-static int version(drm_version_t * version)
-{
-	int len;
-
-	version->version_major = DRIVER_MAJOR;
-	version->version_minor = DRIVER_MINOR;
-	version->version_patchlevel = DRIVER_PATCHLEVEL;
-	DRM_COPY(version->name, DRIVER_NAME);
-	DRM_COPY(version->date, DRIVER_DATE);
-	DRM_COPY(version->desc, DRIVER_DESC);
-	return 0;
-}
-
 static struct pci_device_id pciidlist[] = {
 	tdfx_PCI_IDS
 };
@@ -70,8 +45,6 @@ static struct drm_driver driver = {
 	.reclaim_buffers = drm_core_reclaim_buffers,
 	.get_map_ofs = drm_core_get_map_ofs,
 	.get_reg_ofs = drm_core_get_reg_ofs,
-	.postinit = postinit,
-	.version = version,
 	.fops = {
 		 .owner = THIS_MODULE,
 		 .open = drm_open,
@@ -80,11 +53,18 @@ static struct drm_driver driver = {
 		 .mmap = drm_mmap,
 		 .poll = drm_poll,
 		 .fasync = drm_fasync,
-		 },
+	},
 	.pci_driver = {
-		       .name = DRIVER_NAME,
-		       .id_table = pciidlist,
-		       }
+		 .name = DRIVER_NAME,
+		 .id_table = pciidlist,
+	},
+
+	.name = DRIVER_NAME,
+	.desc = DRIVER_DESC,
+	.date = DRIVER_DATE,
+	.major = DRIVER_MAJOR,
+	.minor = DRIVER_MINOR,
+	.patchlevel = DRIVER_PATCHLEVEL,
 };
 
 static int __init tdfx_init(void)
diff --git a/drivers/char/drm/via_drv.c b/drivers/char/drm/via_drv.c
index 016665e0c69f..6f3e6b32fa81 100644
--- a/drivers/char/drm/via_drv.c
+++ b/drivers/char/drm/via_drv.c
@@ -29,30 +29,6 @@
 
 #include "drm_pciids.h"
 
-static int postinit(struct drm_device *dev, unsigned long flags)
-{
-	DRM_INFO("Initialized %s %d.%d.%d %s on minor %d: %s\n",
-		 DRIVER_NAME,
-		 DRIVER_MAJOR,
-		 DRIVER_MINOR,
-		 DRIVER_PATCHLEVEL,
-		 DRIVER_DATE, dev->primary.minor, pci_pretty_name(dev->pdev)
-	    );
-	return 0;
-}
-
-static int version(drm_version_t * version)
-{
-	int len;
-
-	version->version_major = DRIVER_MAJOR;
-	version->version_minor = DRIVER_MINOR;
-	version->version_patchlevel = DRIVER_PATCHLEVEL;
-	DRM_COPY(version->name, DRIVER_NAME);
-	DRM_COPY(version->date, DRIVER_DATE);
-	DRM_COPY(version->desc, DRIVER_DESC);
-	return 0;
-}
 
 static struct pci_device_id pciidlist[] = {
 	viadrv_PCI_IDS
@@ -88,8 +64,6 @@ static struct drm_driver driver = {
 	.reclaim_buffers = drm_core_reclaim_buffers,
 	.get_map_ofs = drm_core_get_map_ofs,
 	.get_reg_ofs = drm_core_get_reg_ofs,
-	.postinit = postinit,
-	.version = version,
 	.ioctls = ioctls,
 	.num_ioctls = DRM_ARRAY_SIZE(ioctls),
 	.fops = {
@@ -100,11 +74,18 @@ static struct drm_driver driver = {
 		 .mmap = drm_mmap,
 		 .poll = drm_poll,
 		 .fasync = drm_fasync,
-		 },
+	},
 	.pci_driver = {
-		       .name = DRIVER_NAME,
-		       .id_table = pciidlist,
-		       }
+		 .name = DRIVER_NAME,
+		 .id_table = pciidlist,
+	},
+	
+	.name = DRIVER_NAME,
+	.desc = DRIVER_DESC,
+	.date = DRIVER_DATE,
+	.major = DRIVER_MAJOR,
+	.minor = DRIVER_MINOR,
+	.patchlevel = DRIVER_PATCHLEVEL,
 };
 
 static int __init via_init(void)