Skip to content

Commit

Permalink
drm: Add support for platform devices to register as DRM devices
Browse files Browse the repository at this point in the history
Allow platform devices without PCI resources to be DRM devices.

[airlied: fixup warnings with dev pointers]

Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org>
Signed-off-by: Dave Airlie <airlied@redhat.com>
  • Loading branch information
Jordan Crouse authored and Dave Airlie committed Jun 1, 2010
1 parent 01d73a6 commit dcdb167
Show file tree
Hide file tree
Showing 17 changed files with 402 additions and 172 deletions.
4 changes: 2 additions & 2 deletions drivers/gpu/drm/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
select SLOW_WORK
Expand All @@ -17,7 +17,7 @@ menuconfig DRM
These modules provide support for synchronization, security, and
DMA transfers. Please see <http://dri.sourceforge.net/> for more
details. You should also select and configure AGP
(/dev/agpgart) support.
(/dev/agpgart) support if it is available for your platform.

config DRM_KMS_HELPER
tristate
Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ drm-y := drm_auth.o drm_buffer.o drm_bufs.o drm_cache.o \
drm_drv.o drm_fops.o drm_gem.o drm_ioctl.o drm_irq.o \
drm_lock.o drm_memory.o drm_proc.o drm_stub.o drm_vm.o \
drm_agpsupport.o drm_scatter.o ati_pcigart.o drm_pci.o \
drm_sysfs.o drm_hashtab.o drm_sman.o drm_mm.o \
drm_platform.o drm_sysfs.o drm_hashtab.o drm_sman.o drm_mm.o \
drm_crtc.o drm_modes.o drm_edid.o \
drm_info.o drm_debugfs.o drm_encoder_slave.o

Expand Down
37 changes: 5 additions & 32 deletions drivers/gpu/drm/drm_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -243,47 +243,20 @@ int drm_lastclose(struct drm_device * dev)
*
* Initializes an array of drm_device structures, and attempts to
* initialize all available devices, using consecutive minors, registering the
* stubs and initializing the AGP device.
* 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)
{
struct pci_dev *pdev = NULL;
const struct pci_device_id *pid;
int i;

DRM_DEBUG("\n");

INIT_LIST_HEAD(&driver->device_list);

if (driver->driver_features & DRIVER_MODESET)
return pci_register_driver(&driver->pci_driver);

/* 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];

/* Loop around setting up a DRM device for each PCI device
* matching our ID and device class. If we had the internal
* function that pci_get_subsys and pci_get_class used, we'd
* be able to just pass pid in instead of doing a two-stage
* thing.
*/
pdev = NULL;
while ((pdev =
pci_get_subsys(pid->vendor, pid->device, pid->subvendor,
pid->subdevice, pdev)) != NULL) {
if ((pdev->class & pid->class_mask) != pid->class)
continue;

/* stealth mode requires a manual probe */
pci_dev_get(pdev);
drm_get_dev(pdev, pid, driver);
}
}
return 0;
if (driver->driver_features & DRIVER_USE_PLATFORM_DEVICE)
return drm_platform_init(driver);
else
return drm_pci_init(driver);
}

EXPORT_SYMBOL(drm_init);
Expand Down
4 changes: 2 additions & 2 deletions drivers/gpu/drm/drm_edid.c
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter)
return block;

