FAQ Search Today's Posts Mark Forums Read
» Video Reviews

» Linux Archive

Linux-archive is a website aiming to archive linux email lists and to make them easily accessible for linux users/developers.


» Sponsor

» Partners

» Sponsor

Go Back   Linux Archive > Ubuntu > Ubuntu Kernel Team

 
 
LinkBack Thread Tools
 
Old 01-15-2010, 01:29 AM
Zou Nan hai
 
Default drm/i915: remove loop in Ironlake interrupt handler

On Ironlake, there is an interrupt master control bit. With the bit
disabled before clearing IIR, we do not need to handle extra interrupt
in a loop. This patch removes the loop in Ironlake interrupt handler.
It fixed irq lost issue on some Ironlake platforms.

Refactored slightly for karmic because it wouldn't apply directly.

Signed-off-by: Zou Nan hai <Nanhai.zou@intel.com>
Signed-off-by: Zhenyu Wang <zhenyuw@linux.intel.com>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Steve Conklin <sconklin@canonical.com>
---
drivers/gpu/drm/i915/i915_irq.c | 61 ++++++++++++++++----------------------
1 files changed, 26 insertions(+), 35 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 5caf737..84a47c7 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -268,7 +268,6 @@ irqreturn_t igdng_irq_handler(struct drm_device *dev)
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
int ret = IRQ_NONE;
u32 de_iir, gt_iir, de_ier, pch_iir;
- u32 new_de_iir, new_gt_iir, new_pch_iir;
struct drm_i915_master_private *master_priv;

/* disable master interrupt before clearing iir */
@@ -280,47 +279,39 @@ irqreturn_t igdng_irq_handler(struct drm_device *dev)
gt_iir = I915_READ(GTIIR);
pch_iir = I915_READ(SDEIIR);

