#include <linux/pm_qos.h>
 #include <linux/sort.h>
 
+#include "intel_engine_heartbeat.h"
 #include "intel_engine_pm.h"
 #include "intel_gpu_commands.h"
 #include "intel_gt_pm.h"
 /* Try to isolate the impact of cstates from determing frequency response */
 #define CPU_LATENCY 0 /* -1 to disable pm_qos, 0 to disable cstates */
 
+static unsigned long engine_heartbeat_disable(struct intel_engine_cs *engine)
+{
+       unsigned long old;
+
+       old = fetch_and_zero(&engine->props.heartbeat_interval_ms);
+
+       intel_engine_pm_get(engine);
+       intel_engine_park_heartbeat(engine);
+
+       return old;
+}
+
+static void engine_heartbeat_enable(struct intel_engine_cs *engine,
+                                   unsigned long saved)
+{
+       intel_engine_pm_put(engine);
+
+       engine->props.heartbeat_interval_ms = saved;
+}
+
 static void dummy_rps_work(struct work_struct *wrk)
 {
 }
 
        intel_gt_pm_get(gt);
        for_each_engine(engine, gt, id) {
+               unsigned long saved_heartbeat;
                struct i915_request *rq;
                ktime_t min_dt, max_dt;
                int f, limit;
                if (!intel_engine_can_store_dword(engine))
                        continue;
 
+               saved_heartbeat = engine_heartbeat_disable(engine);
+
                rq = igt_spinner_create_request(&spin,
                                                engine->kernel_context,
                                                MI_NOOP);
                        pr_err("%s: RPS spinner did not start\n",
                               engine->name);
                        igt_spinner_end(&spin);
+                       engine_heartbeat_enable(engine, saved_heartbeat);
                        intel_gt_set_wedged(engine->gt);
                        err = -EIO;
                        break;
                        pr_err("%s: could not set minimum frequency [%x], only %x!\n",
                               engine->name, rps->min_freq, read_cagf(rps));
                        igt_spinner_end(&spin);
+                       engine_heartbeat_enable(engine, saved_heartbeat);
                        show_pstate_limits(rps);
                        err = -EINVAL;
                        break;
                        pr_err("%s: could not restore minimum frequency [%x], only %x!\n",
                               engine->name, rps->min_freq, read_cagf(rps));
                        igt_spinner_end(&spin);
+                       engine_heartbeat_enable(engine, saved_heartbeat);
                        show_pstate_limits(rps);
                        err = -EINVAL;
                        break;
                min_dt = ktime_sub(ktime_get(), min_dt);
 
                igt_spinner_end(&spin);
+               engine_heartbeat_enable(engine, saved_heartbeat);
 
                pr_info("%s: range:[%x:%uMHz, %x:%uMHz] limit:[%x:%uMHz], %x:%x response %lluns:%lluns\n",
                        engine->name,
        rps->work.func = dummy_rps_work;
 
        for_each_engine(engine, gt, id) {
+               unsigned long saved_heartbeat;
                struct i915_request *rq;
                struct i915_vma *vma;
                u32 *cancel, *cntr;
                        int freq;
                } min, max;
 
+               saved_heartbeat = engine_heartbeat_disable(engine);
+
                vma = create_spin_counter(engine,
                                          engine->kernel_context->vm, false,
                                          &cancel, &cntr);
                if (IS_ERR(vma)) {
                        err = PTR_ERR(vma);
+                       engine_heartbeat_enable(engine, saved_heartbeat);
                        break;
                }
 
                i915_vma_unpin(vma);
                i915_vma_put(vma);
 
+               engine_heartbeat_enable(engine, saved_heartbeat);
                if (igt_flush_test(gt->i915))
                        err = -EIO;
                if (err)
        rps->work.func = dummy_rps_work;
 
        for_each_engine(engine, gt, id) {
+               unsigned long saved_heartbeat;
                struct i915_request *rq;
                struct i915_vma *vma;
                u32 *cancel, *cntr;
                        int freq;
                } min, max;
 
+               saved_heartbeat = engine_heartbeat_disable(engine);
+
                vma = create_spin_counter(engine,
                                          engine->kernel_context->vm, true,
                                          &cancel, &cntr);
                if (IS_ERR(vma)) {
                        err = PTR_ERR(vma);
+                       engine_heartbeat_enable(engine, saved_heartbeat);
                        break;
                }
 
                i915_vma_unpin(vma);
                i915_vma_put(vma);
 
+               engine_heartbeat_enable(engine, saved_heartbeat);
                if (igt_flush_test(gt->i915))
                        err = -EIO;
                if (err)
        for_each_engine(engine, gt, id) {
                /* Keep the engine busy with a spinner; expect an UP! */
                if (pm_events & GEN6_PM_RP_UP_THRESHOLD) {
+                       unsigned long saved_heartbeat;
+
                        intel_gt_pm_wait_for_idle(engine->gt);
                        GEM_BUG_ON(rps->active);
 
-                       intel_engine_pm_get(engine);
+                       saved_heartbeat = engine_heartbeat_disable(engine);
+
                        err = __rps_up_interrupt(rps, engine, &spin);
-                       intel_engine_pm_put(engine);
+
+                       engine_heartbeat_enable(engine, saved_heartbeat);
                        if (err)
                                goto out;
 
 
                /* Keep the engine awake but idle and check for DOWN */
                if (pm_events & GEN6_PM_RP_DOWN_THRESHOLD) {
-                       intel_engine_pm_get(engine);
+                       unsigned long saved_heartbeat;
+
+                       saved_heartbeat = engine_heartbeat_disable(engine);
                        intel_rc6_disable(>->rc6);
 
                        err = __rps_down_interrupt(rps, engine);
 
                        intel_rc6_enable(>->rc6);
-                       intel_engine_pm_put(engine);
+                       engine_heartbeat_enable(engine, saved_heartbeat);
                        if (err)
                                goto out;
                }
        rps->work.func = dummy_rps_work;
 
        for_each_engine(engine, gt, id) {
+               unsigned long saved_heartbeat;
                struct i915_request *rq;
                struct {
                        u64 power;
                if (!intel_engine_can_store_dword(engine))
                        continue;
 
+               saved_heartbeat = engine_heartbeat_disable(engine);
+
                rq = igt_spinner_create_request(&spin,
                                                engine->kernel_context,
                                                MI_NOOP);
                if (IS_ERR(rq)) {
+                       engine_heartbeat_enable(engine, saved_heartbeat);
                        err = PTR_ERR(rq);
                        break;
                }
                if (!igt_wait_for_spinner(&spin, rq)) {
                        pr_err("%s: RPS spinner did not start\n",
                               engine->name);
+                       igt_spinner_end(&spin);
+                       engine_heartbeat_enable(engine, saved_heartbeat);
                        intel_gt_set_wedged(engine->gt);
                        err = -EIO;
                        break;
                min.power = measure_power_at(rps, &min.freq);
 
                igt_spinner_end(&spin);
+               engine_heartbeat_enable(engine, saved_heartbeat);
 
                pr_info("%s: min:%llumW @ %uMHz, max:%llumW @ %uMHz\n",
                        engine->name,