lkml.org 
[lkml]   [2011]   [Jun]   [1]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[147/165] drm/i915: fix user irq miss in BSD ring on g4x
    2.6.39-stable review patch.  If anyone has any objections, please let us know.

    ------------------
    Content-Length: 2380
    Lines: 75

    From: Boqun Feng <boqun.feng@intel.com>

    commit 5bfa1063a775836a84f97e4df863fc36e1f856ad upstream.

    On g4x, user interrupt in BSD ring is missed.
    This is because though g4x and ironlake share the same bsd_ring,
    their interrupt control interfaces have _two_ differences.

    1.different irq enable/disable functions:
    On g4x are i915_enable_irq and i915_disable_irq.
    On ironlake are ironlake_enable_irq and ironlake_disable_irq.
    2.different irq flag:
    On g4x user interrupt flag in BSD ring on is I915_BSD_USER_INTERRUPT.
    On ironlake is GT_BSD_USER_INTERRUPT

    Old bsd_ring_get/put_irq call ring_get_irq and ring_get_irq.
    ring_get_irq and ring_put_irq only call ironlake_enable/disable_irq.
    So comes the irq miss on g4x.

    To fix this, as other rings' code do, conditionally call different
    functions(i915_enable/disable_irq and ironlake_enable/disable_irq)
    and use different interrupt flags in bsd_ring_get/put_irq.

    Signed-off-by: Boqun Feng <boqun.feng@intel.com>
    Reviewed-by: Xiang, Haihao <haihao.xiang@intel.com>
    Signed-off-by: Keith Packard <keithp@keithp.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

    ---
    drivers/gpu/drm/i915/intel_ringbuffer.c | 29 +++++++++++++++++++++++++++--
    1 file changed, 27 insertions(+), 2 deletions(-)

    --- a/drivers/gpu/drm/i915/intel_ringbuffer.c
    +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
    @@ -666,12 +666,37 @@ gen6_ring_put_irq(struct intel_ring_buff
    static bool
    bsd_ring_get_irq(struct intel_ring_buffer *ring)
    {
    - return ring_get_irq(ring, GT_BSD_USER_INTERRUPT);
    + struct drm_device *dev = ring->dev;
    + drm_i915_private_t *dev_priv = dev->dev_private;
    +
    + if (!dev->irq_enabled)
    + return false;
    +
    + spin_lock(&ring->irq_lock);
    + if (ring->irq_refcount++ == 0) {
    + if (IS_G4X(dev))
    + i915_enable_irq(dev_priv, I915_BSD_USER_INTERRUPT);
    + else
    + ironlake_enable_irq(dev_priv, GT_BSD_USER_INTERRUPT);
    + }
    + spin_unlock(&ring->irq_lock);
    +
    + return true;
    }
    static void
    bsd_ring_put_irq(struct intel_ring_buffer *ring)
    {
    - ring_put_irq(ring, GT_BSD_USER_INTERRUPT);
    + struct drm_device *dev = ring->dev;
    + drm_i915_private_t *dev_priv = dev->dev_private;
    +
    + spin_lock(&ring->irq_lock);
    + if (--ring->irq_refcount == 0) {
    + if (IS_G4X(dev))
    + i915_disable_irq(dev_priv, I915_BSD_USER_INTERRUPT);
    + else
    + ironlake_disable_irq(dev_priv, GT_BSD_USER_INTERRUPT);
    + }
    + spin_unlock(&ring->irq_lock);
    }

    static int



    \
     
     \ /
      Last update: 2011-06-01 10:35    [W:2.954 / U:0.128 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site