summaryrefslogtreecommitdiff
path: root/bsd-core/drm_irq.c
diff options
context:
space:
mode:
authorEric Anholt <anholt@freebsd.org>2003-10-19 23:35:58 +0000
committerEric Anholt <anholt@freebsd.org>2003-10-19 23:35:58 +0000
commit0cf1887139eb1ce18d09f7be0567aa93d802040d (patch)
tree05704a5a90bc9b0fbabed4029f200f9eff955953 /bsd-core/drm_irq.c
parent59fbe01fea8f77fc3810643c14a1738d197d4291 (diff)
- SMPng lock the DRM. This is only partial -- there are a few code paths
used by root (the X Server) which are not locked. However, it should deal with lost-IRQ issues on -current which I think people have been experiencing but I am unable to reproduce (though I understand why they would occur, because of a bug of mine). Note that most of the locking (DRM_LOCK()/UNLOCK()) is all covered by Giant still, so it doesn't matter yet. - Remove locking on FreeBSD-stable and NetBSD. These are covered by the fact that there is no reentrancy of the kernel except by interrupts, which are locked using spldrm()/splx() instead.
Diffstat (limited to 'bsd-core/drm_irq.c')
-rw-r--r--bsd-core/drm_irq.c30
1 files changed, 21 insertions, 9 deletions
diff --git a/bsd-core/drm_irq.c b/bsd-core/drm_irq.c
index 3366ff1c..f984118e 100644
--- a/bsd-core/drm_irq.c
+++ b/bsd-core/drm_irq.c
@@ -27,7 +27,19 @@
* Eric Anholt <anholt@FreeBSD.org>
*
*/
-
+
+#if defined(__FreeBSD__) && __FreeBSD_version >= 500000
+static irqreturn_t
+DRM(irq_handler_wrap)(DRM_IRQ_ARGS)
+{
+ drm_device_t *dev = (drm_device_t *)arg;
+
+ DRM_SPINLOCK(&dev->irq_lock);
+ DRM(irq_handler)(arg);
+ DRM_SPINUNLOCK(&dev->irq_lock);
+}
+#endif
+
int DRM(irq_install)( drm_device_t *dev, int irq )
{
int retcode;
@@ -54,8 +66,9 @@ int DRM(irq_install)( drm_device_t *dev, int irq )
TASK_INIT(&dev->task, 0, DRM(dma_immediate_bh), dev);
#endif
+ DRM_SPININIT(dev->irq_lock, "DRM IRQ lock");
+
#if __HAVE_VBL_IRQ && 0 /* disabled */
- DRM_SPININIT( dev->vbl_lock, "vblsig" );
TAILQ_INIT( &dev->vbl_sig_list );
#endif
@@ -72,6 +85,7 @@ int DRM(irq_install)( drm_device_t *dev, int irq )
if (pci_intr_map(&dev->pa, &dev->ih) != 0) {
#endif
DRM_LOCK();
+ DRM_SPINUNINIT(dev->irq_lock);
dev->irq = 0;
dev->irqrid = 0;
DRM_UNLOCK();
@@ -84,7 +98,7 @@ int DRM(irq_install)( drm_device_t *dev, int irq )
DRM(irq_handler), dev, &dev->irqh);
#else
retcode = bus_setup_intr(dev->device, dev->irqr, INTR_TYPE_TTY | INTR_MPSAFE,
- DRM(irq_handler), dev, &dev->irqh);
+ DRM(irq_handler_wrap), dev, &dev->irqh);
#endif
if ( retcode ) {
#elif defined(__NetBSD__)
@@ -96,6 +110,7 @@ int DRM(irq_install)( drm_device_t *dev, int irq )
#ifdef __FreeBSD__
bus_release_resource(dev->device, SYS_RES_IRQ, dev->irqrid, dev->irqr);
#endif
+ DRM_SPINUNINIT(dev->irq_lock);
dev->irq = 0;
dev->irqrid = 0;
DRM_UNLOCK();
@@ -133,6 +148,7 @@ int DRM(irq_uninstall)( drm_device_t *dev )
#elif defined(__NetBSD__)
pci_intr_disestablish(&dev->pa.pa_pc, dev->irqh);
#endif
+ DRM_SPINUNINIT(dev->irq_lock);
return 0;
}
@@ -187,9 +203,9 @@ int DRM(wait_vblank)( DRM_IOCTL_ARGS )
vblwait.reply.sequence = atomic_read(&dev->vbl_received);
- DRM_SPINLOCK(&dev->vbl_lock);
+ DRM_SPINLOCK(&dev->irq_lock);
TAILQ_INSERT_HEAD(&dev->vbl_sig_list, vbl_sig, link);
- DRM_SPINUNLOCK(&dev->vbl_lock);
+ DRM_SPINUNLOCK(&dev->irq_lock);
ret = 0;
#endif
ret = EINVAL;
@@ -218,8 +234,6 @@ void DRM(vbl_send_signals)( drm_device_t *dev )
unsigned int vbl_seq = atomic_read( &dev->vbl_received );
struct proc *p;
- DRM_SPINLOCK(&dev->vbl_lock);
-
vbl_sig = TAILQ_FIRST(&dev->vbl_sig_list);
while (vbl_sig != NULL) {
drm_vbl_sig_t *next = TAILQ_NEXT(vbl_sig, link);
@@ -234,8 +248,6 @@ void DRM(vbl_send_signals)( drm_device_t *dev )
}
vbl_sig = next;
}
-
- DRM_SPINUNLOCK(&dev->vbl_lock);
}
#endif