Release 4.14 drivers/gpu/drm/drm_irq.c
/*
* drm_irq.c IRQ and vblank support
*
* \author Rickard E. (Rik) Faith <faith@valinux.com>
* \author Gareth Hughes <gareth@valinux.com>
*
* 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
* VA LINUX SYSTEMS AND/OR ITS SUPPLIERS 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.
*/
/*
* Created: Fri Mar 19 14:30:16 1999 by faith@valinux.com
*
* Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
* 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
* VA LINUX SYSTEMS AND/OR ITS SUPPLIERS 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 <drm/drm_irq.h>
#include <drm/drmP.h>
#include <linux/interrupt.h> /* For task queue support */
#include <linux/vgaarb.h>
#include <linux/export.h>
#include "drm_internal.h"
/**
* DOC: irq helpers
*
* The DRM core provides very simple support helpers to enable IRQ handling on a
* device through the drm_irq_install() and drm_irq_uninstall() functions. This
* only supports devices with a single interrupt on the main device stored in
* &drm_device.dev and set as the device paramter in drm_dev_alloc().
*
* These IRQ helpers are strictly optional. Drivers which roll their own only
* need to set &drm_device.irq_enabled to signal the DRM core that vblank
* interrupts are working. Since these helpers don't automatically clean up the
* requested interrupt like e.g. devm_request_irq() they're not really
* recommended.
*/
/**
* drm_irq_install - install IRQ handler
* @dev: DRM device
* @irq: IRQ number to install the handler for
*
* Initializes the IRQ related data. Installs the handler, calling the driver
* &drm_driver.irq_preinstall and &drm_driver.irq_postinstall functions before
* and after the installation.
*
* This is the simplified helper interface provided for drivers with no special
* needs. Drivers which need to install interrupt handlers for multiple
* interrupts must instead set &drm_device.irq_enabled to signal the DRM core
* that vblank interrupts are available.
*
* @irq must match the interrupt number that would be passed to request_irq(),
* if called directly instead of using this helper function.
*
* &drm_driver.irq_handler is called to handle the registered interrupt.
*
* Returns:
* Zero on success or a negative error code on failure.
*/
int drm_irq_install(struct drm_device *dev, int irq)
{
int ret;
unsigned long sh_flags = 0;
if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
return -EINVAL;
if (irq == 0)
return -EINVAL;
/* Driver must have been initialized */
if (!dev->dev_private)
return -EINVAL;
if (dev->irq_enabled)
return -EBUSY;
dev->irq_enabled = true;
DRM_DEBUG("irq=%d\n", irq);
/* Before installing handler */
if (dev->driver->irq_preinstall)
dev->driver->irq_preinstall(dev);
/* Install handler */
if (drm_core_check_feature(dev, DRIVER_IRQ_SHARED))
sh_flags = IRQF_SHARED;
ret = request_irq(irq, dev->driver->irq_handler,
sh_flags, dev->driver->name, dev);
if (ret < 0) {
dev->irq_enabled = false;
return ret;
}
/* After installing handler */
if (dev->driver->irq_postinstall)
ret = dev->driver->irq_postinstall(dev);
if (ret < 0) {
dev->irq_enabled = false;
if (drm_core_check_feature(dev, DRIVER_LEGACY))
vga_client_register(dev->pdev, NULL, NULL, NULL);
free_irq(irq, dev);
} else {
dev->irq = irq;
}
return ret;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Daniel Vetter | 106 | 46.49% | 1 | 5.88% |
Jesse Barnes | 31 | 13.60% | 1 | 5.88% |
Dave Airlie | 30 | 13.16% | 5 | 29.41% |
Michel Dänzer | 20 | 8.77% | 3 | 17.65% |
Eric Anholt | 18 | 7.89% | 2 | 11.76% |
Chris Wilson | 15 | 6.58% | 3 | 17.65% |
Ville Syrjälä | 4 | 1.75% | 1 | 5.88% |
Mario Kleiner | 4 | 1.75% | 1 | 5.88% |
Total | 228 | 100.00% | 17 | 100.00% |
EXPORT_SYMBOL(drm_irq_install);
/**
* drm_irq_uninstall - uninstall the IRQ handler
* @dev: DRM device
*
* Calls the driver's &drm_driver.irq_uninstall function and unregisters the IRQ
* handler. This should only be called by drivers which used drm_irq_install()
* to set up their interrupt handler. Other drivers must only reset
* &drm_device.irq_enabled to false.
*
* Note that for kernel modesetting drivers it is a bug if this function fails.
* The sanity checks are only to catch buggy user modesetting drivers which call
* the same function through an ioctl.
*
* Returns:
* Zero on success or a negative error code on failure.
*/
int drm_irq_uninstall(struct drm_device *dev)
{
unsigned long irqflags;
bool irq_enabled;
int i;
if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
return -EINVAL;
irq_enabled = dev->irq_enabled;
dev->irq_enabled = false;
/*
* Wake up any waiters so they don't hang. This is just to paper over
* issues for UMS drivers which aren't in full control of their
* vblank/irq handling. KMS drivers must ensure that vblanks are all
* disabled when uninstalling the irq handler.
*/
if (dev->num_crtcs) {
spin_lock_irqsave(&dev->vbl_lock, irqflags);
for (i = 0; i < dev->num_crtcs; i++) {
struct drm_vblank_crtc *vblank = &dev->vblank[i];
if (!vblank->enabled)
continue;
WARN_ON(drm_core_check_feature(dev, DRIVER_MODESET));
drm_vblank_disable_and_save(dev, i);
wake_up(&vblank->queue);
}
spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
}
if (!irq_enabled)
return -EINVAL;
DRM_DEBUG("irq=%d\n", dev->irq);
if (drm_core_check_feature(dev, DRIVER_LEGACY))
vga_client_register(dev->pdev, NULL, NULL, NULL);
if (dev->driver->irq_uninstall)
dev->driver->irq_uninstall(dev);
free_irq(dev->irq, dev);
return 0;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Daniel Vetter | 154 | 74.40% | 1 | 14.29% |
Kristian Högsberg | 36 | 17.39% | 1 | 14.29% |
Ville Syrjälä | 6 | 2.90% | 1 | 14.29% |
Jesse Barnes | 4 | 1.93% | 1 | 14.29% |
Chris Wilson | 3 | 1.45% | 1 | 14.29% |
Rob Clark | 2 | 0.97% | 1 | 14.29% |
Mario Kleiner | 2 | 0.97% | 1 | 14.29% |
Total | 207 | 100.00% | 7 | 100.00% |
EXPORT_SYMBOL(drm_irq_uninstall);
int drm_legacy_irq_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_LEGACY))
return 0;
/* UMS was only ever supported on pci devices. */
if (WARN_ON(!dev->pdev))
return -EINVAL;
switch (ctl->func) {
case DRM_INST_HANDLER:
irq = dev->pdev->irq;
if (dev->if_version < DRM_IF_VERSION(1, 2) &&
ctl->irq != irq)
return -EINVAL;
mutex_lock(&dev->struct_mutex);
ret = drm_irq_install(dev, irq);
mutex_unlock(&dev->struct_mutex);
return ret;
case DRM_UNINST_HANDLER:
mutex_lock(&dev->struct_mutex);
ret = drm_irq_uninstall(dev);
mutex_unlock(&dev->struct_mutex);
return ret;
default:
return -EINVAL;
}
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Daniel Vetter | 101 | 56.42% | 2 | 16.67% |
Chris Wilson | 18 | 10.06% | 3 | 25.00% |
Mario Kleiner | 16 | 8.94% | 1 | 8.33% |
Ville Syrjälä | 16 | 8.94% | 2 | 16.67% |
Jesse Barnes | 12 | 6.70% | 1 | 8.33% |
Rob Clark | 8 | 4.47% | 1 | 8.33% |
Kristian Högsberg | 5 | 2.79% | 1 | 8.33% |
Thierry Reding | 3 | 1.68% | 1 | 8.33% |
Total | 179 | 100.00% | 12 | 100.00% |
Overall Contributors
Person | Tokens | Prop | Commits | CommitProp |
Daniel Vetter | 387 | 59.72% | 3 | 10.00% |
Jesse Barnes | 50 | 7.72% | 3 | 10.00% |
Kristian Högsberg | 41 | 6.33% | 1 | 3.33% |
Chris Wilson | 36 | 5.56% | 6 | 20.00% |
Dave Airlie | 33 | 5.09% | 5 | 16.67% |
Ville Syrjälä | 26 | 4.01% | 2 | 6.67% |
Mario Kleiner | 22 | 3.40% | 1 | 3.33% |
Michel Dänzer | 20 | 3.09% | 3 | 10.00% |
Eric Anholt | 18 | 2.78% | 2 | 6.67% |
Rob Clark | 10 | 1.54% | 2 | 6.67% |
Thierry Reding | 3 | 0.46% | 1 | 3.33% |
Paul Gortmaker | 2 | 0.31% | 1 | 3.33% |
Total | 648 | 100.00% | 30 | 100.00% |
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.