aboutsummaryrefslogtreecommitdiff
path: root/drivers/gpu/drm
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r--drivers/gpu/drm/Kconfig8
-rw-r--r--drivers/gpu/drm/drm_bufs.c2
-rw-r--r--drivers/gpu/drm/drm_drv.c30
-rw-r--r--drivers/gpu/drm/drm_ioctl.c140
-rw-r--r--drivers/gpu/drm/drm_proc.c21
-rw-r--r--drivers/gpu/drm/drm_stub.c80
-rw-r--r--drivers/gpu/drm/drm_sysfs.c6
7 files changed, 228 insertions, 59 deletions
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 5130b72d593..44f95952a8f 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -6,7 +6,7 @@
#
menuconfig DRM
tristate "Direct Rendering Manager (XFree86 4.1.0 and higher DRI support)"
- depends on (AGP || AGP=n) && PCI && !EMULATED_CMPXCHG && MMU
+ depends on (AGP || AGP=n) && !EMULATED_CMPXCHG && MMU
select I2C
select I2C_ALGOBIT
help
@@ -95,7 +95,7 @@ config DRM_I915_KMS
config DRM_MGA
tristate "Matrox g200/g400"
- depends on DRM
+ depends on DRM && PCI && AGP
help
Choose this option if you have a Matrox G200, G400 or G450 graphics
card. If M is selected, the module will be called mga. AGP
@@ -112,14 +112,14 @@ config DRM_SIS
config DRM_VIA
tristate "Via unichrome video cards"
- depends on DRM
+ depends on DRM && PCI
help
Choose this option if you have a Via unichrome or compatible video
chipset. If M is selected the module will be called via.
config DRM_SAVAGE
tristate "Savage video cards"
- depends on DRM
+ depends on DRM && PCI
help
Choose this option if you have a Savage3D/4/SuperSavage/Pro/Twister
chipset. If M is selected the module will be called savage.
diff --git a/drivers/gpu/drm/drm_bufs.c b/drivers/gpu/drm/drm_bufs.c
index 72c667f9bee..f56bc66c38a 100644
--- a/drivers/gpu/drm/drm_bufs.c
+++ b/drivers/gpu/drm/drm_bufs.c
@@ -141,7 +141,7 @@ static int drm_addmap_core(struct drm_device * dev, unsigned int offset,
switch (map->type) {
case _DRM_REGISTERS:
case _DRM_FRAME_BUFFER:
-#if !defined(__sparc__) && !defined(__alpha__) && !defined(__ia64__) && !defined(__powerpc64__) && !defined(__x86_64__)
+#if !defined(__sparc__) && !defined(__alpha__) && !defined(__ia64__) && !defined(__powerpc64__) && !defined(__x86_64__) && !defined(__arm__)
if (map->offset + (map->size-1) < map->offset ||
map->offset < virt_to_phys(high_memory)) {
drm_free(map, sizeof(*map), DRM_MEM_MAPS);
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 14c7a23dc15..4bc5cab825b 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -251,6 +251,7 @@ int drm_lastclose(struct drm_device * dev)
*/
int drm_init(struct drm_driver *driver)
{
+#ifdef CONFIG_PCI
struct pci_dev *pdev = NULL;
struct pci_device_id *pid;
int i;
@@ -280,12 +281,41 @@ int drm_init(struct drm_driver *driver)
drm_get_dev(pdev, pid, driver);
}
}
+#endif
return 0;
}
EXPORT_SYMBOL(drm_init);
/**
+ *
+ * Call this to associate a drm_driver with a platform_device.
+ *
+ * \return zero on success or a negative number on failure.
+ *
+ * This is a replacement for drm_init(), but for platform drivers.
+ * In this case, the caller must provide the matching platform_device
+ *
+ * since there is no physical bus to scan through.
+ *
+ * \sa drm_init
+ *
+ */
+
+int drm_platform_init(struct drm_driver *driver, struct platform_device *pdev,
+ void *priv)
+{
+ DRM_DEBUG("\n");
+
+ INIT_LIST_HEAD(&driver->device_list);
+
+ return drm_get_platform_dev(pdev, driver, priv);
+}
+
+EXPORT_SYMBOL(drm_platform_init);
+
+
+/**
* Called via cleanup_module() at module unload time.
*
* Cleans up all DRM device, calling drm_lastclose().
diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
index 1fad76289e6..cebde45b638 100644
--- a/drivers/gpu/drm/drm_ioctl.c
+++ b/drivers/gpu/drm/drm_ioctl.c
@@ -83,8 +83,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;
-
+
if (master->unique_len || master->unique)
return -EBUSY;
@@ -101,29 +100,50 @@ int drm_setunique(struct drm_device *dev, void *data,
master->unique[master->unique_len] = '\0';
- dev->devname =
- drm_alloc(strlen(dev->driver->pci_driver.name) +
- strlen(master->unique) + 2, DRM_MEM_DRIVER);
- if (!dev->devname)
- return -ENOMEM;
-
- 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)
- return -EINVAL;
- 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)))
- return -EINVAL;
+ if ( !drm_core_is_platform(dev) ) {
+
+ /* PCI device */
+
+ int domain, bus, slot, func, ret;
+
+ dev->devname =
+ drm_alloc(strlen(dev->driver->pci_driver.name) +
+ strlen(master->unique) + 2, DRM_MEM_DRIVER);
+ if (!dev->devname)
+ return -ENOMEM;
+
+ 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)
+ return -EINVAL;
+ 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)))
+ return -EINVAL;
+
+ } else {
+
+ /* Platform device */
+ dev->devname =
+ drm_alloc(strlen(dev->driver->name) +
+ strlen(master->unique) + 2, DRM_MEM_DRIVER);
+ if (!dev->devname)
+ return -ENOMEM;
+
+ sprintf(dev->devname, "%s@%s", dev->driver->name,
+ master->unique);
+
+ }
return 0;
}
@@ -131,8 +151,7 @@ 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;
-
+
if (master->unique != NULL)
return -EBUSY;
@@ -142,25 +161,58 @@ static int drm_set_busid(struct drm_device *dev, struct drm_file *file_priv)
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");
- else
- master->unique_len = len;
-
- dev->devname =
- drm_alloc(strlen(dev->driver->pci_driver.name) + master->unique_len +
- 2, DRM_MEM_DRIVER);
- if (dev->devname == NULL)
- return -ENOMEM;
+ if ( !drm_core_is_platform(dev) ) {
+
+ /* PCI device */
+
+ int len;
+
+ 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");
+ else
+ master->unique_len = len;
+
+ dev->devname =
+ drm_alloc(strlen(dev->driver->pci_driver.name)
+ + master->unique_len + 2, DRM_MEM_DRIVER);
+ if (dev->devname == NULL)
+ return -ENOMEM;
+
+ sprintf(dev->devname, "%s@%s", dev->driver->pci_driver.name,
+ master->unique);
+
+ } else {
+
+ /* Platform device */
+
+ int len;
+
+ len = snprintf(master->unique, master->unique_len,
+ "platform:%s", dev->platform_dev->name);
+
+ if (len >= master->unique_len)
+ DRM_ERROR("buffer overflow");
+ else
+ master->unique_len = len;
- sprintf(dev->devname, "%s@%s", dev->driver->pci_driver.name,
- master->unique);
+ dev->devname =
+ drm_alloc(strlen(dev->driver->name)
+ + master->unique_len + 2, DRM_MEM_DRIVER);
+ if (dev->devname == NULL)
+ return -ENOMEM;
+ sprintf(dev->devname, "%s@%s", dev->driver->name,
+ master->unique);
+
+ }
+
return 0;
}
diff --git a/drivers/gpu/drm/drm_proc.c b/drivers/gpu/drm/drm_proc.c
index 8df849f6683..255b12f9a15 100644
--- a/drivers/gpu/drm/drm_proc.c
+++ b/drivers/gpu/drm/drm_proc.c
@@ -214,14 +214,23 @@ static int drm_name_info(char *buf, char **start, off_t offset, int request,
*eof = 0;
if (master->unique) {
- DRM_PROC_PRINT("%s %s %s\n",
- dev->driver->pci_driver.name,
- pci_name(dev->pdev), master->unique);
+ if (drm_core_is_platform(dev)) {
+ DRM_PROC_PRINT("%s %s %s\n", dev->driver->name,
+ dev_name(&dev->platform_dev->dev), master->unique);
+ } else {
+ DRM_PROC_PRINT("%s %s %s\n",
+ dev->driver->pci_driver.name,
+ pci_name(dev->pdev), master->unique);
+ }
} else {
- DRM_PROC_PRINT("%s %s\n", dev->driver->pci_driver.name,
- pci_name(dev->pdev));
+ if (drm_core_is_platform(dev)) {
+ DRM_PROC_PRINT("%s %s\n", dev->driver->name,
+ dev_name(&dev->platform_dev->dev));
+ } else {
+ DRM_PROC_PRINT("%s %s\n", dev->driver->pci_driver.name,
+ pci_name(dev->pdev));
+ }
}
-
if (len > request + offset)
return request;
*eof = 1;
diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c
index 46bb923b097..93ce6cc030f 100644
--- a/drivers/gpu/drm/drm_stub.c
+++ b/drivers/gpu/drm/drm_stub.c
@@ -213,12 +213,13 @@ static int drm_fill_in_dev(struct drm_device * dev, struct pci_dev *pdev,
idr_init(&dev->drw_idr);
dev->pdev = pdev;
- dev->pci_device = pdev->device;
- dev->pci_vendor = pdev->vendor;
-
+ if (pdev) {
+ dev->pci_device = pdev->device;
+ dev->pci_vendor = pdev->vendor;
#ifdef __alpha__
dev->hose = pdev->sysdata;
#endif
+ }
if (drm_ht_create(&dev->map_hash, 12)) {
return -ENOMEM;
@@ -418,6 +419,79 @@ err_g1:
return ret;
}
+ /**
+ *
+ * Register a platform device as a DRM device
+ *
+ * \param pdev - platform device structure
+ * \param driver - the matching drm_driver structure
+ * \return zero on success or a negative number on failure.
+ *
+ * Attempt to gets inter module "drm" information. If we are first
+ * then register the character device and inter module information.
+ * Try and register, if we fail to register, backout previous work.
+ *
+ * \sa drm_get_dev
+ */
+int drm_get_platform_dev(struct platform_device *pdev,
+ struct drm_driver *driver, void *priv)
+{
+ struct drm_device *dev;
+ int ret;
+#if 0
+ int len;
+#endif
+ DRM_DEBUG("\n");
+
+ dev = drm_calloc(1, sizeof(*dev), DRM_MEM_STUB);
+ if (!dev)
+ return -ENOMEM;
+ dev->dev_private = priv;
+
+ if ((ret = drm_fill_in_dev(dev, NULL, NULL, driver))) {
+ printk(KERN_ERR "DRM: Fill_in_dev failed.\n");
+ goto err_g1;
+ }
+ dev->platform_dev = pdev;
+
+ if (drm_core_check_feature(dev, DRIVER_MODESET)) {
+ ret = drm_get_minor(dev, &dev->control, DRM_MINOR_CONTROL);
+ if (ret)
+ goto err_g2;
+ }
+
+ if ((ret = drm_get_minor(dev, &dev->primary, DRM_MINOR_LEGACY)))
+ goto err_g3;
+
+ if (dev->driver->load) {
+ ret = dev->driver->load(dev, 0);
+ if (ret)
+ goto err_g3;
+ }
+
+ /* setup the grouping for the legacy output */
+ if (drm_core_check_feature(dev, DRIVER_MODESET)) {
+ ret = drm_mode_group_init_legacy_group(dev, &dev->primary->mode_group);
+ if (ret)
+ goto err_g3;
+ }
+
+ list_add_tail(&dev->driver_item, &driver->device_list);
+
+ DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n",
+ driver->name, driver->major, driver->minor, driver->patchlevel,
+ driver->date, dev->primary->index);
+
+ return 0;
+
+err_g3:
+ drm_put_minor(&dev->primary);
+err_g2:
+err_g1:
+ drm_free(dev, sizeof(*dev), DRM_MEM_STUB);
+ return ret;
+}
+
/**
* Put a device minor number.
*
diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
index 5aa6780652a..44f7f16ebd6 100644
--- a/drivers/gpu/drm/drm_sysfs.c
+++ b/drivers/gpu/drm/drm_sysfs.c
@@ -477,7 +477,11 @@ int drm_sysfs_device_add(struct drm_minor *minor)
int i, j;
char *minor_str;
- minor->kdev.parent = &minor->dev->pdev->dev;
+ if (minor->dev->pdev) {
+ minor->kdev.parent = &minor->dev->pdev->dev;
+ } else {
+ minor->kdev.parent = &minor->dev->platform_dev->dev;
+ }
minor->kdev.class = drm_class;
minor->kdev.release = drm_sysfs_device_release;
minor->kdev.devt = minor->device;