aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/i915_irq.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/i915_irq.c')
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c15
1 files changed, 8 insertions, 7 deletions
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 8f5276614ce2..13e664ddb611 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -309,12 +309,12 @@ static void i915_error_work_func(struct work_struct *work)
309 DRM_DEBUG("generating error event\n"); 309 DRM_DEBUG("generating error event\n");
310 kobject_uevent_env(&dev->primary->kdev.kobj, KOBJ_CHANGE, error_event); 310 kobject_uevent_env(&dev->primary->kdev.kobj, KOBJ_CHANGE, error_event);
311 311
312 if (dev_priv->mm.wedged) { 312 if (atomic_read(&dev_priv->mm.wedged)) {
313 if (IS_I965G(dev)) { 313 if (IS_I965G(dev)) {
314 DRM_DEBUG("resetting chip\n"); 314 DRM_DEBUG("resetting chip\n");
315 kobject_uevent_env(&dev->primary->kdev.kobj, KOBJ_CHANGE, reset_event); 315 kobject_uevent_env(&dev->primary->kdev.kobj, KOBJ_CHANGE, reset_event);
316 if (!i965_reset(dev, GDRST_RENDER)) { 316 if (!i965_reset(dev, GDRST_RENDER)) {
317 dev_priv->mm.wedged = 0; 317 atomic_set(&dev_priv->mm.wedged, 0);
318 kobject_uevent_env(&dev->primary->kdev.kobj, KOBJ_CHANGE, reset_done_event); 318 kobject_uevent_env(&dev->primary->kdev.kobj, KOBJ_CHANGE, reset_done_event);
319 } 319 }
320 } else { 320 } else {
@@ -385,7 +385,7 @@ out:
385 * so userspace knows something bad happened (should trigger collection 385 * so userspace knows something bad happened (should trigger collection
386 * of a ring dump etc.). 386 * of a ring dump etc.).
387 */ 387 */
388static void i915_handle_error(struct drm_device *dev) 388static void i915_handle_error(struct drm_device *dev, bool wedged)
389{ 389{
390 struct drm_i915_private *dev_priv = dev->dev_private; 390 struct drm_i915_private *dev_priv = dev->dev_private;
391 u32 eir = I915_READ(EIR); 391 u32 eir = I915_READ(EIR);
@@ -495,7 +495,9 @@ static void i915_handle_error(struct drm_device *dev)
495 I915_WRITE(IIR, I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT); 495 I915_WRITE(IIR, I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT);
496 } 496 }
497 497
498 if (dev_priv->mm.wedged) { 498 if (wedged) {
499 atomic_set(&dev_priv->mm.wedged, 1);
500
499 /* 501 /*
500 * Wakeup waiting processes so they don't hang 502 * Wakeup waiting processes so they don't hang
501 */ 503 */
@@ -548,7 +550,7 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
548 pipeb_stats = I915_READ(PIPEBSTAT); 550 pipeb_stats = I915_READ(PIPEBSTAT);
549 551
550 if (iir & I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT) 552 if (iir & I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT)
551 i915_handle_error(dev); 553 i915_handle_error(dev, false);
552 554
553 /* 555 /*
554 * Clear the PIPE(A|B)STAT regs before the IIR 556 * Clear the PIPE(A|B)STAT regs before the IIR
@@ -934,8 +936,7 @@ void i915_hangcheck_elapsed(unsigned long data)
934 936
935 if (dev_priv->last_acthd == acthd && dev_priv->hangcheck_count > 0) { 937 if (dev_priv->last_acthd == acthd && dev_priv->hangcheck_count > 0) {
936 DRM_ERROR("Hangcheck timer elapsed... GPU hung\n"); 938 DRM_ERROR("Hangcheck timer elapsed... GPU hung\n");
937 dev_priv->mm.wedged = true; /* Hopefully this is atomic */ 939 i915_handle_error(dev, true);
938 i915_handle_error(dev);
939 return; 940 return;
940 } 941 }
941 942