diff options
author | Paulo Zanoni <paulo.r.zanoni@intel.com> | 2013-08-15 16:50:01 +0200 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2013-08-23 14:52:29 +0200 |
commit | 60611c137641af41895828cfc74f5be64ed69b49 (patch) | |
tree | 151ed550b03b1555fb982ffbe6148074db22bae1 | |
parent | drm/i915: don't disable/reenable IVB error interrupts when not needed (diff) | |
download | linux-60611c137641af41895828cfc74f5be64ed69b49.tar.xz linux-60611c137641af41895828cfc74f5be64ed69b49.zip |
drm/i915: don't queue PM events we won't process
On SNB/IVB/VLV we only call gen6_rps_irq_handler if one of the IIR
bits set is part of GEN6_PM_RPS_EVENTS, but at gen6_rps_irq_handler we
add all the enabled IIR bits to the work queue, not only the ones that
are part of GEN6_PM_RPS_EVENTS. But then gen6_pm_rps_work only
processes GEN6_PM_RPS_EVENTS, so it's useless to add anything that's
not GEN6_PM_RPS_EVENTS to the work queue.
As a bonus, gen6_rps_irq_handler looks more similar to
hsw_pm_irq_handler, so we may be able to merge them in the future.
v2: - Add a WARN in case we queued something we're not going to
process.
Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
Reviewed-by: Ben Widawsky <ben@bwidawsk.net> (v1)
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-rw-r--r-- | drivers/gpu/drm/i915/i915_irq.c | 9 |
1 files changed, 6 insertions, 3 deletions
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 976113af1859..c10d2f1af0be 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -789,6 +789,9 @@ static void gen6_pm_rps_work(struct work_struct *work) snb_enable_pm_irq(dev_priv, GEN6_PM_RPS_EVENTS); spin_unlock_irq(&dev_priv->irq_lock); + /* Make sure we didn't queue anything we're not going to process. */ + WARN_ON(pm_iir & ~GEN6_PM_RPS_EVENTS); + if ((pm_iir & GEN6_PM_RPS_EVENTS) == 0) return; @@ -959,7 +962,7 @@ static void gen6_rps_irq_handler(struct drm_i915_private *dev_priv, */ spin_lock(&dev_priv->irq_lock); - dev_priv->rps.pm_iir |= pm_iir; + dev_priv->rps.pm_iir |= pm_iir & GEN6_PM_RPS_EVENTS; snb_set_pm_irq(dev_priv, dev_priv->rps.pm_iir); spin_unlock(&dev_priv->irq_lock); @@ -1128,7 +1131,7 @@ static irqreturn_t valleyview_irq_handler(int irq, void *arg) if (pipe_stats[0] & PIPE_GMBUS_INTERRUPT_STATUS) gmbus_irq_handler(dev); - if (pm_iir & GEN6_PM_RPS_EVENTS) + if (pm_iir) gen6_rps_irq_handler(dev_priv, pm_iir); I915_WRITE(GTIIR, gt_iir); @@ -1433,7 +1436,7 @@ static irqreturn_t ironlake_irq_handler(int irq, void *arg) if (pm_iir) { if (IS_HASWELL(dev)) hsw_pm_irq_handler(dev_priv, pm_iir); - else if (pm_iir & GEN6_PM_RPS_EVENTS) + else gen6_rps_irq_handler(dev_priv, pm_iir); I915_WRITE(GEN6_PMIIR, pm_iir); ret = IRQ_HANDLED; |