int (*info)(struct nvkm_engine *, u64 mthd, u64 *data);
        int (*init)(struct nvkm_engine *);
        int (*fini)(struct nvkm_engine *, bool suspend);
+       int (*reset)(struct nvkm_engine *);
        void (*intr)(struct nvkm_engine *);
        void (*tile)(struct nvkm_engine *, int region, struct nvkm_fb_tile *);
        bool (*chsw_load)(struct nvkm_engine *);
 
 struct nvkm_engine *nvkm_engine_ref(struct nvkm_engine *);
 void nvkm_engine_unref(struct nvkm_engine **);
+int nvkm_engine_reset(struct nvkm_engine *);
 void nvkm_engine_tile(struct nvkm_engine *, int region);
 bool nvkm_engine_chsw_load(struct nvkm_engine *);
 #endif
 
        return false;
 }
 
+int
+nvkm_engine_reset(struct nvkm_engine *engine)
+{
+       if (engine->func->reset)
+               return engine->func->reset(engine);
+
+       nvkm_subdev_fini(&engine->subdev, false);
+       return nvkm_subdev_init(&engine->subdev);
+}
+
 void
 nvkm_engine_unref(struct nvkm_engine **pengine)
 {
 
                }
 
                ENGN_DEBUG(engn, "resetting...");
-               nvkm_subdev_fini(&engn->engine->subdev, false);
-               WARN_ON(nvkm_subdev_init(&engn->engine->subdev));
+               /*TODO: can we do something less of a potential catastrophe on failure? */
+               WARN_ON(nvkm_engine_reset(engn->engine));
        }
 
        /* Submit runlist update, and clear any remaining exception state. */