Skip to content

Commit

Permalink
Merge branch 'drm-init-cleanup' of git://people.freedesktop.org/~danv…
Browse files Browse the repository at this point in the history
…et/drm into drm-next

Next pull request, this time more of the drm de-midlayering work. The big
thing is that his patch series here removes everything from drm_bus except
the set_busid callback. Thierry has a few more patches on top of this to
make that one optional to.

With that we can ditch all the non-pci drm_bus implementations, which
Thierry has already done for the fake tegra host1x drm_bus.

Reviewed by Thierry, Laurent and David and now also survived some testing
on my intel boxes to make sure the irq fumble is fixed correctly ;-) The
last minute rebase was just to add the r-b tags from Thierry for the 2
patches I've redone.

* 'drm-init-cleanup' of git://people.freedesktop.org/~danvet/drm:
  drm/<drivers>: don't set driver->dev_priv_size to 0
  drm: Remove dev->kdriver
  drm: remove drm_bus->get_name
  drm: rip out dev->devname
  drm: inline drm_pci_set_unique
  drm: remove bus->get_irq implementations
  drm: pass the irq explicitly to drm_irq_install
  drm/irq: Look up the pci irq directly in the drm_control ioctl
  drm/irq: track the irq installed in drm_irq_install in dev->irq
  drm: rename dev->count_lock to dev->buf_lock
  drm: Rip out totally bogus vga_switcheroo->can_switch locking
  drm: kill drm_bus->bus_type
  drm: remove drm_dev_to_irq from drivers
  drm/irq: remove cargo-culted locking from irq_install/uninstall
  drm/irq: drm_control is a legacy ioctl, so pci devices only
  drm/pci: fold in irq_by_busid support
  drm/irq: simplify irq checks in drm_wait_vblank
  • Loading branch information
Dave Airlie committed Apr 30, 2014
2 parents 7e9ab40 + 3c84139 commit 444c9a0
Show file tree
Hide file tree
Showing 30 changed files with 158 additions and 267 deletions.
10 changes: 1 addition & 9 deletions Documentation/DocBook/drm.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -341,22 +341,14 @@ char *date;</synopsis>
</para>
<sect4>
<title>Managed IRQ Registration</title>
<para>
Both the <function>drm_irq_install</function> and
<function>drm_irq_uninstall</function> functions get the device IRQ by
calling <function>drm_dev_to_irq</function>. This inline function will
call a bus-specific operation to retrieve the IRQ number. For platform
devices, <function>platform_get_irq</function>(..., 0) is used to
retrieve the IRQ number.
</para>
<para>
<function>drm_irq_install</function> starts by calling the
<methodname>irq_preinstall</methodname> driver operation. The operation
is optional and must make sure that the interrupt will not get fired by
clearing all pending interrupt flags or disabling the interrupt.
</para>
<para>
The IRQ will then be requested by a call to
The passed-in IRQ will then be requested by a call to
<function>request_irq</function>. If the DRIVER_IRQ_SHARED driver
feature flag is set, a shared (IRQF_SHARED) IRQ handler will be
requested.
Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/armada/armada_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ static int armada_drm_load(struct drm_device *dev, unsigned long flags)
if (ret)
goto err_kms;

ret = drm_irq_install(dev);
ret = drm_irq_install(dev, platform_get_irq(dev->platformdev, 0));
if (ret)
goto err_kms;

