[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