Commit 8410ea3b authored by Dave Airlie's avatar Dave Airlie Committed by Dave Airlie

drm: rework PCI/platform driver interface.

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: default avatarDave Airlie <airlied@redhat.com>
parent ff72145b
......@@ -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,
......
......@@ -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)) {
bus_name = dev->driver->bus->get_name(dev);
if (master->unique) {
seq_printf(m, "%s %s %s\n",
dev->driver->platform_device->name,
bus_name,
dev_name(dev->dev), master->unique);
} else {
seq_printf(m, "%s\n",
dev->driver->platform_device->name);
seq_printf(m, "%s %s\n",
bus_name, dev_name(dev->dev));
}
} 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));
}
}
return 0;
}
......
......@@ -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 @@ int drm_setunique(struct drm_device *dev, void *data,
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;
ret = dev->driver->bus->set_busid(dev, master);
if (ret)
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);
}
return 0;
err:
drm_unset_busid(dev, master);
return ret;
......
......@@ -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);
}
/*
......
......@@ -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 @@ int drm_get_pci_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
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);
......@@ -109,8 +109,60 @@ int drm_get_platform_dev(struct platform_device *platdev,
}
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);
......@@ -269,23 +269,12 @@ 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);
......@@ -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)
{
......
......@@ -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);
......
......@@ -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);
......
......@@ -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;
......
......@@ -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);
......
......@@ -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();
}
......
......@@ -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);
......
......@@ -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;
......
......@@ -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);
......
......@@ -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;
......
......@@ -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();
}
......
......@@ -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;
......
......@@ -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);
......
......@@ -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);
......
......@@ -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);
......
......@@ -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);
......
......@@ -909,7 +909,15 @@ static struct drm_driver driver = {
#endif
.llseek = noop_llseek,
},
.pci_driver = {
.name = VMWGFX_DRIVER_NAME,
.desc = VMWGFX_DRIVER_DESC,
.date = VMWGFX_DRIVER_DATE,
.major = VMWGFX_DRIVER_MAJOR,
.minor = VMWGFX_DRIVER_MINOR,
.patchlevel = VMWGFX_DRIVER_PATCHLEVEL
};
static struct pci_driver vmw_pci_driver = {
.name = VMWGFX_DRIVER_NAME,
.id_table = vmw_pci_id_list,
.probe = vmw_probe,
......@@ -917,13 +925,6 @@ static struct drm_driver driver = {
.driver = {
.pm = &vmw_pm_ops
}
},
.name = VMWGFX_DRIVER_NAME,
.desc = VMWGFX_DRIVER_DESC,
.date = VMWGFX_DRIVER_DATE,
.major = VMWGFX_DRIVER_MAJOR,
.minor = VMWGFX_DRIVER_MINOR,
.patchlevel = VMWGFX_DRIVER_PATCHLEVEL
};
static int vmw_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
......@@ -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);
......
......@@ -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;
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)
static __inline__ int drm_pci_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)
{
}
#include "drm_mem_util.h"
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);
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,
const struct pci_device_id *ent,
/* 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);
int drm_get_minor(struct drm_device *dev, struct drm_minor **minor, int type);
/*@}*/
#endif /* __KERNEL__ */
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment