Merge tag 'mmc-v4.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc
[cascardo/linux.git] / drivers / gpu / drm / i915 / intel_breadcrumbs.c
index 9bad14d..495611b 100644 (file)
@@ -578,6 +578,36 @@ int intel_engine_init_breadcrumbs(struct intel_engine_cs *engine)
        return 0;
 }
 
+static void cancel_fake_irq(struct intel_engine_cs *engine)
+{
+       struct intel_breadcrumbs *b = &engine->breadcrumbs;
+
+       del_timer_sync(&b->hangcheck);
+       del_timer_sync(&b->fake_irq);
+       clear_bit(engine->id, &engine->i915->gpu_error.missed_irq_rings);
+}
+
+void intel_engine_reset_breadcrumbs(struct intel_engine_cs *engine)
+{
+       struct intel_breadcrumbs *b = &engine->breadcrumbs;
+
+       cancel_fake_irq(engine);
+       spin_lock(&b->lock);
+
+       __intel_breadcrumbs_disable_irq(b);
+       if (intel_engine_has_waiter(engine)) {
+               b->timeout = wait_timeout();
+               __intel_breadcrumbs_enable_irq(b);
+               if (READ_ONCE(b->irq_posted))
+                       wake_up_process(b->first_wait->tsk);
+       } else {
+               /* sanitize the IMR and unmask any auxiliary interrupts */
+               irq_disable(engine);
+       }
+
+       spin_unlock(&b->lock);
+}
+
 void intel_engine_fini_breadcrumbs(struct intel_engine_cs *engine)
 {
        struct intel_breadcrumbs *b = &engine->breadcrumbs;
@@ -585,8 +615,7 @@ void intel_engine_fini_breadcrumbs(struct intel_engine_cs *engine)
        if (!IS_ERR_OR_NULL(b->signaler))
                kthread_stop(b->signaler);
 
-       del_timer_sync(&b->hangcheck);
-       del_timer_sync(&b->fake_irq);
+       cancel_fake_irq(engine);
 }
 
 unsigned int intel_kick_waiters(struct drm_i915_private *i915)