carp:
dev_warn(&connector->dev->pdev->dev, "%s: EDID block %d invalid.\n",
dev_warn(connector->dev->dev, "%s: EDID block %d invalid.\n",
drm_get_connector_name(connector), j);

out:
Expand Down Expand Up @@ -1626,7 +1626,7 @@ int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid)
return 0;
}
if (!drm_edid_is_valid(edid)) {
dev_warn(&connector->dev->pdev->dev, "%s: EDID invalid.\n",
dev_warn(connector->dev->dev, "%s: EDID invalid.\n",
drm_get_connector_name(connector));
return 0;
}
Expand Down
23 changes: 17 additions & 6 deletions drivers/gpu/drm/drm_info.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,24 @@ int drm_name_info(struct seq_file *m, void *data)
if (!master)
return 0;

if (master->unique) {
seq_printf(m, "%s %s %s\n",
dev->driver->pci_driver.name,
pci_name(dev->pdev), master->unique);
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);
}
} else {
seq_printf(m, "%s %s\n", dev->driver->pci_driver.name,
pci_name(dev->pdev));
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;
Expand Down
71 changes: 48 additions & 23 deletions drivers/gpu/drm/drm_ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -132,32 +132,57 @@ 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;

master->unique_len = 40;
master->unique_size = master->unique_len;
master->unique = kmalloc(master->unique_size, GFP_KERNEL);
if (master->unique == NULL)
return -ENOMEM;
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");

dev->devname =
kmalloc(strlen(dev->platformdev->name) +
master->unique_len + 2, GFP_KERNEL);

if (dev->devname == NULL)
return -ENOMEM;

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");
else
master->unique_len = 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 =
kmalloc(strlen(dev->driver->pci_driver.name) +
master->unique_len + 2, GFP_KERNEL);

dev->devname = kmalloc(strlen(dev->driver->pci_driver.name) +
master->unique_len + 2, GFP_KERNEL);
if (dev->devname == NULL)
return -ENOMEM;
if (dev->devname == NULL)
return -ENOMEM;

sprintf(dev->devname, "%s@%s", dev->driver->pci_driver.name,
master->unique);
sprintf(dev->devname, "%s@%s", dev->driver->pci_driver.name,
master->unique);
}

return 0;
}
Expand Down
15 changes: 9 additions & 6 deletions drivers/gpu/drm/drm_irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ 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))
return -EINVAL;

if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
return -EINVAL;

Expand Down Expand Up @@ -211,7 +214,7 @@ int drm_irq_install(struct drm_device *dev)
if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
return -EINVAL;

if (dev->pdev->irq == 0)
if (drm_dev_to_irq(dev) == 0)
return -EINVAL;

mutex_lock(&dev->struct_mutex);
Expand All @@ -229,7 +232,7 @@ int drm_irq_install(struct drm_device *dev)
dev->irq_enabled = 1;
mutex_unlock(&dev->struct_mutex);

DRM_DEBUG("irq=%d\n", dev->pdev->irq);
DRM_DEBUG("irq=%d\n", drm_dev_to_irq(dev));

/* Before installing handler */
dev->driver->irq_preinstall(dev);
Expand Down Expand Up @@ -302,14 +305,14 @@ int drm_irq_uninstall(struct drm_device * dev)
if (!irq_enabled)
return -EINVAL;

DRM_DEBUG("irq=%d\n", dev->pdev->irq);
DRM_DEBUG("irq=%d\n", drm_dev_to_irq(dev));

if (!drm_core_check_feature(dev, DRIVER_MODESET))
vga_client_register(dev->pdev, NULL, NULL, NULL);

dev->driver->irq_uninstall(dev);

free_irq(dev->pdev->irq, dev);
free_irq(drm_dev_to_irq(dev), dev);

return 0;
}
Expand Down Expand Up @@ -341,7 +344,7 @@ int drm_control(struct drm_device *dev, void *data,
if (drm_core_check_feature(dev, DRIVER_MODESET))
return 0;
if (dev->if_version < DRM_IF_VERSION(1, 2) &&
ctl->irq != dev->pdev->irq)
ctl->irq != drm_dev_to_irq(dev))
return -EINVAL;
return drm_irq_install(dev);
case DRM_UNINST_HANDLER:
Expand Down Expand Up @@ -651,7 +654,7 @@ int drm_wait_vblank(struct drm_device *dev, void *data,
int ret = 0;
unsigned int flags, seq, crtc;

if ((!dev->pdev->irq) || (!dev->irq_enabled))
if ((!drm_dev_to_irq(dev)) || (!dev->irq_enabled))
return -EINVAL;

if (vblwait->request.type & _DRM_VBLANK_SIGNAL)
Expand Down
Loading

0 comments on commit dcdb167

Please sign in to comment.