drm: Add support for platform devices to register as DRM devices
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>
This commit is contained in:
parent
01d73a6967
commit
dcdb167402
|
@ -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
|
||||
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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:
|
||||
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
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);
|
||||
|
||||
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 (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,
|
||||
"platform:%s", dev->platformdev->name);
|
||||
|
||||
dev->devname = kmalloc(strlen(dev->driver->pci_driver.name) +
|
||||
master->unique_len + 2, GFP_KERNEL);
|
||||
if (dev->devname == NULL)
|
||||
return -ENOMEM;
|
||||
if (len > master->unique_len)
|
||||
DRM_ERROR("Unique buffer overflowed\n");
|
||||
|
||||
sprintf(dev->devname, "%s@%s", dev->driver->pci_driver.name,
|
||||
master->unique);
|
||||
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;
|
||||
|
||||
dev->devname =
|
||||
kmalloc(strlen(dev->driver->pci_driver.name) +
|
||||
master->unique_len + 2, GFP_KERNEL);
|
||||
|
||||
if (dev->devname == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
sprintf(dev->devname, "%s@%s", dev->driver->pci_driver.name,
|
||||
master->unique);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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:
|
||||
|
@ -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)
|
||||
|
|
|
@ -124,4 +124,147 @@ void drm_pci_free(struct drm_device * dev, drm_dma_handle_t * dmah)
|
|||
|
||||
EXPORT_SYMBOL(drm_pci_free);
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
/**
|
||||
* Register.
|
||||
*
|
||||
* \param pdev - PCI device structure
|
||||
* \param ent entry from the PCI ID table with device type flags
|
||||
* \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.
|
||||
*/
|
||||
int drm_get_pci_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
|
||||
struct drm_driver *driver)
|
||||
{
|
||||
struct drm_device *dev;
|
||||
int ret;
|
||||
|
||||
DRM_DEBUG("\n");
|
||||
|
||||
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
|
||||
if (!dev)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = pci_enable_device(pdev);
|
||||
if (ret)
|
||||
goto err_g1;
|
||||
|
||||
pci_set_master(pdev);
|
||||
|
||||
dev->pdev = pdev;
|
||||
dev->dev = &pdev->dev;
|
||||
|
||||
dev->pci_device = pdev->device;
|
||||
dev->pci_vendor = pdev->vendor;
|
||||
|
||||
#ifdef __alpha__
|
||||
dev->hose = pdev->sysdata;
|
||||
#endif
|
||||
|
||||
if ((ret = drm_fill_in_dev(dev, ent, driver))) {
|
||||
printk(KERN_ERR "DRM: Fill_in_dev failed.\n");
|
||||
goto err_g2;
|
||||
}
|
||||
|
||||
if (drm_core_check_feature(dev, DRIVER_MODESET)) {
|
||||
pci_set_drvdata(pdev, dev);
|
||||
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, ent->driver_data);
|
||||
if (ret)
|
||||
goto err_g4;
|
||||
}
|
||||
|
||||
/* 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_g4;
|
||||
}
|
||||
|
||||
list_add_tail(&dev->driver_item, &driver->device_list);
|
||||
|
||||
DRM_INFO("Initialized %s %d.%d.%d %s for %s on minor %d\n",
|
||||
driver->name, driver->major, driver->minor, driver->patchlevel,
|
||||
driver->date, pci_name(pdev), dev->primary->index);
|
||||
|
||||
return 0;
|
||||
|
||||
err_g4:
|
||||
drm_put_minor(&dev->primary);
|
||||
err_g3:
|
||||
if (drm_core_check_feature(dev, DRIVER_MODESET))
|
||||
drm_put_minor(&dev->control);
|
||||
err_g2:
|
||||
pci_disable_device(pdev);
|
||||
err_g1:
|
||||
kfree(dev);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_get_pci_dev);
|
||||
|
||||
/**
|
||||
* PCI device initialization. Called via drm_init at module load time,
|
||||
*
|
||||
* \return zero on success or a negative number on failure.
|
||||
*
|
||||
* Initializes a drm_device structures,registering the
|
||||
* stubs and initializing the AGP device.
|
||||
*
|
||||
* 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)
|
||||
{
|
||||
struct pci_dev *pdev = NULL;
|
||||
const struct pci_device_id *pid;
|
||||
int i;
|
||||
|
||||
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_pci_dev(pdev, pid, driver);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
int drm_pci_init(struct drm_driver *driver)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endif
|
||||
/*@}*/
|
||||
|
|
|
@ -0,0 +1,122 @@
|
|||
/*
|
||||
* Derived from drm_pci.c
|
||||
*
|
||||
* Copyright 2003 José Fonseca.
|
||||
* Copyright 2003 Leif Delgass.
|
||||
* Copyright (c) 2009, Code Aurora Forum.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "drmP.h"
|
||||
|
||||
/**
|
||||
* Register.
|
||||
*
|
||||
* \param platdev - Platform device struture
|
||||
* \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.
|
||||
*/
|
||||
|
||||
int drm_get_platform_dev(struct platform_device *platdev,
|
||||
struct drm_driver *driver)
|
||||
{
|
||||
struct drm_device *dev;
|
||||
int ret;
|
||||
|
||||
DRM_DEBUG("\n");
|
||||
|
||||
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
|
||||
if (!dev)
|
||||
return -ENOMEM;
|
||||
|
||||
dev->platformdev = platdev;
|
||||
dev->dev = &platdev->dev;
|
||||
|
||||
ret = drm_fill_in_dev(dev, NULL, driver);
|
||||
|
||||
if (ret) {
|
||||
printk(KERN_ERR "DRM: Fill_in_dev failed.\n");
|
||||
goto err_g1;
|
||||
}
|
||||
|
||||
if (drm_core_check_feature(dev, DRIVER_MODESET)) {
|
||||
dev_set_drvdata(&platdev->dev, dev);
|
||||
ret = drm_get_minor(dev, &dev->control, DRM_MINOR_CONTROL);
|
||||
if (ret)
|
||||
goto err_g1;
|
||||
}
|
||||
|
||||
ret = drm_get_minor(dev, &dev->primary, DRM_MINOR_LEGACY);
|
||||
if (ret)
|
||||
goto err_g2;
|
||||
|
||||
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:
|
||||
if (drm_core_check_feature(dev, DRIVER_MODESET))
|
||||
drm_put_minor(&dev->control);
|
||||
err_g1:
|
||||
kfree(dev);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_get_platform_dev);
|
||||
|
||||
/**
|
||||
* Platform device initialization. Called via drm_init at module load time,
|
||||
*
|
||||
* \return zero on success or a negative number on failure.
|
||||
*
|
||||
* Initializes a drm_device structures,registering the
|
||||
* stubs
|
||||
*
|
||||
* Expands the \c DRIVER_PREINIT and \c DRIVER_POST_INIT macros before and
|
||||
* after the initialization for driver customization.
|
||||
*/
|
||||
|
||||
int drm_platform_init(struct drm_driver *driver)
|
||||
{
|
||||
return drm_get_platform_dev(driver->platform_device, driver);
|
||||
}
|
|
@ -224,7 +224,7 @@ int drm_dropmaster_ioctl(struct drm_device *dev, void *data,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int drm_fill_in_dev(struct drm_device * dev, struct pci_dev *pdev,
|
||||
int drm_fill_in_dev(struct drm_device *dev,
|
||||
const struct pci_device_id *ent,
|
||||
struct drm_driver *driver)
|
||||
{
|
||||
|
@ -245,14 +245,6 @@ 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;
|
||||
|
||||
#ifdef __alpha__
|
||||
dev->hose = pdev->sysdata;
|
||||
#endif
|
||||
|
||||
if (drm_ht_create(&dev->map_hash, 12)) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
@ -321,7 +313,7 @@ static int drm_fill_in_dev(struct drm_device * dev, struct pci_dev *pdev,
|
|||
* create the proc init entry via proc_init(). This routines assigns
|
||||
* minor numbers to secondary heads of multi-headed cards
|
||||
*/
|
||||
static int drm_get_minor(struct drm_device *dev, struct drm_minor **minor, int type)
|
||||
int drm_get_minor(struct drm_device *dev, struct drm_minor **minor, int type)
|
||||
{
|
||||
struct drm_minor *new_minor;
|
||||
int ret;
|
||||
|
@ -387,83 +379,6 @@ err_idr:
|
|||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register.
|
||||
*
|
||||
* \param pdev - PCI device structure
|
||||
* \param ent entry from the PCI ID table with device type flags
|
||||
* \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.
|
||||
*/
|
||||
int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
|
||||
struct drm_driver *driver)
|
||||
{
|
||||
struct drm_device *dev;
|
||||
int ret;
|
||||
|
||||
DRM_DEBUG("\n");
|
||||
|
||||
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
|
||||
if (!dev)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = pci_enable_device(pdev);
|
||||
if (ret)
|
||||
goto err_g1;
|
||||
|
||||
pci_set_master(pdev);
|
||||
if ((ret = drm_fill_in_dev(dev, pdev, ent, driver))) {
|
||||
printk(KERN_ERR "DRM: Fill_in_dev failed.\n");
|
||||
goto err_g2;
|
||||
}
|
||||
|
||||
if (drm_core_check_feature(dev, DRIVER_MODESET)) {
|
||||
pci_set_drvdata(pdev, dev);
|
||||
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, ent->driver_data);
|
||||
if (ret)
|
||||
goto err_g4;
|
||||
}
|
||||
|
||||
/* 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_g4;
|
||||
}
|
||||
|
||||
list_add_tail(&dev->driver_item, &driver->device_list);
|
||||
|
||||
DRM_INFO("Initialized %s %d.%d.%d %s for %s on minor %d\n",
|
||||
driver->name, driver->major, driver->minor, driver->patchlevel,
|
||||
driver->date, pci_name(pdev), dev->primary->index);
|
||||
|
||||
return 0;
|
||||
|
||||
err_g4:
|
||||
drm_put_minor(&dev->primary);
|
||||
err_g3:
|
||||
if (drm_core_check_feature(dev, DRIVER_MODESET))
|
||||
drm_put_minor(&dev->control);
|
||||
err_g2:
|
||||
pci_disable_device(pdev);
|
||||
err_g1:
|
||||
kfree(dev);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_get_dev);
|
||||
|
||||
/**
|
||||
* Put a secondary minor number.
|
||||
*
|
||||
|
|
|
@ -488,7 +488,8 @@ int drm_sysfs_device_add(struct drm_minor *minor)
|
|||
int err;
|
||||
char *minor_str;
|
||||
|
||||
minor->kdev.parent = &minor->dev->pdev->dev;
|
||||
minor->kdev.parent = minor->dev->dev;
|
||||
|
||||
minor->kdev.class = drm_class;
|
||||
minor->kdev.release = drm_sysfs_device_release;
|
||||
minor->kdev.devt = minor->device;
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include "i915_drm.h"
|
||||
#include "i915_drv.h"
|
||||
#include "i915_trace.h"
|
||||
#include <linux/pci.h>
|
||||
#include <linux/vgaarb.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/pnp.h>
|
||||
|
|
|
@ -435,7 +435,7 @@ int i965_reset(struct drm_device *dev, u8 flags)
|
|||
static int __devinit
|
||||
i915_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
{
|
||||
return drm_get_dev(pdev, ent, &driver);
|
||||
return drm_get_pci_dev(pdev, ent, &driver);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -132,7 +132,7 @@ static struct drm_driver driver;
|
|||
static int __devinit
|
||||
nouveau_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
{
|
||||
return drm_get_dev(pdev, ent, &driver);
|
||||
return drm_get_pci_dev(pdev, ent, &driver);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -236,7 +236,7 @@ static struct drm_driver kms_driver;
|
|||
static int __devinit
|
||||
radeon_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
{
|
||||
return drm_get_dev(pdev, ent, &kms_driver);
|
||||
return drm_get_pci_dev(pdev, ent, &kms_driver);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -758,7 +758,7 @@ static struct drm_driver driver = {
|
|||
|
||||
static int vmw_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
{
|
||||
return drm_get_dev(pdev, ent, &driver);
|
||||
return drm_get_pci_dev(pdev, ent, &driver);
|
||||
}
|
||||
|
||||
static int __init vmwgfx_init(void)
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
/*
|
||||
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
|
||||
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
|
||||
* Copyright (c) 2009-2010, Code Aurora Forum.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
|
@ -48,6 +49,7 @@
|
|||
#include <linux/proc_fs.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/file.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/smp_lock.h> /* For (un)lock_kernel */
|
||||
|
@ -144,6 +146,7 @@ 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
|
||||
|
||||
/***********************************************************************/
|
||||
/** \name Begin the DRM... */
|
||||
|
@ -823,6 +826,7 @@ struct drm_driver {
|
|||
int num_ioctls;
|
||||
struct file_operations fops;
|
||||
struct pci_driver pci_driver;
|
||||
struct platform_device *platform_device;
|
||||
/* List of devices hanging off this driver */
|
||||
struct list_head device_list;
|
||||
};
|
||||
|
@ -1015,12 +1019,16 @@ struct drm_device {
|
|||
|
||||
struct drm_agp_head *agp; /**< AGP data */
|
||||
|
||||
struct device *dev; /**< Device structure */
|
||||
struct pci_dev *pdev; /**< PCI device structure */
|
||||
int pci_vendor; /**< PCI vendor id */
|
||||
int pci_device; /**< PCI device id */
|
||||
#ifdef __alpha__
|
||||
struct pci_controller *hose;
|
||||
#endif
|
||||
|
||||
struct platform_device *platformdev; /**< Platform device struture */
|
||||
|
||||
struct drm_sg_mem *sg; /**< Scatter gather memory */
|
||||
int num_crtcs; /**< Number of CRTCs on this device */
|
||||
void *dev_private; /**< device private data */
|
||||
|
@ -1060,17 +1068,21 @@ struct drm_device {
|
|||
|
||||
};
|
||||
|
||||
static inline int drm_dev_to_irq(struct drm_device *dev)
|
||||
{
|
||||
return dev->pdev->irq;
|
||||
}
|
||||
|
||||
static __inline__ int drm_core_check_feature(struct drm_device *dev,
|
||||
int feature)
|
||||
{
|
||||
return ((dev->driver->driver_features & feature) ? 1 : 0);
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
#ifdef __alpha__
|
||||
#define drm_get_pci_domain(dev) dev->hose->index
|
||||
#else
|
||||
|
@ -1347,8 +1359,11 @@ 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_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
|
||||
struct drm_driver *driver);
|
||||
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;
|
||||
|
@ -1525,6 +1540,9 @@ static __inline__ struct drm_local_map *drm_core_findmap(struct drm_device *dev,
|
|||
|
||||
static __inline__ int drm_device_is_agp(struct drm_device *dev)
|
||||
{
|
||||
if (drm_core_check_feature(dev, DRIVER_USE_PLATFORM_DEVICE))
|
||||
return 0;
|
||||
|
||||
if (dev->driver->device_is_agp != NULL) {
|
||||
int err = (*dev->driver->device_is_agp) (dev);
|
||||
|
||||
|
@ -1538,7 +1556,10 @@ static __inline__ int drm_device_is_agp(struct drm_device *dev)
|
|||
|
||||
static __inline__ int drm_device_is_pcie(struct drm_device *dev)
|
||||
{
|
||||
return pci_find_capability(dev->pdev, PCI_CAP_ID_EXP);
|
||||
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)
|
||||
|
@ -1546,6 +1567,21 @@ static __inline__ void drm_core_dropmap(struct drm_local_map *map)
|
|||
}
|
||||
|
||||
#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,
|
||||
const struct pci_device_id *ent,
|
||||
struct drm_driver *driver);
|
||||
int drm_get_minor(struct drm_device *dev, struct drm_minor **minor, int type);
|
||||
/*@}*/
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
|
Loading…
Reference in New Issue