OSDN Git Service

RADEON: fix race in vblank interrupt handling
authorJesse Barnes <jbarnes@jbarnes-mobile.amr.corp.intel.com>
Thu, 21 Jun 2007 22:23:20 +0000 (15:23 -0700)
committerJesse Barnes <jbarnes@jbarnes-mobile.amr.corp.intel.com>
Thu, 21 Jun 2007 22:23:20 +0000 (15:23 -0700)
It's possible that we disable vblank interrupts and clear the
corresponding flag in irq_enable_reg, but receive an interrupt at just
the wrong time, causing us to not ack it properly, nor report to the
core kernel that it was handled.  Fix that case by always handling
vblank interrupts, even if the irq_enable_reg field is clear.

shared-core/radeon_irq.c

index d1f0e31..4409026 100644 (file)
@@ -37,7 +37,7 @@
 
 static void radeon_irq_set_state(drm_device_t *dev, u32 mask, int state)
 {
-       drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private;
+       drm_radeon_private_t *dev_priv = dev->dev_private;
 
        if (state)
                dev_priv->irq_enable_reg |= mask;
@@ -49,8 +49,6 @@ static void radeon_irq_set_state(drm_device_t *dev, u32 mask, int state)
 
 int radeon_enable_vblank(drm_device_t *dev, int crtc)
 {
-       drm_radeon_private_t *dev_priv = dev->dev_private;
-
        switch (crtc) {
        case 0:
                radeon_irq_set_state(dev, RADEON_CRTC_VBLANK_MASK, 1);
@@ -69,8 +67,6 @@ int radeon_enable_vblank(drm_device_t *dev, int crtc)
 
 void radeon_disable_vblank(drm_device_t *dev, int crtc)
 {
-       drm_radeon_private_t *dev_priv = dev->dev_private;
-
        switch (crtc) {
        case 0:
                radeon_irq_set_state(dev, RADEON_CRTC_VBLANK_MASK, 0);
@@ -88,7 +84,8 @@ void radeon_disable_vblank(drm_device_t *dev, int crtc)
 static __inline__ u32 radeon_acknowledge_irqs(drm_radeon_private_t * dev_priv,
                                              u32 mask)
 {
-       u32 irqs = RADEON_READ(RADEON_GEN_INT_STATUS) & mask;
+       u32 irqs = RADEON_READ(RADEON_GEN_INT_STATUS) &
+               (mask | RADEON_CRTC_VBLANK_MASK | RADEON_CRTC2_VBLANK_MASK);
        if (irqs)
                RADEON_WRITE(RADEON_GEN_INT_STATUS, irqs);
        return irqs;