[PATCH 1/2] drm: rework PCI/platform driver interface.

Jordan Crouse jcrouse at codeaurora.org
Mon Feb 7 16:34:24 PST 2011


On 02/06/2011 08:09 PM, Dave Airlie wrote:
> This abstracts the pci/platform interface out a step further,
> we can go further but this is far enough for now to allow USB
> to be plugged in.
>
> The drivers now just call the init code directly for their
> device type.
>
> Signed-off-by: Dave Airlie<airlied at redhat.com>

You don't need my ACK, but I'll give it to you anyway - platform stuff looks good, very clean, much sanity.

Jordan

> ---
>   drivers/gpu/drm/drm_drv.c               |   43 -------
>   drivers/gpu/drm/drm_info.c              |   27 ++---
>   drivers/gpu/drm/drm_ioctl.c             |  115 ++----------------
>   drivers/gpu/drm/drm_irq.c               |   14 +--
>   drivers/gpu/drm/drm_pci.c               |  205 ++++++++++++++++++++++++++++++-
>   drivers/gpu/drm/drm_platform.c          |   75 +++++++++++-
>   drivers/gpu/drm/drm_stub.c              |   20 +---
>   drivers/gpu/drm/i810/i810_drv.c         |   14 +-
>   drivers/gpu/drm/i915/i915_drv.c         |   20 ++--
>   drivers/gpu/drm/mga/mga_dma.c           |    2 +-
>   drivers/gpu/drm/mga/mga_drv.c           |   13 +-
>   drivers/gpu/drm/nouveau/nouveau_drv.c   |   21 ++--
>   drivers/gpu/drm/nouveau/nouveau_mem.c   |    2 +-
>   drivers/gpu/drm/nouveau/nouveau_state.c |    4 +-
>   drivers/gpu/drm/r128/r128_drv.c         |   14 ++-
>   drivers/gpu/drm/radeon/radeon_cp.c      |    4 +-
>   drivers/gpu/drm/radeon/radeon_drv.c     |   36 +++---
>   drivers/gpu/drm/radeon/radeon_kms.c     |    4 +-
>   drivers/gpu/drm/savage/savage_drv.c     |   14 +-
>   drivers/gpu/drm/sis/sis_drv.c           |   13 +-
>   drivers/gpu/drm/tdfx/tdfx_drv.c         |   13 +-
>   drivers/gpu/drm/via/via_drv.c           |   13 +-
>   drivers/gpu/drm/vmwgfx/vmwgfx_drv.c     |   23 ++--
>   include/drm/drmP.h                      |  106 ++++++++--------
>   24 files changed, 456 insertions(+), 359 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
> index 3e99198..0d04914 100644
> --- a/drivers/gpu/drm/drm_drv.c
> +++ b/drivers/gpu/drm/drm_drv.c
> @@ -237,49 +237,6 @@ int drm_lastclose(struct drm_device * dev)
>   	return 0;
>   }
>
> -/**
> - * Module initialization. Called via init_module at module load time, or via
> - * linux/init/main.c (this is not currently supported).
> - *
> - * \return zero on success or a negative number on failure.
> - *
> - * Initializes an array of drm_device structures, and attempts to
> - * initialize all available devices, using consecutive minors, registering the
> - * stubs and initializing the device.
> - *
> - * Expands the \c DRIVER_PREINIT and \c DRIVER_POST_INIT macros before and
> - * after the initialization for driver customization.
> - */
> -int drm_init(struct drm_driver *driver)
> -{
> -	DRM_DEBUG("\n");
> -	INIT_LIST_HEAD(&driver->device_list);
> -
> -	if (driver->driver_features&  DRIVER_USE_PLATFORM_DEVICE)
> -		return drm_platform_init(driver);
> -	else
> -		return drm_pci_init(driver);
> -}
> -
> -EXPORT_SYMBOL(drm_init);
> -
> -void drm_exit(struct drm_driver *driver)
> -{
> -	struct drm_device *dev, *tmp;
> -	DRM_DEBUG("\n");
> -
> -	if (driver->driver_features&  DRIVER_MODESET) {
> -		pci_unregister_driver(&driver->pci_driver);
> -	} else {
> -		list_for_each_entry_safe(dev, tmp,&driver->device_list, driver_item)
> -			drm_put_dev(dev);
> -	}
> -
> -	DRM_INFO("Module unloaded\n");
> -}
> -
> -EXPORT_SYMBOL(drm_exit);
> -
>   /** File operations structure */
>   static const struct file_operations drm_stub_fops = {
>   	.owner = THIS_MODULE,
> diff --git a/drivers/gpu/drm/drm_info.c b/drivers/gpu/drm/drm_info.c
> index 3cdbaf3..812aaac 100644
> --- a/drivers/gpu/drm/drm_info.c
> +++ b/drivers/gpu/drm/drm_info.c
> @@ -47,30 +47,19 @@ int drm_name_info(struct seq_file *m, void *data)
>   	struct drm_minor *minor = node->minor;
>   	struct drm_device *dev = minor->dev;
>   	struct drm_master *master = minor->master;
> -
> +	const char *bus_name;
>   	if (!master)
>   		return 0;
>
> -	if (drm_core_check_feature(dev, DRIVER_USE_PLATFORM_DEVICE)) {
> -		if (master->unique) {
> -			seq_printf(m, "%s %s %s\n",
> -					dev->driver->platform_device->name,
> -					dev_name(dev->dev), master->unique);
> -		} else {
> -			seq_printf(m, "%s\n",
> -				dev->driver->platform_device->name);
> -		}
> +	bus_name = dev->driver->bus->get_name(dev);
> +	if (master->unique) {
> +		seq_printf(m, "%s %s %s\n",
> +			   bus_name,
> +			   dev_name(dev->dev), master->unique);
>   	} else {
> -		if (master->unique) {
> -			seq_printf(m, "%s %s %s\n",
> -				dev->driver->pci_driver.name,
> -				dev_name(dev->dev), master->unique);
> -		} else {
> -			seq_printf(m, "%s %s\n", dev->driver->pci_driver.name,
> -				dev_name(dev->dev));
> -		}
> +		seq_printf(m, "%s %s\n",
> +			   bus_name, dev_name(dev->dev));
>   	}
> -
>   	return 0;
>   }
>
> diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
> index 47db4df..1174905 100644
> --- a/drivers/gpu/drm/drm_ioctl.c
> +++ b/drivers/gpu/drm/drm_ioctl.c
> @@ -96,7 +96,7 @@ int drm_setunique(struct drm_device *dev, void *data,
>   {
>   	struct drm_unique *u = data;
>   	struct drm_master *master = file_priv->master;
> -	int domain, bus, slot, func, ret;
> +	int ret;
>
>   	if (master->unique_len || master->unique)
>   		return -EBUSY;
> @@ -104,50 +104,12 @@ int drm_setunique(struct drm_device *dev, void *data,
>   	if (!u->unique_len || u->unique_len>  1024)
>   		return -EINVAL;
>
> -	master->unique_len = u->unique_len;
> -	master->unique_size = u->unique_len + 1;
> -	master->unique = kmalloc(master->unique_size, GFP_KERNEL);
> -	if (!master->unique) {
> -		ret = -ENOMEM;
> -		goto err;
> -	}
> -
> -	if (copy_from_user(master->unique, u->unique, master->unique_len)) {
> -		ret = -EFAULT;
> -		goto err;
> -	}
> -
> -	master->unique[master->unique_len] = '\0';
> -
> -	dev->devname = kmalloc(strlen(dev->driver->pci_driver.name) +
> -			       strlen(master->unique) + 2, GFP_KERNEL);
> -	if (!dev->devname) {
> -		ret = -ENOMEM;
> -		goto err;
> -	}
> -
> -	sprintf(dev->devname, "%s@%s", dev->driver->pci_driver.name,
> -		master->unique);
> -
> -	/* Return error if the busid submitted doesn't match the device's actual
> -	 * busid.
> -	 */
> -	ret = sscanf(master->unique, "PCI:%d:%d:%d",&bus,&slot,&func);
> -	if (ret != 3) {
> -		ret = -EINVAL;
> -		goto err;
> -	}
> -
> -	domain = bus>>  8;
> -	bus&= 0xff;
> +	if (!dev->driver->bus->set_unique)
> +		return -EINVAL;
>
> -	if ((domain != drm_get_pci_domain(dev)) ||
> -	    (bus != dev->pdev->bus->number) ||
> -	    (slot != PCI_SLOT(dev->pdev->devfn)) ||
> -	    (func != PCI_FUNC(dev->pdev->devfn))) {
> -		ret = -EINVAL;
> +	ret = dev->driver->bus->set_unique(dev, master, u);
> +	if (ret)
>   		goto err;
> -	}
>
>   	return 0;
>
> @@ -159,74 +121,15 @@ err:
>   static int drm_set_busid(struct drm_device *dev, struct drm_file *file_priv)
>   {
>   	struct drm_master *master = file_priv->master;
> -	int len, ret;
> +	int ret;
>
>   	if (master->unique != NULL)
>   		drm_unset_busid(dev, master);
>
> -	if (drm_core_check_feature(dev, DRIVER_USE_PLATFORM_DEVICE)) {
> -		master->unique_len = 10 + strlen(dev->platformdev->name);
> -		master->unique = kmalloc(master->unique_len + 1, GFP_KERNEL);
> -
> -		if (master->unique == NULL)
> -			return -ENOMEM;
> -
> -		len = snprintf(master->unique, master->unique_len,
> -			"platform:%s", dev->platformdev->name);
> -
> -		if (len>  master->unique_len) {
> -			DRM_ERROR("Unique buffer overflowed\n");
> -			ret = -EINVAL;
> -			goto err;
> -		}
> -
> -		dev->devname =
> -			kmalloc(strlen(dev->platformdev->name) +
> -				master->unique_len + 2, GFP_KERNEL);
> -
> -		if (dev->devname == NULL) {
> -			ret = -ENOMEM;
> -			goto err;
> -		}
> -
> -		sprintf(dev->devname, "%s@%s", dev->platformdev->name,
> -			master->unique);
> -
> -	} else {
> -		master->unique_len = 40;
> -		master->unique_size = master->unique_len;
> -		master->unique = kmalloc(master->unique_size, GFP_KERNEL);
> -		if (master->unique == NULL)
> -			return -ENOMEM;
> -
> -		len = snprintf(master->unique, master->unique_len,
> -			"pci:%04x:%02x:%02x.%d",
> -			drm_get_pci_domain(dev),
> -			dev->pdev->bus->number,
> -			PCI_SLOT(dev->pdev->devfn),
> -			PCI_FUNC(dev->pdev->devfn));
> -		if (len>= master->unique_len) {
> -			DRM_ERROR("buffer overflow");
> -			ret = -EINVAL;
> -			goto err;
> -		} else
> -			master->unique_len = len;
> -
> -		dev->devname =
> -			kmalloc(strlen(dev->driver->pci_driver.name) +
> -				master->unique_len + 2, GFP_KERNEL);
> -
> -		if (dev->devname == NULL) {
> -			ret = -ENOMEM;
> -			goto err;
> -		}
> -
> -		sprintf(dev->devname, "%s@%s", dev->driver->pci_driver.name,
> -			master->unique);
> -	}
> -
> +	ret = dev->driver->bus->set_busid(dev, master);
> +	if (ret)
> +		goto err;
>   	return 0;
> -
>   err:
>   	drm_unset_busid(dev, master);
>   	return ret;
> diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
> index 3dadfa2..cb49685 100644
> --- a/drivers/gpu/drm/drm_irq.c
> +++ b/drivers/gpu/drm/drm_irq.c
> @@ -74,23 +74,13 @@ int drm_irq_by_busid(struct drm_device *dev, void *data,
>   {
>   	struct drm_irq_busid *p = data;
>
> -	if (drm_core_check_feature(dev, DRIVER_USE_PLATFORM_DEVICE))
> +	if (!dev->driver->bus->irq_by_busid)
>   		return -EINVAL;
>
>   	if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
>   		return -EINVAL;
>
> -	if ((p->busnum>>  8) != drm_get_pci_domain(dev) ||
> -	    (p->busnum&  0xff) != dev->pdev->bus->number ||
> -	    p->devnum != PCI_SLOT(dev->pdev->devfn) || p->funcnum != PCI_FUNC(dev->pdev->devfn))
> -		return -EINVAL;
> -
> -	p->irq = dev->pdev->irq;
> -
> -	DRM_DEBUG("%d:%d:%d =>  IRQ %d\n", p->busnum, p->devnum, p->funcnum,
> -		  p->irq);
> -
> -	return 0;
> +	return dev->driver->bus->irq_by_busid(dev, p);
>   }
>
>   /*
> diff --git a/drivers/gpu/drm/drm_pci.c b/drivers/gpu/drm/drm_pci.c
> index f5bd9e5..e1aee4f 100644
> --- a/drivers/gpu/drm/drm_pci.c
> +++ b/drivers/gpu/drm/drm_pci.c
> @@ -125,6 +125,176 @@ void drm_pci_free(struct drm_device * dev, drm_dma_handle_t * dmah)
>   EXPORT_SYMBOL(drm_pci_free);
>
>   #ifdef CONFIG_PCI
> +
> +static int drm_get_pci_domain(struct drm_device *dev)
> +{
> +#ifndef __alpha__
> +	/* For historical reasons, drm_get_pci_domain() is busticated
> +	 * on most archs and has to remain so for userspace interface
> +	 *<  1.4, except on alpha which was right from the beginning
> +	 */
> +	if (dev->if_version<  0x10004)
> +		return 0;
> +#endif /* __alpha__ */
> +
> +	return pci_domain_nr(dev->pdev->bus);
> +}
> +
> +static int drm_pci_get_irq(struct drm_device *dev)
> +{
> +	return dev->pdev->irq;
> +}
> +
> +static const char *drm_pci_get_name(struct drm_device *dev)
> +{
> +	struct pci_driver *pdriver = dev->driver->kdriver.pci;
> +	return pdriver->name;
> +}
> +
> +int drm_pci_set_busid(struct drm_device *dev, struct drm_master *master)
> +{
> +	int len, ret;
> +	struct pci_driver *pdriver = dev->driver->kdriver.pci;
> +	master->unique_len = 40;
> +	master->unique_size = master->unique_len;
> +	master->unique = kmalloc(master->unique_size, GFP_KERNEL);
> +	if (master->unique == NULL)
> +		return -ENOMEM;
> +
> +
> +	len = snprintf(master->unique, master->unique_len,
> +		       "pci:%04x:%02x:%02x.%d",
> +		       drm_get_pci_domain(dev),
> +		       dev->pdev->bus->number,
> +		       PCI_SLOT(dev->pdev->devfn),
> +		       PCI_FUNC(dev->pdev->devfn));
> +
> +	if (len>= master->unique_len) {
> +		DRM_ERROR("buffer overflow");
> +		ret = -EINVAL;
> +		goto err;
> +	} else
> +		master->unique_len = len;
> +
> +	dev->devname =
> +		kmalloc(strlen(pdriver->name) +
> +			master->unique_len + 2, GFP_KERNEL);
> +
> +	if (dev->devname == NULL) {
> +		ret = -ENOMEM;
> +		goto err;
> +	}
> +
> +	sprintf(dev->devname, "%s@%s", pdriver->name,
> +		master->unique);
> +
> +	return 0;
> +err:
> +	return ret;
> +}
> +
> +int drm_pci_set_unique(struct drm_device *dev,
> +		       struct drm_master *master,
> +		       struct drm_unique *u)
> +{
> +	int domain, bus, slot, func, ret;
> +	const char *bus_name;
> +
> +	master->unique_len = u->unique_len;
> +	master->unique_size = u->unique_len + 1;
> +	master->unique = kmalloc(master->unique_size, GFP_KERNEL);
> +	if (!master->unique) {
> +		ret = -ENOMEM;
> +		goto err;
> +	}
> +
> +	if (copy_from_user(master->unique, u->unique, master->unique_len)) {
> +		ret = -EFAULT;
> +		goto err;
> +	}
> +
> +	master->unique[master->unique_len] = '\0';
> +
> +	bus_name = dev->driver->bus->get_name(dev);
> +	dev->devname = kmalloc(strlen(bus_name) +
> +			       strlen(master->unique) + 2, GFP_KERNEL);
> +	if (!dev->devname) {
> +		ret = -ENOMEM;
> +		goto err;
> +	}
> +
> +	sprintf(dev->devname, "%s@%s", bus_name,
> +		master->unique);
> +
> +	/* Return error if the busid submitted doesn't match the device's actual
> +	 * busid.
> +	 */
> +	ret = sscanf(master->unique, "PCI:%d:%d:%d",&bus,&slot,&func);
> +	if (ret != 3) {
> +		ret = -EINVAL;
> +		goto err;
> +	}
> +
> +	domain = bus>>  8;
> +	bus&= 0xff;
> +
> +	if ((domain != drm_get_pci_domain(dev)) ||
> +	    (bus != dev->pdev->bus->number) ||
> +	    (slot != PCI_SLOT(dev->pdev->devfn)) ||
> +	    (func != PCI_FUNC(dev->pdev->devfn))) {
> +		ret = -EINVAL;
> +		goto err;
> +	}
> +	return 0;
> +err:
> +	return ret;
> +}
> +
> +
> +int drm_pci_irq_by_busid(struct drm_device *dev, struct drm_irq_busid *p)
> +{
> +	if ((p->busnum>>  8) != drm_get_pci_domain(dev) ||
> +	    (p->busnum&  0xff) != dev->pdev->bus->number ||
> +	    p->devnum != PCI_SLOT(dev->pdev->devfn) || p->funcnum != PCI_FUNC(dev->pdev->devfn))
> +		return -EINVAL;
> +
> +	p->irq = dev->pdev->irq;
> +
> +	DRM_DEBUG("%d:%d:%d =>  IRQ %d\n", p->busnum, p->devnum, p->funcnum,
> +		  p->irq);
> +	return 0;
> +}
> +
> +int drm_pci_agp_init(struct drm_device *dev)
> +{
> +	if (drm_core_has_AGP(dev)) {
> +		if (drm_pci_device_is_agp(dev))
> +			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");
> +			return -EINVAL;
> +		}
> +		if (drm_core_has_MTRR(dev)) {
> +			if (dev->agp)
> +				dev->agp->agp_mtrr =
> +					mtrr_add(dev->agp->agp_info.aper_base,
> +						 dev->agp->agp_info.aper_size *
> +						 1024 * 1024, MTRR_TYPE_WRCOMB, 1);
> +		}
> +	}
> +	return 0;
> +}
> +
> +static struct drm_bus drm_pci_bus = {
> +	.bus_type = DRIVER_BUS_PCI,
> +	.get_irq = drm_pci_get_irq,
> +	.get_name = drm_pci_get_name,
> +	.set_busid = drm_pci_set_busid,
> +	.set_unique = drm_pci_set_unique,
> +	.agp_init = drm_pci_agp_init,
> +};
> +
>   /**
>    * Register.
>    *
> @@ -219,7 +389,7 @@ err_g1:
>   EXPORT_SYMBOL(drm_get_pci_dev);
>
>   /**
> - * PCI device initialization. Called via drm_init at module load time,
> + * PCI device initialization. Called direct from modules at load time.
>    *
>    * \return zero on success or a negative number on failure.
>    *
> @@ -229,18 +399,24 @@ EXPORT_SYMBOL(drm_get_pci_dev);
>    * Expands the \c DRIVER_PREINIT and \c DRIVER_POST_INIT macros before and
>    * after the initialization for driver customization.
>    */
> -int drm_pci_init(struct drm_driver *driver)
> +int drm_pci_init(struct drm_driver *driver, struct pci_driver *pdriver)
>   {
>   	struct pci_dev *pdev = NULL;
>   	const struct pci_device_id *pid;
>   	int i;
>
> +	DRM_DEBUG("\n");
> +
> +	INIT_LIST_HEAD(&driver->device_list);
> +	driver->kdriver.pci = pdriver;
> +	driver->bus =&drm_pci_bus;
> +
>   	if (driver->driver_features&  DRIVER_MODESET)
> -		return pci_register_driver(&driver->pci_driver);
> +		return pci_register_driver(pdriver);
>
>   	/* If not using KMS, fall back to stealth mode manual scanning. */
> -	for (i = 0; driver->pci_driver.id_table[i].vendor != 0; i++) {
> -		pid =&driver->pci_driver.id_table[i];
> +	for (i = 0; pdriver->id_table[i].vendor != 0; i++) {
> +		pid =&pdriver->id_table[i];
>
>   		/* Loop around setting up a DRM device for each PCI device
>   		 * matching our ID and device class.  If we had the internal
> @@ -265,10 +441,27 @@ int drm_pci_init(struct drm_driver *driver)
>
>   #else
>
> -int drm_pci_init(struct drm_driver *driver)
> +int drm_pci_init(struct drm_driver *driver, struct pci_driver *pdriver)
>   {
>   	return -1;
>   }
>
>   #endif
> +
> +EXPORT_SYMBOL(drm_pci_init);
> +
>   /*@}*/
> +void drm_pci_exit(struct drm_driver *driver, struct pci_driver *pdriver)
> +{
> +	struct drm_device *dev, *tmp;
> +	DRM_DEBUG("\n");
> +
> +	if (driver->driver_features&  DRIVER_MODESET) {
> +		pci_unregister_driver(pdriver);
> +	} else {
> +		list_for_each_entry_safe(dev, tmp,&driver->device_list, driver_item)
> +			drm_put_dev(dev);
> +	}
> +	DRM_INFO("Module unloaded\n");
> +}
> +EXPORT_SYMBOL(drm_pci_exit);
> diff --git a/drivers/gpu/drm/drm_platform.c b/drivers/gpu/drm/drm_platform.c
> index 92d1d0f..7223f06 100644
> --- a/drivers/gpu/drm/drm_platform.c
> +++ b/drivers/gpu/drm/drm_platform.c
> @@ -109,8 +109,60 @@ err_g1:
>   }
>   EXPORT_SYMBOL(drm_get_platform_dev);
>
> +static int drm_platform_get_irq(struct drm_device *dev)
> +{
> +	return platform_get_irq(dev->platformdev, 0);
> +}
> +
> +static const char *drm_platform_get_name(struct drm_device *dev)
> +{
> +	return dev->platformdev->name;
> +}
> +
> +static int drm_platform_set_busid(struct drm_device *dev, struct drm_master *master)
> +{
> +	int len, ret;
> +
> +	master->unique_len = 10 + strlen(dev->platformdev->name);
> +	master->unique = kmalloc(master->unique_len + 1, GFP_KERNEL);
> +
> +	if (master->unique == NULL)
> +		return -ENOMEM;
> +
> +	len = snprintf(master->unique, master->unique_len,
> +		       "platform:%s", dev->platformdev->name);
> +
> +	if (len>  master->unique_len) {
> +		DRM_ERROR("Unique buffer overflowed\n");
> +		ret = -EINVAL;
> +		goto err;
> +	}
> +
> +	dev->devname =
> +		kmalloc(strlen(dev->platformdev->name) +
> +			master->unique_len + 2, GFP_KERNEL);
> +
> +	if (dev->devname == NULL) {
> +		ret = -ENOMEM;
> +		goto err;
> +	}
> +
> +	sprintf(dev->devname, "%s@%s", dev->platformdev->name,
> +		master->unique);
> +	return 0;
> +err:
> +	return ret;
> +}
> +
> +static struct drm_bus drm_platform_bus = {
> +	.bus_type = DRIVER_BUS_PLATFORM,
> +	.get_irq = drm_platform_get_irq,
> +	.get_name = drm_platform_get_name,
> +	.set_busid = drm_platform_set_busid,
> +};
> +
>   /**
> - * Platform device initialization. Called via drm_init at module load time,
> + * Platform device initialization. Called direct from modules.
>    *
>    * \return zero on success or a negative number on failure.
>    *
> @@ -121,7 +173,24 @@ EXPORT_SYMBOL(drm_get_platform_dev);
>    * after the initialization for driver customization.
>    */
>
> -int drm_platform_init(struct drm_driver *driver)
> +int drm_platform_init(struct drm_driver *driver, struct platform_device *platform_device)
>   {
> -	return drm_get_platform_dev(driver->platform_device, driver);
> +	DRM_DEBUG("\n");
> +
> +	driver->kdriver.platform_device = platform_device;
> +	driver->bus =&drm_platform_bus;
> +	INIT_LIST_HEAD(&driver->device_list);
> +	return drm_get_platform_dev(platform_device, driver);
> +}
> +EXPORT_SYMBOL(drm_platform_init);
> +
> +void drm_platform_exit(struct drm_driver *driver, struct platform_device *platform_device)
> +{
> +	struct drm_device *dev, *tmp;
> +	DRM_DEBUG("\n");
> +
> +	list_for_each_entry_safe(dev, tmp,&driver->device_list, driver_item)
> +		drm_put_dev(dev);
> +	DRM_INFO("Module unloaded\n");
>   }
> +EXPORT_SYMBOL(drm_platform_exit);
> diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c
> index d59edc1..0bf2c77 100644
> --- a/drivers/gpu/drm/drm_stub.c
> +++ b/drivers/gpu/drm/drm_stub.c
> @@ -269,25 +269,14 @@ int drm_fill_in_dev(struct drm_device *dev,
>
>   	dev->driver = driver;
>
> -	if (drm_core_has_AGP(dev)) {
> -		if (drm_device_is_agp(dev))
> -			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;
> +	if (dev->driver->bus->agp_init) {
> +		retcode = dev->driver->bus->agp_init(dev);
> +		if (retcode)
>   			goto error_out_unreg;
> -		}
> -		if (drm_core_has_MTRR(dev)) {
> -			if (dev->agp)
> -				dev->agp->agp_mtrr =
> -				    mtrr_add(dev->agp->agp_info.aper_base,
> -					     dev->agp->agp_info.aper_size *
> -					     1024 * 1024, MTRR_TYPE_WRCOMB, 1);
> -		}
>   	}
>
>
> +
>   	retcode = drm_ctxbitmap_init(dev);
>   	if (retcode) {
>   		DRM_ERROR("Cannot allocate memory for context bitmap.\n");
> @@ -425,7 +414,6 @@ int drm_put_minor(struct drm_minor **minor_p)
>    *
>    * Cleans up all DRM device, calling drm_lastclose().
>    *
> - * \sa drm_init
>    */
>   void drm_put_dev(struct drm_device *dev)
>   {
> diff --git a/drivers/gpu/drm/i810/i810_drv.c b/drivers/gpu/drm/i810/i810_drv.c
> index 0152fa2..6f98d05 100644
> --- a/drivers/gpu/drm/i810/i810_drv.c
> +++ b/drivers/gpu/drm/i810/i810_drv.c
> @@ -64,11 +64,6 @@ static struct drm_driver driver = {
>   		 .llseek = noop_llseek,
>   	},
>
> -	.pci_driver = {
> -		 .name = DRIVER_NAME,
> -		 .id_table = pciidlist,
> -	},
> -
>   	.name = DRIVER_NAME,
>   	.desc = DRIVER_DESC,
>   	.date = DRIVER_DATE,
> @@ -77,6 +72,11 @@ static struct drm_driver driver = {
>   	.patchlevel = DRIVER_PATCHLEVEL,
>   };
>
> +static struct pci_driver i810_pci_driver = {
> +	.name = DRIVER_NAME,
> +	.id_table = pciidlist,
> +};
> +
>   static int __init i810_init(void)
>   {
>   	if (num_possible_cpus()>  1) {
> @@ -84,12 +84,12 @@ static int __init i810_init(void)
>   		return -EINVAL;
>   	}
>   	driver.num_ioctls = i810_max_ioctl;
> -	return drm_init(&driver);
> +	return drm_pci_init(&driver,&i810_pci_driver);
>   }
>
>   static void __exit i810_exit(void)
>   {
> -	drm_exit(&driver);
> +	drm_pci_exit(&driver,&i810_pci_driver);
>   }
>
>   module_init(i810_init);
> diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
> index 17fde2f..9ad42d5 100644
> --- a/drivers/gpu/drm/i915/i915_drv.c
> +++ b/drivers/gpu/drm/i915/i915_drv.c
> @@ -719,14 +719,6 @@ static struct drm_driver driver = {
>   		 .llseek = noop_llseek,
>   	},
>
> -	.pci_driver = {
> -		 .name = DRIVER_NAME,
> -		 .id_table = pciidlist,
> -		 .probe = i915_pci_probe,
> -		 .remove = i915_pci_remove,
> -		 .driver.pm =&i915_pm_ops,
> -	},
> -
>   	.name = DRIVER_NAME,
>   	.desc = DRIVER_DESC,
>   	.date = DRIVER_DATE,
> @@ -735,6 +727,14 @@ static struct drm_driver driver = {
>   	.patchlevel = DRIVER_PATCHLEVEL,
>   };
>
> +static struct pci_driver i915_pci_driver = {
> +	.name = DRIVER_NAME,
> +	.id_table = pciidlist,
> +	.probe = i915_pci_probe,
> +	.remove = i915_pci_remove,
> +	.driver.pm =&i915_pm_ops,
> +};
> +
>   static int __init i915_init(void)
>   {
>   	if (!intel_agp_enabled) {
> @@ -768,12 +768,12 @@ static int __init i915_init(void)
>   	if (!(driver.driver_features&  DRIVER_MODESET))
>   		driver.get_vblank_timestamp = NULL;
>
> -	return drm_init(&driver);
> +	return drm_pci_init(&driver,&i915_pci_driver);
>   }
>
>   static void __exit i915_exit(void)
>   {
> -	drm_exit(&driver);
> +	drm_pci_exit(&driver,&i915_pci_driver);
>   }
>
>   module_init(i915_init);
> diff --git a/drivers/gpu/drm/mga/mga_dma.c b/drivers/gpu/drm/mga/mga_dma.c
> index 08868ac..1e1eb1d 100644
> --- a/drivers/gpu/drm/mga/mga_dma.c
> +++ b/drivers/gpu/drm/mga/mga_dma.c
> @@ -703,7 +703,7 @@ static int mga_do_pci_dma_bootstrap(struct drm_device *dev,
>   static int mga_do_dma_bootstrap(struct drm_device *dev,
>   				drm_mga_dma_bootstrap_t *dma_bs)
>   {
> -	const int is_agp = (dma_bs->agp_mode != 0)&&  drm_device_is_agp(dev);
> +	const int is_agp = (dma_bs->agp_mode != 0)&&  drm_pci_device_is_agp(dev);
>   	int err;
>   	drm_mga_private_t *const dev_priv =
>   	    (drm_mga_private_t *) dev->dev_private;
> diff --git a/drivers/gpu/drm/mga/mga_drv.c b/drivers/gpu/drm/mga/mga_drv.c
> index 0aaf5f6..42d3187 100644
> --- a/drivers/gpu/drm/mga/mga_drv.c
> +++ b/drivers/gpu/drm/mga/mga_drv.c
> @@ -75,10 +75,6 @@ static struct drm_driver driver = {
>   #endif
>   		.llseek = noop_llseek,
>   	},
> -	.pci_driver = {
> -		.name = DRIVER_NAME,
> -		.id_table = pciidlist,
> -	},
>
>   	.name = DRIVER_NAME,
>   	.desc = DRIVER_DESC,
> @@ -88,15 +84,20 @@ static struct drm_driver driver = {
>   	.patchlevel = DRIVER_PATCHLEVEL,
>   };
>
> +static struct pci_driver mga_pci_driver = {
> +	.name = DRIVER_NAME,
> +	.id_table = pciidlist,
> +};
> +
>   static int __init mga_init(void)
>   {
>   	driver.num_ioctls = mga_max_ioctl;
> -	return drm_init(&driver);
> +	return drm_pci_init(&driver,&mga_pci_driver);
>   }
>
>   static void __exit mga_exit(void)
>   {
> -	drm_exit(&driver);
> +	drm_pci_exit(&driver,&mga_pci_driver);
>   }
>
>   module_init(mga_init);
> diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.c b/drivers/gpu/drm/nouveau/nouveau_drv.c
> index f658a04..155ebdc 100644
> --- a/drivers/gpu/drm/nouveau/nouveau_drv.c
> +++ b/drivers/gpu/drm/nouveau/nouveau_drv.c
> @@ -408,14 +408,6 @@ static struct drm_driver driver = {
>   #endif
>   		.llseek = noop_llseek,
>   	},
> -	.pci_driver = {
> -		.name = DRIVER_NAME,
> -		.id_table = pciidlist,
> -		.probe = nouveau_pci_probe,
> -		.remove = nouveau_pci_remove,
> -		.suspend = nouveau_pci_suspend,
> -		.resume = nouveau_pci_resume
> -	},
>
>   	.gem_init_object = nouveau_gem_object_new,
>   	.gem_free_object = nouveau_gem_object_del,
> @@ -432,6 +424,15 @@ static struct drm_driver driver = {
>   	.patchlevel = DRIVER_PATCHLEVEL,
>   };
>
> +static struct pci_driver nouveau_pci_driver = {
> +		.name = DRIVER_NAME,
> +		.id_table = pciidlist,
> +		.probe = nouveau_pci_probe,
> +		.remove = nouveau_pci_remove,
> +		.suspend = nouveau_pci_suspend,
> +		.resume = nouveau_pci_resume
> +};
> +
>   static int __init nouveau_init(void)
>   {
>   	driver.num_ioctls = nouveau_max_ioctl;
> @@ -449,7 +450,7 @@ static int __init nouveau_init(void)
>   		return 0;
>
>   	nouveau_register_dsm_handler();
> -	return drm_init(&driver);
> +	return drm_pci_init(&driver,&nouveau_pci_driver);
>   }
>
>   static void __exit nouveau_exit(void)
> @@ -457,7 +458,7 @@ static void __exit nouveau_exit(void)
>   	if (!nouveau_modeset)
>   		return;
>
> -	drm_exit(&driver);
> +	drm_pci_exit(&driver,&nouveau_pci_driver);
>   	nouveau_unregister_dsm_handler();
>   }
>
> diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c
> index 26347b7..123969d 100644
> --- a/drivers/gpu/drm/nouveau/nouveau_mem.c
> +++ b/drivers/gpu/drm/nouveau/nouveau_mem.c
> @@ -480,7 +480,7 @@ nouveau_mem_gart_init(struct drm_device *dev)
>   	dev_priv->gart_info.type = NOUVEAU_GART_NONE;
>
>   #if !defined(__powerpc__)&&  !defined(__ia64__)
> -	if (drm_device_is_agp(dev)&&  dev->agp&&  nouveau_agpmode) {
> +	if (drm_pci_device_is_agp(dev)&&  dev->agp&&  nouveau_agpmode) {
>   		ret = nouveau_mem_init_agp(dev);
>   		if (ret)
>   			NV_ERROR(dev, "Error initialising AGP: %d\n", ret);
> diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c
> index a54fc43..2148d01 100644
> --- a/drivers/gpu/drm/nouveau/nouveau_state.c
> +++ b/drivers/gpu/drm/nouveau/nouveau_state.c
> @@ -1103,9 +1103,9 @@ int nouveau_ioctl_getparam(struct drm_device *dev, void *data,
>   		getparam->value = dev->pci_device;
>   		break;
>   	case NOUVEAU_GETPARAM_BUS_TYPE:
> -		if (drm_device_is_agp(dev))
> +		if (drm_pci_device_is_agp(dev))
>   			getparam->value = NV_AGP;
> -		else if (drm_device_is_pcie(dev))
> +		else if (drm_pci_device_is_pcie(dev))
>   			getparam->value = NV_PCIE;
>   		else
>   			getparam->value = NV_PCI;
> diff --git a/drivers/gpu/drm/r128/r128_drv.c b/drivers/gpu/drm/r128/r128_drv.c
> index 18c3c71..b9e8efd 100644
> --- a/drivers/gpu/drm/r128/r128_drv.c
> +++ b/drivers/gpu/drm/r128/r128_drv.c
> @@ -71,10 +71,7 @@ static struct drm_driver driver = {
>   #endif
>   		.llseek = noop_llseek,
>   	},
> -	.pci_driver = {
> -		.name = DRIVER_NAME,
> -		.id_table = pciidlist,
> -	},
> +
>
>   	.name = DRIVER_NAME,
>   	.desc = DRIVER_DESC,
> @@ -89,16 +86,21 @@ int r128_driver_load(struct drm_device *dev, unsigned long flags)
>   	return drm_vblank_init(dev, 1);
>   }
>
> +static struct pci_driver r128_pci_driver = {
> +	.name = DRIVER_NAME,
> +	.id_table = pciidlist,
> +};
> +
>   static int __init r128_init(void)
>   {
>   	driver.num_ioctls = r128_max_ioctl;
>
> -	return drm_init(&driver);
> +	return drm_pci_init(&driver,&r128_pci_driver);
>   }
>
>   static void __exit r128_exit(void)
>   {
> -	drm_exit(&driver);
> +	drm_pci_exit(&driver,&r128_pci_driver);
>   }
>
>   module_init(r128_init);
> diff --git a/drivers/gpu/drm/radeon/radeon_cp.c b/drivers/gpu/drm/radeon/radeon_cp.c
> index eb6b9ee..3d599e3 100644
> --- a/drivers/gpu/drm/radeon/radeon_cp.c
> +++ b/drivers/gpu/drm/radeon/radeon_cp.c
> @@ -2113,9 +2113,9 @@ int radeon_driver_load(struct drm_device *dev, unsigned long flags)
>   		break;
>   	}
>
> -	if (drm_device_is_agp(dev))
> +	if (drm_pci_device_is_agp(dev))
>   		dev_priv->flags |= RADEON_IS_AGP;
> -	else if (drm_device_is_pcie(dev))
> +	else if (drm_pci_device_is_pcie(dev))
>   		dev_priv->flags |= RADEON_IS_PCIE;
>   	else
>   		dev_priv->flags |= RADEON_IS_PCI;
> diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c
> index ca1b7d4..8a0df3d 100644
> --- a/drivers/gpu/drm/radeon/radeon_drv.c
> +++ b/drivers/gpu/drm/radeon/radeon_drv.c
> @@ -238,11 +238,6 @@ static struct drm_driver driver_old = {
>   		 .llseek = noop_llseek,
>   	},
>
> -	.pci_driver = {
> -		 .name = DRIVER_NAME,
> -		 .id_table = pciidlist,
> -	},
> -
>   	.name = DRIVER_NAME,
>   	.desc = DRIVER_DESC,
>   	.date = DRIVER_DATE,
> @@ -349,15 +344,6 @@ static struct drm_driver kms_driver = {
>   #endif
>   	},
>
> -	.pci_driver = {
> -		 .name = DRIVER_NAME,
> -		 .id_table = pciidlist,
> -		 .probe = radeon_pci_probe,
> -		 .remove = radeon_pci_remove,
> -		 .suspend = radeon_pci_suspend,
> -		 .resume = radeon_pci_resume,
> -	},
> -
>   	.name = DRIVER_NAME,
>   	.desc = DRIVER_DESC,
>   	.date = DRIVER_DATE,
> @@ -367,15 +353,32 @@ static struct drm_driver kms_driver = {
>   };
>
>   static struct drm_driver *driver;
> +static struct pci_driver *pdriver;
> +
> +static struct pci_driver radeon_pci_driver = {
> +	.name = DRIVER_NAME,
> +	.id_table = pciidlist,
> +};
> +
> +static struct pci_driver radeon_kms_pci_driver = {
> +	.name = DRIVER_NAME,
> +	.id_table = pciidlist,
> +	.probe = radeon_pci_probe,
> +	.remove = radeon_pci_remove,
> +	.suspend = radeon_pci_suspend,
> +	.resume = radeon_pci_resume,
> +};
>
>   static int __init radeon_init(void)
>   {
>   	driver =&driver_old;
> +	pdriver =&radeon_pci_driver;
>   	driver->num_ioctls = radeon_max_ioctl;
>   #ifdef CONFIG_VGA_CONSOLE
>   	if (vgacon_text_force()&&  radeon_modeset == -1) {
>   		DRM_INFO("VGACON disable radeon kernel modesetting.\n");
>   		driver =&driver_old;
> +		pdriver =&radeon_pci_driver;
>   		driver->driver_features&= ~DRIVER_MODESET;
>   		radeon_modeset = 0;
>   	}
> @@ -393,18 +396,19 @@ static int __init radeon_init(void)
>   	if (radeon_modeset == 1) {
>   		DRM_INFO("radeon kernel modesetting enabled.\n");
>   		driver =&kms_driver;
> +		pdriver =&radeon_kms_pci_driver;
>   		driver->driver_features |= DRIVER_MODESET;
>   		driver->num_ioctls = radeon_max_kms_ioctl;
>   		radeon_register_atpx_handler();
>   	}
>   	/* if the vga console setting is enabled still
>   	 * let modprobe override it */
> -	return drm_init(driver);
> +	return drm_pci_init(driver, pdriver);
>   }
>
>   static void __exit radeon_exit(void)
>   {
> -	drm_exit(driver);
> +	drm_pci_exit(driver, pdriver);
>   	radeon_unregister_atpx_handler();
>   }
>
> diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c
> index 8387d32..4057ebf 100644
> --- a/drivers/gpu/drm/radeon/radeon_kms.c
> +++ b/drivers/gpu/drm/radeon/radeon_kms.c
> @@ -58,9 +58,9 @@ int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags)
>   	dev->dev_private = (void *)rdev;
>
>   	/* update BUS flag */
> -	if (drm_device_is_agp(dev)) {
> +	if (drm_pci_device_is_agp(dev)) {
>   		flags |= RADEON_IS_AGP;
> -	} else if (drm_device_is_pcie(dev)) {
> +	} else if (drm_pci_device_is_pcie(dev)) {
>   		flags |= RADEON_IS_PCIE;
>   	} else {
>   		flags |= RADEON_IS_PCI;
> diff --git a/drivers/gpu/drm/savage/savage_drv.c b/drivers/gpu/drm/savage/savage_drv.c
> index fa64d25..6464490 100644
> --- a/drivers/gpu/drm/savage/savage_drv.c
> +++ b/drivers/gpu/drm/savage/savage_drv.c
> @@ -55,11 +55,6 @@ static struct drm_driver driver = {
>   		 .llseek = noop_llseek,
>   	},
>
> -	.pci_driver = {
> -		 .name = DRIVER_NAME,
> -		 .id_table = pciidlist,
> -	},
> -
>   	.name = DRIVER_NAME,
>   	.desc = DRIVER_DESC,
>   	.date = DRIVER_DATE,
> @@ -68,15 +63,20 @@ static struct drm_driver driver = {
>   	.patchlevel = DRIVER_PATCHLEVEL,
>   };
>
> +static struct pci_driver savage_pci_driver = {
> +	.name = DRIVER_NAME,
> +	.id_table = pciidlist,
> +};
> +
>   static int __init savage_init(void)
>   {
>   	driver.num_ioctls = savage_max_ioctl;
> -	return drm_init(&driver);
> +	return drm_pci_init(&driver,&savage_pci_driver);
>   }
>
>   static void __exit savage_exit(void)
>   {
> -	drm_exit(&driver);
> +	drm_pci_exit(&driver,&savage_pci_driver);
>   }
>
>   module_init(savage_init);
> diff --git a/drivers/gpu/drm/sis/sis_drv.c b/drivers/gpu/drm/sis/sis_drv.c
> index 4caf5d0..46d5be6 100644
> --- a/drivers/gpu/drm/sis/sis_drv.c
> +++ b/drivers/gpu/drm/sis/sis_drv.c
> @@ -82,10 +82,6 @@ static struct drm_driver driver = {
>   		 .fasync = drm_fasync,
>   		 .llseek = noop_llseek,
>   	},
> -	.pci_driver = {
> -		 .name = DRIVER_NAME,
> -		 .id_table = pciidlist,
> -	},
>
>   	.name = DRIVER_NAME,
>   	.desc = DRIVER_DESC,
> @@ -95,15 +91,20 @@ static struct drm_driver driver = {
>   	.patchlevel = DRIVER_PATCHLEVEL,
>   };
>
> +static struct pci_driver sis_pci_driver = {
> +	.name = DRIVER_NAME,
> +	.id_table = pciidlist,
> +};
> +
>   static int __init sis_init(void)
>   {
>   	driver.num_ioctls = sis_max_ioctl;
> -	return drm_init(&driver);
> +	return drm_pci_init(&driver,&sis_pci_driver);
>   }
>
>   static void __exit sis_exit(void)
>   {
> -	drm_exit(&driver);
> +	drm_pci_exit(&driver,&sis_pci_driver);
>   }
>
>   module_init(sis_init);
> diff --git a/drivers/gpu/drm/tdfx/tdfx_drv.c b/drivers/gpu/drm/tdfx/tdfx_drv.c
> index b70fa91..8bf9881 100644
> --- a/drivers/gpu/drm/tdfx/tdfx_drv.c
> +++ b/drivers/gpu/drm/tdfx/tdfx_drv.c
> @@ -52,10 +52,6 @@ static struct drm_driver driver = {
>   		 .fasync = drm_fasync,
>   		 .llseek = noop_llseek,
>   	},
> -	.pci_driver = {
> -		 .name = DRIVER_NAME,
> -		 .id_table = pciidlist,
> -	},
>
>   	.name = DRIVER_NAME,
>   	.desc = DRIVER_DESC,
> @@ -65,14 +61,19 @@ static struct drm_driver driver = {
>   	.patchlevel = DRIVER_PATCHLEVEL,
>   };
>
> +static struct pci_driver tdfx_pci_driver = {
> +	.name = DRIVER_NAME,
> +	.id_table = pciidlist,
> +};
> +
>   static int __init tdfx_init(void)
>   {
> -	return drm_init(&driver);
> +	return drm_pci_init(&driver,&tdfx_pci_driver);
>   }
>
>   static void __exit tdfx_exit(void)
>   {
> -	drm_exit(&driver);
> +	drm_pci_exit(&driver,&tdfx_pci_driver);
>   }
>
>   module_init(tdfx_init);
> diff --git a/drivers/gpu/drm/via/via_drv.c b/drivers/gpu/drm/via/via_drv.c
> index e1ff4e7..920a552 100644
> --- a/drivers/gpu/drm/via/via_drv.c
> +++ b/drivers/gpu/drm/via/via_drv.c
> @@ -62,10 +62,6 @@ static struct drm_driver driver = {
>   		.fasync = drm_fasync,
>   		.llseek = noop_llseek,
>   		},
> -	.pci_driver = {
> -		.name = DRIVER_NAME,
> -		.id_table = pciidlist,
> -	},
>
>   	.name = DRIVER_NAME,
>   	.desc = DRIVER_DESC,
> @@ -75,16 +71,21 @@ static struct drm_driver driver = {
>   	.patchlevel = DRIVER_PATCHLEVEL,
>   };
>
> +static struct pci_driver via_pci_driver = {
> +	.name = DRIVER_NAME,
> +	.id_table = pciidlist,
> +};
> +
>   static int __init via_init(void)
>   {
>   	driver.num_ioctls = via_max_ioctl;
>   	via_init_command_verifier();
> -	return drm_init(&driver);
> +	return drm_pci_init(&driver,&via_pci_driver);
>   }
>
>   static void __exit via_exit(void)
>   {
> -	drm_exit(&driver);
> +	drm_pci_exit(&driver,&via_pci_driver);
>   }
>
>   module_init(via_init);
> diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
> index 10ca97e..96949b9 100644
> --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
> +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
> @@ -909,15 +909,6 @@ static struct drm_driver driver = {
>   #endif
>   		 .llseek = noop_llseek,
>   	},
> -	.pci_driver = {
> -		 .name = VMWGFX_DRIVER_NAME,
> -		 .id_table = vmw_pci_id_list,
> -		 .probe = vmw_probe,
> -		 .remove = vmw_remove,
> -		 .driver = {
> -			 .pm =&vmw_pm_ops
> -		 }
> -	 },
>   	.name = VMWGFX_DRIVER_NAME,
>   	.desc = VMWGFX_DRIVER_DESC,
>   	.date = VMWGFX_DRIVER_DATE,
> @@ -926,6 +917,16 @@ static struct drm_driver driver = {
>   	.patchlevel = VMWGFX_DRIVER_PATCHLEVEL
>   };
>
> +static struct pci_driver vmw_pci_driver = {
> +	.name = VMWGFX_DRIVER_NAME,
> +	.id_table = vmw_pci_id_list,
> +	.probe = vmw_probe,
> +	.remove = vmw_remove,
> +	.driver = {
> +		.pm =&vmw_pm_ops
> +	}
> +};
> +
>   static int vmw_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
>   {
>   	return drm_get_pci_dev(pdev, ent,&driver);
> @@ -934,7 +935,7 @@ static int vmw_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
>   static int __init vmwgfx_init(void)
>   {
>   	int ret;
> -	ret = drm_init(&driver);
> +	ret = drm_pci_init(&driver,&vmw_pci_driver);
>   	if (ret)
>   		DRM_ERROR("Failed initializing DRM.\n");
>   	return ret;
> @@ -942,7 +943,7 @@ static int __init vmwgfx_init(void)
>
>   static void __exit vmwgfx_exit(void)
>   {
> -	drm_exit(&driver);
> +	drm_pci_exit(&driver,&vmw_pci_driver);
>   }
>
>   module_init(vmwgfx_init);
> diff --git a/include/drm/drmP.h b/include/drm/drmP.h
> index 3cbe7a0..a99aefb 100644
> --- a/include/drm/drmP.h
> +++ b/include/drm/drmP.h
> @@ -145,7 +145,10 @@ extern void drm_ut_debug_printk(unsigned int request_level,
>   #define DRIVER_IRQ_VBL2    0x800
>   #define DRIVER_GEM         0x1000
>   #define DRIVER_MODESET     0x2000
> -#define DRIVER_USE_PLATFORM_DEVICE  0x4000
> +
> +#define DRIVER_BUS_PCI 0x1
> +#define DRIVER_BUS_PLATFORM 0x2
> +#define DRIVER_BUS_USB 0x3
>
>   /***********************************************************************/
>   /** \name Begin the DRM... */
> @@ -698,6 +701,19 @@ struct drm_master {
>   #define DRM_SCANOUTPOS_INVBL        (1<<  1)
>   #define DRM_SCANOUTPOS_ACCURATE     (1<<  2)
>
> +struct drm_bus {
> +	int bus_type;
> +	int (*get_irq)(struct drm_device *dev);
> +	const char *(*get_name)(struct drm_device *dev);
> +	int (*set_busid)(struct drm_device *dev, struct drm_master *master);
> +	int (*set_unique)(struct drm_device *dev, struct drm_master *master,
> +			  struct drm_unique *unique);
> +	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);
> +
> +};
> +
>   /**
>    * DRM driver structure. This structure represent the common code for
>    * a family of cards. There will one drm_device for each card present
> @@ -906,8 +922,12 @@ struct drm_driver {
>   	struct drm_ioctl_desc *ioctls;
>   	int num_ioctls;
>   	struct file_operations fops;
> -	struct pci_driver pci_driver;
> -	struct platform_device *platform_device;
> +	union {
> +		struct pci_driver *pci;
> +		struct platform_device *platform_device;
> +	} kdriver;
> +	struct drm_bus *bus;
> +
>   	/* List of devices hanging off this driver */
>   	struct list_head device_list;
>   };
> @@ -1147,28 +1167,9 @@ static __inline__ int drm_core_check_feature(struct drm_device *dev,
>
>   static inline int drm_dev_to_irq(struct drm_device *dev)
>   {
> -	if (drm_core_check_feature(dev, DRIVER_USE_PLATFORM_DEVICE))
> -		return platform_get_irq(dev->platformdev, 0);
> -	else
> -		return dev->pdev->irq;
> +	return dev->driver->bus->get_irq(dev);
>   }
>
> -static inline int drm_get_pci_domain(struct drm_device *dev)
> -{
> -	if (drm_core_check_feature(dev, DRIVER_USE_PLATFORM_DEVICE))
> -		return 0;
> -
> -#ifndef __alpha__
> -	/* For historical reasons, drm_get_pci_domain() is busticated
> -	 * on most archs and has to remain so for userspace interface
> -	 *<  1.4, except on alpha which was right from the beginning
> -	 */
> -	if (dev->if_version<  0x10004)
> -		return 0;
> -#endif /* __alpha__ */
> -
> -	return pci_domain_nr(dev->pdev->bus);
> -}
>
>   #if __OS_HAS_AGP
>   static inline int drm_core_has_AGP(struct drm_device *dev)
> @@ -1222,8 +1223,6 @@ static inline int drm_mtrr_del(int handle, unsigned long offset,
>   /*@{*/
>
>   				/* Driver support (drm_drv.h) */
> -extern int drm_init(struct drm_driver *driver);
> -extern void drm_exit(struct drm_driver *driver);
>   extern long drm_ioctl(struct file *filp,
>   		      unsigned int cmd, unsigned long arg);
>   extern long drm_compat_ioctl(struct file *filp,
> @@ -1433,11 +1432,7 @@ extern int drm_dropmaster_ioctl(struct drm_device *dev, void *data,
>   struct drm_master *drm_master_create(struct drm_minor *minor);
>   extern struct drm_master *drm_master_get(struct drm_master *master);
>   extern void drm_master_put(struct drm_master **master);
> -extern int drm_get_pci_dev(struct pci_dev *pdev,
> -			   const struct pci_device_id *ent,
> -			   struct drm_driver *driver);
> -extern int drm_get_platform_dev(struct platform_device *pdev,
> -				struct drm_driver *driver);
> +
>   extern void drm_put_dev(struct drm_device *dev);
>   extern int drm_put_minor(struct drm_minor **minor);
>   extern unsigned int drm_debug;
> @@ -1628,11 +1623,21 @@ static __inline__ struct drm_local_map *drm_core_findmap(struct drm_device *dev,
>   	return NULL;
>   }
>
> -static __inline__ int drm_device_is_agp(struct drm_device *dev)
> +static __inline__ void drm_core_dropmap(struct drm_local_map *map)
>   {
> -	if (drm_core_check_feature(dev, DRIVER_USE_PLATFORM_DEVICE))
> -		return 0;
> +}
> +
> +#include "drm_mem_util.h"
>
> +extern int drm_fill_in_dev(struct drm_device *dev,
> +			   const struct pci_device_id *ent,
> +			   struct drm_driver *driver);
> +int drm_get_minor(struct drm_device *dev, struct drm_minor **minor, int type);
> +/*@}*/
> +
> +/* PCI section */
> +static __inline__ int drm_pci_device_is_agp(struct drm_device *dev)
> +{
>   	if (dev->driver->device_is_agp != NULL) {
>   		int err = (*dev->driver->device_is_agp) (dev);
>
> @@ -1644,35 +1649,26 @@ static __inline__ int drm_device_is_agp(struct drm_device *dev)
>   	return pci_find_capability(dev->pdev, PCI_CAP_ID_AGP);
>   }
>
> -static __inline__ int drm_device_is_pcie(struct drm_device *dev)
> -{
> -	if (drm_core_check_feature(dev, DRIVER_USE_PLATFORM_DEVICE))
> -		return 0;
> -	else
> -		return pci_find_capability(dev->pdev, PCI_CAP_ID_EXP);
> -}
>
> -static __inline__ void drm_core_dropmap(struct drm_local_map *map)
> +static __inline__ int drm_pci_device_is_pcie(struct drm_device *dev)
>   {
> +	return pci_find_capability(dev->pdev, PCI_CAP_ID_EXP);
>   }
>
> -#include "drm_mem_util.h"
>
> -static inline void *drm_get_device(struct drm_device *dev)
> -{
> -	if (drm_core_check_feature(dev, DRIVER_USE_PLATFORM_DEVICE))
> -		return dev->platformdev;
> -	else
> -		return dev->pdev;
> -}
> -
> -extern int drm_platform_init(struct drm_driver *driver);
> -extern int drm_pci_init(struct drm_driver *driver);
> -extern int drm_fill_in_dev(struct drm_device *dev,
> +extern int drm_pci_init(struct drm_driver *driver, struct pci_driver *pdriver);
> +extern void drm_pci_exit(struct drm_driver *driver, struct pci_driver *pdriver);
> +extern int drm_get_pci_dev(struct pci_dev *pdev,
>   			   const struct pci_device_id *ent,
>   			   struct drm_driver *driver);
> -int drm_get_minor(struct drm_device *dev, struct drm_minor **minor, int type);
> -/*@}*/
> +
> +
> +/* platform section */
> +extern int drm_platform_init(struct drm_driver *driver, struct platform_device *platform_device);
> +extern void drm_platform_exit(struct drm_driver *driver, struct platform_device *platform_device);
> +
> +extern int drm_get_platform_dev(struct platform_device *pdev,
> +				struct drm_driver *driver);
>
>   #endif				/* __KERNEL__ */
>   #endif


More information about the dri-devel mailing list