drm: rework PCI/platform driver interface.
Dave Airlie [Tue, 14 Dec 2010 17:16:38 +0000 (03:16 +1000)]
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@redhat.com>

24 files changed:
drivers/gpu/drm/drm_drv.c
drivers/gpu/drm/drm_info.c
drivers/gpu/drm/drm_ioctl.c
drivers/gpu/drm/drm_irq.c
drivers/gpu/drm/drm_pci.c
drivers/gpu/drm/drm_platform.c
drivers/gpu/drm/drm_stub.c
drivers/gpu/drm/i810/i810_drv.c
drivers/gpu/drm/i915/i915_drv.c
drivers/gpu/drm/mga/mga_dma.c
drivers/gpu/drm/mga/mga_drv.c
drivers/gpu/drm/nouveau/nouveau_drv.c
drivers/gpu/drm/nouveau/nouveau_mem.c
drivers/gpu/drm/nouveau/nouveau_state.c
drivers/gpu/drm/r128/r128_drv.c
drivers/gpu/drm/radeon/radeon_cp.c
drivers/gpu/drm/radeon/radeon_drv.c
drivers/gpu/drm/radeon/radeon_kms.c
drivers/gpu/drm/savage/savage_drv.c
drivers/gpu/drm/sis/sis_drv.c
drivers/gpu/drm/tdfx/tdfx_drv.c
drivers/gpu/drm/via/via_drv.c
drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
include/drm/drmP.h

index 3e99198..0d04914 100644 (file)
@@ -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,
index 3cdbaf3..812aaac 100644 (file)
@@ -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;
 }
 
index 47db4df..1174905 100644 (file)
@@ -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;
index 3dadfa2..cb49685 100644 (file)
@@ -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);
 }
 
 /*
index f5bd9e5..e1aee4f 100644 (file)
@@ -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);
index 92d1d0f..7223f06 100644 (file)
@@ -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);
index d59edc1..0bf2c77 100644 (file)
@@ -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)
 {
index 0152fa2..6f98d05 100644 (file)
@@ -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);
index 17fde2f..9ad42d5 100644 (file)
@@ -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);
index 08868ac..1e1eb1d 100644 (file)
@@ -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;
index 0aaf5f6..42d3187 100644 (file)
@@ -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);
index f658a04..155ebdc 100644 (file)
@@ -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();
 }
 
index 26347b7..123969d 100644 (file)
@@ -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);
index a54fc43..2148d01 100644 (file)
@@ -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;
index 18c3c71..b9e8efd 100644 (file)
@@ -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);
index eb6b9ee..3d599e3 100644 (file)
@@ -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;
index ca1b7d4..8a0df3d 100644 (file)
@@ -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();
 }
 
index 8387d32..4057ebf 100644 (file)
@@ -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;
index fa64d25..6464490 100644 (file)
@@ -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);
index 4caf5d0..46d5be6 100644 (file)
@@ -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);
index b70fa91..8bf9881 100644 (file)
@@ -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);
index e1ff4e7..920a552 100644 (file)
@@ -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);
index 10ca97e..96949b9 100644 (file)
@@ -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);
index 3cbe7a0..a99aefb 100644 (file)
@@ -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