- for (; {
- if (de_iir == 0 && gt_iir == 0 && pch_iir == 0)
- break;
-
- ret = IRQ_HANDLED;
-
- /* should clear PCH hotplug event before clear CPU irq */
- I915_WRITE(SDEIIR, pch_iir);
- new_pch_iir = I915_READ(SDEIIR);
+ if (de_iir == 0 && gt_iir == 0 && pch_iir == 0)
+ goto done;

- I915_WRITE(DEIIR, de_iir);
- new_de_iir = I915_READ(DEIIR);
- I915_WRITE(GTIIR, gt_iir);
- new_gt_iir = I915_READ(GTIIR);
-
- if (dev->primary->master) {
- master_priv = dev->primary->master->driver_priv;
- if (master_priv->sarea_priv)
- master_priv->sarea_priv->last_dispatch =
- READ_BREADCRUMB(dev_priv);
- }
+ ret = IRQ_HANDLED;

- if (gt_iir & GT_USER_INTERRUPT) {
- dev_priv->mm.irq_gem_seqno = i915_get_gem_seqno(dev);
- DRM_WAKEUP(&dev_priv->irq_queue);
- }
+ if (dev->primary->master) {
+ master_priv = dev->primary->master->driver_priv;
+ if (master_priv->sarea_priv)
+ master_priv->sarea_priv->last_dispatch =
+ READ_BREADCRUMB(dev_priv);
+ }

- if (de_iir & DE_GSE)
- ironlake_opregion_gse_intr(dev);
+ if (gt_iir & GT_USER_INTERRUPT) {
+ u32 seqno = i915_get_gem_seqno(dev);
+ dev_priv->mm.irq_gem_seqno = seqno;
+ DRM_WAKEUP(&dev_priv->irq_queue);
+ }

- /* check event from PCH */
- if ((de_iir & DE_PCH_EVENT) &&
- (pch_iir & SDE_HOTPLUG_MASK)) {
- queue_work(dev_priv->wq, &dev_priv->hotplug_work);
- }
+ if (de_iir & DE_GSE)
+ ironlake_opregion_gse_intr(dev);

- de_iir = new_de_iir;
- gt_iir = new_gt_iir;
- pch_iir = new_pch_iir;
+ /* check event from PCH */
+ if ((de_iir & DE_PCH_EVENT) &&
+ (pch_iir & SDE_HOTPLUG_MASK)) {
+ queue_work(dev_priv->wq, &dev_priv->hotplug_work);
}

+ /* should clear PCH hotplug event before clear CPU irq */
+ I915_WRITE(SDEIIR, pch_iir);
+ I915_WRITE(GTIIR, gt_iir);
+ I915_WRITE(DEIIR, de_iir);
+
+done:
I915_WRITE(DEIER, de_ier);
(void)I915_READ(DEIER);

--
1.6.3.3


--------------040605020201020705080808
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

--
kernel-team mailing list
kernel-team@lists.ubuntu.com
https://lists.ubuntu.com/mailman/listinfo/kernel-team

--------------040605020201020705080808--
 
Old 01-26-2010, 01:58 PM
Steve Conklin
 
Default drm/i915: remove loop in Ironlake interrupt handler

From: Zou Nan hai <Nanhai.zou@intel.com>

On Ironlake, there is an interrupt master control bit. With the bit
disabled before clearing IIR, we do not need to handle extra interrupt
in a loop. This patch removes the loop in Ironlake interrupt handler.
It fixed irq lost issue on some Ironlake platforms.

Cc: Stable Team <stable@kernel.org>
Signed-off-by: Zou Nan hai <Nanhai.zou@intel.com>
Signed-off-by: Zhenyu Wang <zhenyuw@linux.intel.com>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Steve Conklin <sconklin@canonical.com>
---
drivers/gpu/drm/i915/i915_irq.c | 66 +++++++++++++++++----------------------
1 files changed, 29 insertions(+), 37 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index da94c99..dad6000 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -269,7 +269,6 @@ irqreturn_t igdng_irq_handler(struct drm_device *dev)
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
int ret = IRQ_NONE;
u32 de_iir, gt_iir, de_ier, pch_iir;
- u32 new_de_iir, new_gt_iir, new_pch_iir;
struct drm_i915_master_private *master_priv;

/* disable master interrupt before clearing iir */
@@ -281,49 +280,42 @@ irqreturn_t igdng_irq_handler(struct drm_device *dev)
gt_iir = I915_READ(GTIIR);
pch_iir = I915_READ(SDEIIR);

- for (; {
- if (de_iir == 0 && gt_iir == 0 && pch_iir == 0)
- break;
-
- ret = IRQ_HANDLED;
-
- /* should clear PCH hotplug event before clear CPU irq */
- I915_WRITE(SDEIIR, pch_iir);
- new_pch_iir = I915_READ(SDEIIR);
-
- I915_WRITE(DEIIR, de_iir);
- new_de_iir = I915_READ(DEIIR);
- I915_WRITE(GTIIR, gt_iir);
- new_gt_iir = I915_READ(GTIIR);
+ if (de_iir == 0 && gt_iir == 0 && pch_iir == 0)
+ goto done;

- if (dev->primary->master) {
- master_priv = dev->primary->master->driver_priv;
- if (master_priv->sarea_priv)
- master_priv->sarea_priv->last_dispatch =
- READ_BREADCRUMB(dev_priv);
- }
+ ret = IRQ_HANDLED;

- if (gt_iir & GT_USER_INTERRUPT) {
- u32 seqno = i915_get_gem_seqno(dev);
- dev_priv->mm.irq_gem_seqno = seqno;
- trace_i915_gem_request_complete(dev, seqno);
- DRM_WAKEUP(&dev_priv->irq_queue);
- }
+ if (dev->primary->master) {
+ master_priv = dev->primary->master->driver_priv;
+ if (master_priv->sarea_priv)
+ master_priv->sarea_priv->last_dispatch =
+ READ_BREADCRUMB(dev_priv);
+ }

- if (de_iir & DE_GSE)
- ironlake_opregion_gse_intr(dev);
+ if (gt_iir & GT_USER_INTERRUPT) {
+ u32 seqno = i915_get_gem_seqno(dev);
+ dev_priv->mm.irq_gem_seqno = seqno;
+ trace_i915_gem_request_complete(dev, seqno);
+ DRM_WAKEUP(&dev_priv->irq_queue);
+ dev_priv->hangcheck_count = 0;
+ mod_timer(&dev_priv->hangcheck_timer, jiffies + DRM_I915_HANGCHECK_PERIOD);
+ }

- /* check event from PCH */
- if ((de_iir & DE_PCH_EVENT) &&
- (pch_iir & SDE_HOTPLUG_MASK)) {
- queue_work(dev_priv->wq, &dev_priv->hotplug_work);
- }
+ if (de_iir & DE_GSE)
+ ironlake_opregion_gse_intr(dev);

- de_iir = new_de_iir;
- gt_iir = new_gt_iir;
- pch_iir = new_pch_iir;
+ /* check event from PCH */
+ if ((de_iir & DE_PCH_EVENT) &&
+ (pch_iir & SDE_HOTPLUG_MASK)) {
+ queue_work(dev_priv->wq, &dev_priv->hotplug_work);
}

+ /* should clear PCH hotplug event before clear CPU irq */
+ I915_WRITE(SDEIIR, pch_iir);
+ I915_WRITE(GTIIR, gt_iir);
+ I915_WRITE(DEIIR, de_iir);
+
+done:
I915_WRITE(DEIER, de_ier);
(void)I915_READ(DEIER);

--
1.6.3.3


--
kernel-team mailing list
kernel-team@lists.ubuntu.com
https://lists.ubuntu.com/mailman/listinfo/kernel-team
 
Old 01-26-2010, 02:03 PM
Steve Conklin
 
Default drm/i915: remove loop in Ironlake interrupt handler

From: Zou Nan hai <Nanhai.zou@intel.com>

On Ironlake, there is an interrupt master control bit. With the bit
disabled before clearing IIR, we do not need to handle extra interrupt
in a loop. This patch removes the loop in Ironlake interrupt handler.
It fixed irq lost issue on some Ironlake platforms.

Cc: Stable Team <stable@kernel.org>
Signed-off-by: Zou Nan hai <Nanhai.zou@intel.com>
Signed-off-by: Zhenyu Wang <zhenyuw@linux.intel.com>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Steve Conklin <sconklin@canonical.com>
---
drivers/gpu/drm/i915/i915_irq.c | 66 +++++++++++++++++----------------------
1 files changed, 29 insertions(+), 37 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index da94c99..dad6000 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -269,7 +269,6 @@ irqreturn_t igdng_irq_handler(struct drm_device *dev)
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
int ret = IRQ_NONE;
u32 de_iir, gt_iir, de_ier, pch_iir;
- u32 new_de_iir, new_gt_iir, new_pch_iir;
struct drm_i915_master_private *master_priv;

/* disable master interrupt before clearing iir */
@@ -281,49 +280,42 @@ irqreturn_t igdng_irq_handler(struct drm_device *dev)
gt_iir = I915_READ(GTIIR);
pch_iir = I915_READ(SDEIIR);

- for (; {
- if (de_iir == 0 && gt_iir == 0 && pch_iir == 0)
- break;
-
- ret = IRQ_HANDLED;
-
- /* should clear PCH hotplug event before clear CPU irq */
- I915_WRITE(SDEIIR, pch_iir);
- new_pch_iir = I915_READ(SDEIIR);
-
- I915_WRITE(DEIIR, de_iir);
- new_de_iir = I915_READ(DEIIR);
- I915_WRITE(GTIIR, gt_iir);
- new_gt_iir = I915_READ(GTIIR);
+ if (de_iir == 0 && gt_iir == 0 && pch_iir == 0)
+ goto done;

- if (dev->primary->master) {
- master_priv = dev->primary->master->driver_priv;
- if (master_priv->sarea_priv)
- master_priv->sarea_priv->last_dispatch =
- READ_BREADCRUMB(dev_priv);
- }
+ ret = IRQ_HANDLED;

- if (gt_iir & GT_USER_INTERRUPT) {
- u32 seqno = i915_get_gem_seqno(dev);
- dev_priv->mm.irq_gem_seqno = seqno;
- trace_i915_gem_request_complete(dev, seqno);
- DRM_WAKEUP(&dev_priv->irq_queue);
- }
+ if (dev->primary->master) {
+ master_priv = dev->primary->master->driver_priv;
+ if (master_priv->sarea_priv)
+ master_priv->sarea_priv->last_dispatch =
+ READ_BREADCRUMB(dev_priv);
+ }

- if (de_iir & DE_GSE)
- ironlake_opregion_gse_intr(dev);
+ if (gt_iir & GT_USER_INTERRUPT) {
+ u32 seqno = i915_get_gem_seqno(dev);
+ dev_priv->mm.irq_gem_seqno = seqno;
+ trace_i915_gem_request_complete(dev, seqno);
+ DRM_WAKEUP(&dev_priv->irq_queue);
+ dev_priv->hangcheck_count = 0;
+ mod_timer(&dev_priv->hangcheck_timer, jiffies + DRM_I915_HANGCHECK_PERIOD);
+ }

- /* check event from PCH */
- if ((de_iir & DE_PCH_EVENT) &&
- (pch_iir & SDE_HOTPLUG_MASK)) {
- queue_work(dev_priv->wq, &dev_priv->hotplug_work);
- }
+ if (de_iir & DE_GSE)
+ ironlake_opregion_gse_intr(dev);

- de_iir = new_de_iir;
- gt_iir = new_gt_iir;
- pch_iir = new_pch_iir;
+ /* check event from PCH */
+ if ((de_iir & DE_PCH_EVENT) &&
+ (pch_iir & SDE_HOTPLUG_MASK)) {
+ queue_work(dev_priv->wq, &dev_priv->hotplug_work);
}

+ /* should clear PCH hotplug event before clear CPU irq */
+ I915_WRITE(SDEIIR, pch_iir);
+ I915_WRITE(GTIIR, gt_iir);
+ I915_WRITE(DEIIR, de_iir);
+
+done:
I915_WRITE(DEIER, de_ier);
(void)I915_READ(DEIER);

--
1.6.3.3


--
kernel-team mailing list
kernel-team@lists.ubuntu.com
https://lists.ubuntu.com/mailman/listinfo/kernel-team
 

Thread Tools




All times are GMT. The time now is 06:01 AM.

VBulletin, Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO ©2007, Crawlability, Inc.
Copyright 2007 - 2008, www.linux-archive.org