Expand Down
1 change: 0 additions & 1 deletion drivers/gpu/drm/ast/ast_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,6 @@ static const struct file_operations ast_fops = {

static struct drm_driver driver = {
.driver_features = DRIVER_MODESET | DRIVER_GEM,
.dev_priv_size = 0,

.load = ast_driver_load,
.unload = ast_driver_unload,
Expand Down
32 changes: 16 additions & 16 deletions drivers/gpu/drm/drm_bufs.c
Original file line number Diff line number Diff line change
Expand Up @@ -656,13 +656,13 @@ int drm_addbufs_agp(struct drm_device * dev, struct drm_buf_desc * request)
DRM_DEBUG("zone invalid\n");
return -EINVAL;
}
spin_lock(&dev->count_lock);
spin_lock(&dev->buf_lock);
if (dev->buf_use) {
spin_unlock(&dev->count_lock);
spin_unlock(&dev->buf_lock);
return -EBUSY;
}
atomic_inc(&dev->buf_alloc);
spin_unlock(&dev->count_lock);
spin_unlock(&dev->buf_lock);

mutex_lock(&dev->struct_mutex);
entry = &dma->bufs[order];
Expand Down Expand Up @@ -805,13 +805,13 @@ int drm_addbufs_pci(struct drm_device * dev, struct drm_buf_desc * request)
page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0;
total = PAGE_SIZE << page_order;

spin_lock(&dev->count_lock);
spin_lock(&dev->buf_lock);
if (dev->buf_use) {
spin_unlock(&dev->count_lock);
spin_unlock(&dev->buf_lock);
return -EBUSY;
}
atomic_inc(&dev->buf_alloc);
spin_unlock(&dev->count_lock);
spin_unlock(&dev->buf_lock);

mutex_lock(&dev->struct_mutex);
entry = &dma->bufs[order];
Expand Down Expand Up @@ -1015,13 +1015,13 @@ static int drm_addbufs_sg(struct drm_device * dev, struct drm_buf_desc * request
if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER)
return -EINVAL;

spin_lock(&dev->count_lock);
spin_lock(&dev->buf_lock);
if (dev->buf_use) {
spin_unlock(&dev->count_lock);
spin_unlock(&dev->buf_lock);
return -EBUSY;
}
atomic_inc(&dev->buf_alloc);
spin_unlock(&dev->count_lock);
spin_unlock(&dev->buf_lock);

mutex_lock(&dev->struct_mutex);
entry = &dma->bufs[order];
Expand Down Expand Up @@ -1175,7 +1175,7 @@ int drm_addbufs(struct drm_device *dev, void *data,
* \param arg pointer to a drm_buf_info structure.
* \return zero on success or a negative number on failure.
*
* Increments drm_device::buf_use while holding the drm_device::count_lock
* Increments drm_device::buf_use while holding the drm_device::buf_lock
* lock, preventing of allocating more buffers after this call. Information
* about each requested buffer is then copied into user space.
*/
Expand All @@ -1196,13 +1196,13 @@ int drm_infobufs(struct drm_device *dev, void *data,
if (!dma)
return -EINVAL;

spin_lock(&dev->count_lock);
spin_lock(&dev->buf_lock);
if (atomic_read(&dev->buf_alloc)) {
spin_unlock(&dev->count_lock);
spin_unlock(&dev->buf_lock);
return -EBUSY;
}
++dev->buf_use; /* Can't allocate more after this call */
spin_unlock(&dev->count_lock);
spin_unlock(&dev->buf_lock);

for (i = 0, count = 0; i < DRM_MAX_ORDER + 1; i++) {
if (dma->bufs[i].buf_count)
Expand Down Expand Up @@ -1381,13 +1381,13 @@ int drm_mapbufs(struct drm_device *dev, void *data,
if (!dma)
return -EINVAL;

spin_lock(&dev->count_lock);
spin_lock(&dev->buf_lock);
if (atomic_read(&dev->buf_alloc)) {
spin_unlock(&dev->count_lock);
spin_unlock(&dev->buf_lock);
return -EBUSY;
}
dev->buf_use++; /* Can't allocate more after this call */
spin_unlock(&dev->count_lock);
spin_unlock(&dev->buf_lock);

if (request->count >= dma->buf_count) {
if ((dev->agp && (dma->flags & _DRM_DMA_USE_AGP))
Expand Down
6 changes: 2 additions & 4 deletions drivers/gpu/drm/drm_info.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,18 +47,16 @@ 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;

bus_name = dev->driver->bus->get_name(dev);
if (master->unique) {
seq_printf(m, "%s %s %s\n",
bus_name,
dev->driver->name,
dev_name(dev->dev), master->unique);
} else {
seq_printf(m, "%s %s\n",
bus_name, dev_name(dev->dev));
dev->driver->name, dev_name(dev->dev));
}
return 0;
}
Expand Down
13 changes: 7 additions & 6 deletions drivers/gpu/drm/drm_ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,6 @@ static void
drm_unset_busid(struct drm_device *dev,
struct drm_master *master)
{
kfree(dev->devname);
dev->devname = NULL;

kfree(master->unique);
master->unique = NULL;
master->unique_len = 0;
Expand All @@ -93,7 +90,8 @@ drm_unset_busid(struct drm_device *dev,
* Copies the bus id from userspace into drm_device::unique, and verifies that
* it matches the device this DRM is attached to (EINVAL otherwise). Deprecated
* in interface version 1.1 and will return EBUSY when setversion has requested
* version 1.1 or greater.
* version 1.1 or greater. Also note that KMS is all version 1.1 and later and
* UMS was only ever supported on pci devices.
*/
int drm_setunique(struct drm_device *dev, void *data,
struct drm_file *file_priv)
Expand All @@ -108,10 +106,13 @@ int drm_setunique(struct drm_device *dev, void *data,
if (!u->unique_len || u->unique_len > 1024)
return -EINVAL;

if (!dev->driver->bus->set_unique)
if (drm_core_check_feature(dev, DRIVER_MODESET))
return 0;

if (WARN_ON(!dev->pdev))
return -EINVAL;

ret = dev->driver->bus->set_unique(dev, master, u);
ret = drm_pci_set_unique(dev, master, u);
if (ret)
goto err;

Expand Down
105 changes: 35 additions & 70 deletions drivers/gpu/drm/drm_irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,33 +56,6 @@
*/
#define DRM_REDUNDANT_VBLIRQ_THRESH_NS 1000000

/**
* Get interrupt from bus id.
*
* \param inode device inode.
* \param file_priv DRM file private.
* \param cmd command.
* \param arg user argument, pointing to a drm_irq_busid structure.
* \return zero on success or a negative number on failure.
*
* Finds the PCI device with the specified bus id and gets its IRQ number.
* This IOCTL is deprecated, and will now return EINVAL for any busid not equal
* to that of the device that this DRM instance attached to.
*/
int drm_irq_by_busid(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
struct drm_irq_busid *p = data;

if (!dev->driver->bus->irq_by_busid)
return -EINVAL;

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

return dev->driver->bus->irq_by_busid(dev, p);
}

/*
* Clear vblank timestamp buffer for a crtc.
*/
Expand Down Expand Up @@ -269,34 +242,26 @@ static void drm_irq_vgaarb_nokms(void *cookie, bool state)
* \c irq_preinstall() and \c irq_postinstall() functions
* before and after the installation.
*/
int drm_irq_install(struct drm_device *dev)
int drm_irq_install(struct drm_device *dev, int irq)
{
int ret;
unsigned long sh_flags = 0;
char *irqname;

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

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

mutex_lock(&dev->struct_mutex);

/* Driver must have been initialized */
if (!dev->dev_private) {
mutex_unlock(&dev->struct_mutex);
if (!dev->dev_private)
return -EINVAL;
}

if (dev->irq_enabled) {
mutex_unlock(&dev->struct_mutex);
if (dev->irq_enabled)
return -EBUSY;
}
dev->irq_enabled = true;
mutex_unlock(&dev->struct_mutex);

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

/* Before installing handler */
if (dev->driver->irq_preinstall)
Expand All @@ -306,18 +271,11 @@ int drm_irq_install(struct drm_device *dev)
if (drm_core_check_feature(dev, DRIVER_IRQ_SHARED))
sh_flags = IRQF_SHARED;

if (dev->devname)
irqname = dev->devname;
else
irqname = dev->driver->name;

ret = request_irq(drm_dev_to_irq(dev), dev->driver->irq_handler,
sh_flags, irqname, dev);
ret = request_irq(irq, dev->driver->irq_handler,
sh_flags, dev->driver->name, dev);

if (ret < 0) {
mutex_lock(&dev->struct_mutex);
dev->irq_enabled = false;
mutex_unlock(&dev->struct_mutex);
return ret;
}

Expand All @@ -329,12 +287,12 @@ int drm_irq_install(struct drm_device *dev)
ret = dev->driver->irq_postinstall(dev);

if (ret < 0) {
mutex_lock(&dev->struct_mutex);
dev->irq_enabled = false;
mutex_unlock(&dev->struct_mutex);
if (!drm_core_check_feature(dev, DRIVER_MODESET))
vga_client_register(dev->pdev, NULL, NULL, NULL);
free_irq(drm_dev_to_irq(dev), dev);
free_irq(irq, dev);
} else {
dev->irq = irq;
}

return ret;
Expand All @@ -357,10 +315,8 @@ int drm_irq_uninstall(struct drm_device *dev)
if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
return -EINVAL;

mutex_lock(&dev->struct_mutex);
irq_enabled = dev->irq_enabled;
dev->irq_enabled = false;
mutex_unlock(&dev->struct_mutex);

/*
* Wake up any waiters so they don't hang.
Expand All @@ -379,15 +335,15 @@ int drm_irq_uninstall(struct drm_device *dev)
if (!irq_enabled)
return -EINVAL;

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

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

if (dev->driver->irq_uninstall)
dev->driver->irq_uninstall(dev);

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

return 0;
}
Expand All @@ -408,28 +364,38 @@ int drm_control(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
struct drm_control *ctl = data;
int ret = 0, irq;

/* if we haven't irq we fallback for compatibility reasons -
* this used to be a separate function in drm_dma.h
*/

if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
return 0;
if (drm_core_check_feature(dev, DRIVER_MODESET))
return 0;
/* UMS was only ever support on pci devices. */
if (WARN_ON(!dev->pdev))
return -EINVAL;

switch (ctl->func) {
case DRM_INST_HANDLER:
if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
return 0;
if (drm_core_check_feature(dev, DRIVER_MODESET))
return 0;
irq = dev->pdev->irq;

if (dev->if_version < DRM_IF_VERSION(1, 2) &&
ctl->irq != drm_dev_to_irq(dev))
ctl->irq != irq)
return -EINVAL;
return drm_irq_install(dev);
mutex_lock(&dev->struct_mutex);
ret = drm_irq_install(dev, irq);
mutex_unlock(&dev->struct_mutex);

return ret;
case DRM_UNINST_HANDLER:
if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
return 0;
if (drm_core_check_feature(dev, DRIVER_MODESET))
return 0;
return drm_irq_uninstall(dev);
mutex_lock(&dev->struct_mutex);
ret = drm_irq_uninstall(dev);
mutex_unlock(&dev->struct_mutex);

return ret;
default:
return -EINVAL;
}
Expand Down Expand Up @@ -1160,9 +1126,8 @@ int drm_wait_vblank(struct drm_device *dev, void *data,
int ret;
unsigned int flags, seq, crtc, high_crtc;

if (drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
if ((!drm_dev_to_irq(dev)) || (!dev->irq_enabled))
return -EINVAL;
if (!dev->irq_enabled)
return -EINVAL;

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

0 comments on commit 444c9a0

Please sign in to comment.