drm/nouveau/falcon: remove dependence on namedb/engctx lookup

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/ce.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/ce.h
index e832f72..43c18ab 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/engine/ce.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/ce.h
@@ -1,8 +1,8 @@
 #ifndef __NVKM_CE_H__
 #define __NVKM_CE_H__
-#include <core/engine.h>
+#include <engine/falcon.h>
 
-void gt215_ce_intr(struct nvkm_subdev *);
+void gt215_ce_intr(struct nvkm_falcon *, struct nvkm_fifo_chan *);
 
 extern struct nvkm_oclass gt215_ce_oclass;
 extern struct nvkm_oclass gf100_ce0_oclass;
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/falcon.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/falcon.h
index 5e6f1f5..bdadc8b 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/engine/falcon.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/falcon.h
@@ -1,6 +1,7 @@
 #ifndef __NVKM_FALCON_H__
 #define __NVKM_FALCON_H__
 #include <core/engctx.h>
+struct nvkm_fifo_chan;
 
 struct nvkm_falcon_chan {
 	struct nvkm_engctx base;
@@ -30,6 +31,7 @@
 
 struct nvkm_falcon {
 	struct nvkm_engine engine;
+	const struct nvkm_falcon_func *func;
 
 	u32 addr;
 	u8  version;
@@ -51,10 +53,14 @@
 	} data;
 };
 
+struct nvkm_falcon_func {
+	void (*intr)(struct nvkm_falcon *, struct nvkm_fifo_chan *);
+};
+
 #define nv_falcon(priv) ((struct nvkm_falcon *)priv)
 
-#define nvkm_falcon_create(p,e,c,b,d,i,f,r)                                 \
-	nvkm_falcon_create_((p), (e), (c), (b), (d), (i), (f),              \
+#define nvkm_falcon_create(a,p,e,c,b,d,i,f,r)                                 \
+	nvkm_falcon_create_((a), (p), (e), (c), (b), (d), (i), (f),              \
 			       sizeof(**r),(void **)r)
 #define nvkm_falcon_destroy(p)                                              \
 	nvkm_engine_destroy(&(p)->engine)
@@ -67,12 +73,10 @@
 	_nvkm_falcon_fini(nv_object(_falcon), (s));                          \
 })
 
-int nvkm_falcon_create_(struct nvkm_object *, struct nvkm_object *,
-			   struct nvkm_oclass *, u32, bool, const char *,
-			   const char *, int, void **);
-
-void nvkm_falcon_intr(struct nvkm_subdev *subdev);
-
+int nvkm_falcon_create_(const struct nvkm_falcon_func *,
+			struct nvkm_object *, struct nvkm_object *,
+			struct nvkm_oclass *, u32, bool, const char *,
+			const char *, int, void **);
 #define _nvkm_falcon_dtor _nvkm_engine_dtor
 int  _nvkm_falcon_init(struct nvkm_object *);
 int  _nvkm_falcon_fini(struct nvkm_object *, bool);
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/ce/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/ce/gf100.c
index 1989f65..6faf38e 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/ce/gf100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/ce/gf100.c
@@ -88,6 +88,11 @@
 	return 0;
 }
 
+static const struct nvkm_falcon_func
+gf100_ce_func = {
+	.intr = gt215_ce_intr,
+};
+
 static int
 gf100_ce0_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
 	       struct nvkm_oclass *oclass, void *data, u32 size,
@@ -96,14 +101,13 @@
 	struct nvkm_falcon *ce;
 	int ret;
 
-	ret = nvkm_falcon_create(parent, engine, oclass, 0x104000, true,
-				 "PCE0", "ce0", &ce);
+	ret = nvkm_falcon_create(&gf100_ce_func, parent, engine, oclass,
+				 0x104000, true, "PCE0", "ce0", &ce);
 	*pobject = nv_object(ce);
 	if (ret)
 		return ret;
 
 	nv_subdev(ce)->unit = 0x00000040;
-	nv_subdev(ce)->intr = gt215_ce_intr;
 	nv_engine(ce)->cclass = &gf100_ce0_cclass;
 	nv_engine(ce)->sclass = gf100_ce0_sclass;
 	nv_falcon(ce)->code.data = gf100_ce_code;
@@ -121,14 +125,13 @@
 	struct nvkm_falcon *ce;
 	int ret;
 
-	ret = nvkm_falcon_create(parent, engine, oclass, 0x105000, true,
-				 "PCE1", "ce1", &ce);
+	ret = nvkm_falcon_create(&gf100_ce_func, parent, engine, oclass,
+				 0x105000, true, "PCE1", "ce1", &ce);
 	*pobject = nv_object(ce);
 	if (ret)
 		return ret;
 
 	nv_subdev(ce)->unit = 0x00000080;
-	nv_subdev(ce)->intr = gt215_ce_intr;
 	nv_engine(ce)->cclass = &gf100_ce1_cclass;
 	nv_engine(ce)->sclass = gf100_ce1_sclass;
 	nv_falcon(ce)->code.data = gf100_ce_code;
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/ce/gt215.c b/drivers/gpu/drm/nouveau/nvkm/engine/ce/gt215.c
index b52acdc..a632570 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/ce/gt215.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/ce/gt215.c
@@ -22,7 +22,6 @@
  * Authors: Ben Skeggs
  */
 #include <engine/ce.h>
-#include <engine/falcon.h>
 #include <engine/fifo.h>
 #include "fuc/gt215.fuc3.h"
 
@@ -70,47 +69,31 @@
 };
 
 void
-gt215_ce_intr(struct nvkm_subdev *subdev)
+gt215_ce_intr(struct nvkm_falcon *ce, struct nvkm_fifo_chan *chan)
 {
-	struct nvkm_falcon *ce = (void *)subdev;
-	struct nvkm_engine *engine = &ce->engine;
-	struct nvkm_device *device = engine->subdev.device;
-	struct nvkm_fifo *fifo = device->fifo;
-	struct nvkm_object *engctx;
-	const struct nvkm_enum *en;
+	struct nvkm_subdev *subdev = &ce->engine.subdev;
+	struct nvkm_device *device = subdev->device;
 	const u32 base = (nv_subidx(subdev) - NVDEV_ENGINE_CE0) * 0x1000;
-	u32 dispatch = nvkm_rd32(device, 0x10401c + base);
-	u32 stat = nvkm_rd32(device, 0x104008 + base) & dispatch & ~(dispatch >> 16);
-	u64 inst = nvkm_rd32(device, 0x104050 + base) & 0x3fffffff;
 	u32 ssta = nvkm_rd32(device, 0x104040 + base) & 0x0000ffff;
 	u32 addr = nvkm_rd32(device, 0x104040 + base) >> 16;
 	u32 mthd = (addr & 0x07ff) << 2;
 	u32 subc = (addr & 0x3800) >> 11;
 	u32 data = nvkm_rd32(device, 0x104044 + base);
-	int chid;
+	const struct nvkm_enum *en =
+		nvkm_enum_find(gt215_ce_isr_error_name, ssta);
 
-	engctx = nvkm_engctx_get(engine, inst);
-	chid   = fifo->chid(fifo, engctx);
-
-	if (stat & 0x00000040) {
-		en = nvkm_enum_find(gt215_ce_isr_error_name, ssta);
-		nvkm_error(subdev, "DISPATCH_ERROR %04x [%s] "
-				   "ch %d [%010llx %s] subc %d "
-				   "mthd %04x data %08x\n",
-			   ssta, en ? en->name : "", chid, inst << 12,
-			   nvkm_client_name(engctx), subc, mthd, data);
-		nvkm_wr32(device, 0x104004 + base, 0x00000040);
-		stat &= ~0x00000040;
-	}
-
-	if (stat) {
-		nvkm_error(subdev, "intr %08x\n", stat);
-		nvkm_wr32(device, 0x104004 + base, stat);
-	}
-
-	nvkm_engctx_put(engctx);
+	nvkm_error(subdev, "DISPATCH_ERROR %04x [%s] ch %d [%010llx %s] "
+			   "subc %d mthd %04x data %08x\n", ssta,
+		   en ? en->name : "", chan ? chan->chid : -1,
+		   chan ? chan->inst : 0, nvkm_client_name(chan),
+		   subc, mthd, data);
 }
 
+static const struct nvkm_falcon_func
+gt215_ce_func = {
+	.intr = gt215_ce_intr,
+};
+
 static int
 gt215_ce_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
 	      struct nvkm_oclass *oclass, void *data, u32 size,
@@ -120,14 +103,13 @@
 	struct nvkm_falcon *ce;
 	int ret;
 
-	ret = nvkm_falcon_create(parent, engine, oclass, 0x104000, enable,
-				 "PCE0", "ce0", &ce);
+	ret = nvkm_falcon_create(&gt215_ce_func, parent, engine, oclass,
+				 0x104000, enable, "PCE0", "ce0", &ce);
 	*pobject = nv_object(ce);
 	if (ret)
 		return ret;
 
 	nv_subdev(ce)->unit = 0x00802000;
-	nv_subdev(ce)->intr = gt215_ce_intr;
 	nv_engine(ce)->cclass = &gt215_ce_cclass;
 	nv_engine(ce)->sclass = gt215_ce_sclass;
 	nv_falcon(ce)->code.data = gt215_ce_code;
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/falcon.c b/drivers/gpu/drm/nouveau/nvkm/engine/falcon.c
index 27bc50e..b0cbe81 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/falcon.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/falcon.c
@@ -20,17 +20,31 @@
  * OTHER DEALINGS IN THE SOFTWARE.
  */
 #include <engine/falcon.h>
+#include <engine/fifo.h>
 
 #include <subdev/timer.h>
 
-void
+static void
 nvkm_falcon_intr(struct nvkm_subdev *subdev)
 {
 	struct nvkm_falcon *falcon = (void *)subdev;
 	struct nvkm_device *device = falcon->engine.subdev.device;
 	const u32 base = falcon->addr;
-	u32 dispatch = nvkm_rd32(device, base + 0x01c);
-	u32 intr = nvkm_rd32(device, base + 0x008) & dispatch & ~(dispatch >> 16);
+	u32 dest = nvkm_rd32(device, base + 0x01c);
+	u32 intr = nvkm_rd32(device, base + 0x008) & dest & ~(dest >> 16);
+	u32 inst = nvkm_rd32(device, base + 0x050) & 0x3fffffff;
+	struct nvkm_fifo_chan *chan;
+	unsigned long flags;
+
+	chan = nvkm_fifo_chan_inst(device->fifo, (u64)inst << 12, &flags);
+
+	if (intr & 0x00000040) {
+		if (falcon->func->intr) {
+			falcon->func->intr(falcon, chan);
+			nvkm_wr32(device, base + 0x004, 0x00000040);
+			intr &= ~0x00000040;
+		}
+	}
 
 	if (intr & 0x00000010) {
 		nvkm_debug(subdev, "ucode halted\n");
@@ -42,6 +56,8 @@
 		nvkm_error(subdev, "intr %08x\n", intr);
 		nvkm_wr32(device, base + 0x004, intr);
 	}
+
+	nvkm_fifo_chan_put(device->fifo, flags, &chan);
 }
 
 static void *
@@ -260,7 +276,8 @@
 }
 
 int
-nvkm_falcon_create_(struct nvkm_object *parent, struct nvkm_object *engine,
+nvkm_falcon_create_(const struct nvkm_falcon_func *func,
+		    struct nvkm_object *parent, struct nvkm_object *engine,
 		    struct nvkm_oclass *oclass, u32 addr, bool enable,
 		    const char *iname, const char *fname,
 		    int length, void **pobject)
@@ -274,6 +291,8 @@
 	if (ret)
 		return ret;
 
+	falcon->engine.subdev.intr = nvkm_falcon_intr;
+	falcon->func = func;
 	falcon->addr = addr;
 	return 0;
 }
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/mspdec/g98.c b/drivers/gpu/drm/nouveau/nvkm/engine/mspdec/g98.c
index c8a1a12..fbb3845 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/mspdec/g98.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/mspdec/g98.c
@@ -72,6 +72,10 @@
 	return 0;
 }
 
+static const struct nvkm_falcon_func
+g98_mspdec_func = {
+};
+
 static int
 g98_mspdec_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
 		struct nvkm_oclass *oclass, void *data, u32 size,
@@ -80,8 +84,8 @@
 	struct nvkm_falcon *mspdec;
 	int ret;
 
-	ret = nvkm_falcon_create(parent, engine, oclass, 0x085000, true,
-				 "PMSPDEC", "mspdec", &mspdec);
+	ret = nvkm_falcon_create(&g98_mspdec_func, parent, engine, oclass,
+				  0x085000, true, "PMSPDEC", "mspdec", &mspdec);
 	*pobject = nv_object(mspdec);
 	if (ret)
 		return ret;
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/mspdec/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/mspdec/gf100.c
index 4b759f3..71b75e91 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/mspdec/gf100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/mspdec/gf100.c
@@ -71,6 +71,10 @@
 	return 0;
 }
 
+static const struct nvkm_falcon_func
+gf100_mspdec_func = {
+};
+
 static int
 gf100_mspdec_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
 		  struct nvkm_oclass *oclass, void *data, u32 size,
@@ -79,14 +83,13 @@
 	struct nvkm_falcon *mspdec;
 	int ret;
 
-	ret = nvkm_falcon_create(parent, engine, oclass, 0x085000, true,
-				 "PMSPDEC", "mspdec", &mspdec);
+	ret = nvkm_falcon_create(&gf100_mspdec_func, parent, engine, oclass,
+				 0x085000, true, "PMSPDEC", "mspdec", &mspdec);
 	*pobject = nv_object(mspdec);
 	if (ret)
 		return ret;
 
 	nv_subdev(mspdec)->unit = 0x00020000;
-	nv_subdev(mspdec)->intr = nvkm_falcon_intr;
 	nv_engine(mspdec)->cclass = &gf100_mspdec_cclass;
 	nv_engine(mspdec)->sclass = gf100_mspdec_sclass;
 	return 0;
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/mspdec/gk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/mspdec/gk104.c
index ab29236..a103789 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/mspdec/gk104.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/mspdec/gk104.c
@@ -71,6 +71,10 @@
 	return 0;
 }
 
+static const struct nvkm_falcon_func
+gk104_mspdec_func = {
+};
+
 static int
 gk104_mspdec_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
 		  struct nvkm_oclass *oclass, void *data, u32 size,
@@ -79,14 +83,13 @@
 	struct nvkm_falcon *falcon;
 	int ret;
 
-	ret = nvkm_falcon_create(parent, engine, oclass, 0x085000, true,
-				 "PMSPDEC", "mspdec", &falcon);
+	ret = nvkm_falcon_create(&gk104_mspdec_func, parent, engine, oclass,
+				 0x085000, true, "PMSPDEC", "mspdec", &falcon);
 	*pobject = nv_object(falcon);
 	if (ret)
 		return ret;
 
 	nv_subdev(falcon)->unit = 0x00020000;
-	nv_subdev(falcon)->intr = nvkm_falcon_intr;
 	nv_engine(falcon)->cclass = &gk104_mspdec_cclass;
 	nv_engine(falcon)->sclass = gk104_mspdec_sclass;
 	return 0;
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/msppp/g98.c b/drivers/gpu/drm/nouveau/nvkm/engine/msppp/g98.c
index 80b12ab..9029ff0 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/msppp/g98.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/msppp/g98.c
@@ -72,6 +72,10 @@
 	return 0;
 }
 
+static const struct nvkm_falcon_func
+g98_msppp_func = {
+};
+
 static int
 g98_msppp_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
 	       struct nvkm_oclass *oclass, void *data, u32 size,
@@ -80,8 +84,8 @@
 	struct nvkm_falcon *msppp;
 	int ret;
 
-	ret = nvkm_falcon_create(parent, engine, oclass, 0x086000, true,
-				 "PMSPPP", "msppp", &msppp);
+	ret = nvkm_falcon_create(&g98_msppp_func, parent, engine, oclass,
+				 0x086000, true, "PMSPPP", "msppp", &msppp);
 	*pobject = nv_object(msppp);
 	if (ret)
 		return ret;
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/msppp/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/msppp/gf100.c
index 5f5018b..2b21fe5 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/msppp/gf100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/msppp/gf100.c
@@ -71,6 +71,10 @@
 	return 0;
 }
 
+static const struct nvkm_falcon_func
+gf100_msppp_func = {
+};
+
 static int
 gf100_msppp_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
 		 struct nvkm_oclass *oclass, void *data, u32 size,
@@ -79,14 +83,13 @@
 	struct nvkm_falcon *msppp;
 	int ret;
 
-	ret = nvkm_falcon_create(parent, engine, oclass, 0x086000, true,
-				 "PMSPPP", "msppp", &msppp);
+	ret = nvkm_falcon_create(&gf100_msppp_func, parent, engine, oclass,
+				 0x086000, true, "PMSPPP", "msppp", &msppp);
 	*pobject = nv_object(msppp);
 	if (ret)
 		return ret;
 
 	nv_subdev(msppp)->unit = 0x00000002;
-	nv_subdev(msppp)->intr = nvkm_falcon_intr;
 	nv_engine(msppp)->cclass = &gf100_msppp_cclass;
 	nv_engine(msppp)->sclass = gf100_msppp_sclass;
 	return 0;
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/msvld/g98.c b/drivers/gpu/drm/nouveau/nvkm/engine/msvld/g98.c
index 5312cd6..cdb7de5 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/msvld/g98.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/msvld/g98.c
@@ -73,6 +73,10 @@
 	return 0;
 }
 
+static const struct nvkm_falcon_func
+g98_msvld_func = {
+};
+
 static int
 g98_msvld_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
 	       struct nvkm_oclass *oclass, void *data, u32 size,
@@ -81,8 +85,8 @@
 	struct nvkm_falcon *msvld;
 	int ret;
 
-	ret = nvkm_falcon_create(parent, engine, oclass, 0x084000, true,
-				 "PMSVLD", "msvld", &msvld);
+	ret = nvkm_falcon_create(&g98_msvld_func, parent, engine, oclass,
+				 0x084000, true, "PMSVLD", "msvld", &msvld);
 	*pobject = nv_object(msvld);
 	if (ret)
 		return ret;
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/msvld/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/msvld/gf100.c
index e5de6db..1124373 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/msvld/gf100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/msvld/gf100.c
@@ -71,6 +71,10 @@
 	return 0;
 }
 
+static const struct nvkm_falcon_func
+gf100_msvld_func = {
+};
+
 static int
 gf100_msvld_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
 		 struct nvkm_oclass *oclass, void *data, u32 size,
@@ -79,14 +83,13 @@
 	struct nvkm_falcon *msvld;
 	int ret;
 
-	ret = nvkm_falcon_create(parent, engine, oclass, 0x084000, true,
-				 "PMSVLD", "msvld", &msvld);
+	ret = nvkm_falcon_create(&gf100_msvld_func, parent, engine, oclass,
+				 0x084000, true, "PMSVLD", "msvld", &msvld);
 	*pobject = nv_object(msvld);
 	if (ret)
 		return ret;
 
 	nv_subdev(msvld)->unit = 0x00008000;
-	nv_subdev(msvld)->intr = nvkm_falcon_intr;
 	nv_engine(msvld)->cclass = &gf100_msvld_cclass;
 	nv_engine(msvld)->sclass = gf100_msvld_sclass;
 	return 0;
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/msvld/gk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/msvld/gk104.c
index 0858765..addef2b 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/msvld/gk104.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/msvld/gk104.c
@@ -71,6 +71,10 @@
 	return 0;
 }
 
+static const struct nvkm_falcon_func
+gk104_msvld_func = {
+};
+
 static int
 gk104_msvld_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
 		 struct nvkm_oclass *oclass, void *data, u32 size,
@@ -79,14 +83,13 @@
 	struct nvkm_falcon *msvld;
 	int ret;
 
-	ret = nvkm_falcon_create(parent, engine, oclass, 0x084000, true,
-				 "PMSVLD", "msvld", &msvld);
+	ret = nvkm_falcon_create(&gk104_msvld_func, parent, engine, oclass,
+				 0x084000, true, "PMSVLD", "msvld", &msvld);
 	*pobject = nv_object(msvld);
 	if (ret)
 		return ret;
 
 	nv_subdev(msvld)->unit = 0x00008000;
-	nv_subdev(msvld)->intr = nvkm_falcon_intr;
 	nv_engine(msvld)->cclass = &gk104_msvld_cclass;
 	nv_engine(msvld)->sclass = gk104_msvld_sclass;
 	return 0;
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/sec/g98.c b/drivers/gpu/drm/nouveau/nvkm/engine/sec/g98.c
index 431bd5a..e654409 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/sec/g98.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/sec/g98.c
@@ -23,11 +23,11 @@
  */
 #include <engine/sec.h>
 #include <engine/falcon.h>
+#include <engine/fifo.h>
 #include "fuc/g98.fuc0s.h"
 
 #include <core/client.h>
 #include <core/enum.h>
-#include <engine/fifo.h>
 
 /*******************************************************************************
  * Crypt object classes
@@ -69,46 +69,30 @@
 };
 
 static void
-g98_sec_intr(struct nvkm_subdev *subdev)
+g98_sec_intr(struct nvkm_falcon *sec, struct nvkm_fifo_chan *chan)
 {
-	struct nvkm_falcon *sec = (void *)subdev;
-	struct nvkm_device *device = sec->engine.subdev.device;
-	struct nvkm_fifo *fifo = device->fifo;
-	struct nvkm_engine *engine = nv_engine(subdev);
-	struct nvkm_object *engctx;
-	u32 disp = nvkm_rd32(device, 0x08701c);
-	u32 stat = nvkm_rd32(device, 0x087008) & disp & ~(disp >> 16);
-	u32 inst = nvkm_rd32(device, 0x087050) & 0x3fffffff;
+	struct nvkm_subdev *subdev = &sec->engine.subdev;
+	struct nvkm_device *device = subdev->device;
 	u32 ssta = nvkm_rd32(device, 0x087040) & 0x0000ffff;
 	u32 addr = nvkm_rd32(device, 0x087040) >> 16;
 	u32 mthd = (addr & 0x07ff) << 2;
 	u32 subc = (addr & 0x3800) >> 11;
 	u32 data = nvkm_rd32(device, 0x087044);
-	const struct nvkm_enum *en;
-	int chid;
+	const struct nvkm_enum *en =
+		nvkm_enum_find(g98_sec_isr_error_name, ssta);
 
-	engctx = nvkm_engctx_get(engine, inst);
-	chid   = fifo->chid(fifo, engctx);
-
-	if (stat & 0x00000040) {
-		en = nvkm_enum_find(g98_sec_isr_error_name, ssta);
-		nvkm_error(subdev, "DISPATCH_ERROR %04x [%s] "
-				   "ch %d [%010llx %s] subc %d "
-				   "mthd %04x data %08x\n", ssta,
-			   en ? en->name : "", chid, (u64)inst << 12,
-			   nvkm_client_name(engctx), subc, mthd, data);
-		nvkm_wr32(device, 0x087004, 0x00000040);
-		stat &= ~0x00000040;
-	}
-
-	if (stat) {
-		nvkm_error(subdev, "intr %08x\n", stat);
-		nvkm_wr32(device, 0x087004, stat);
-	}
-
-	nvkm_engctx_put(engctx);
+	nvkm_error(subdev, "DISPATCH_ERROR %04x [%s] ch %d [%010llx %s] "
+			   "subc %d mthd %04x data %08x\n", ssta,
+		   en ? en->name : "UNKNOWN", chan ? chan->chid : -1,
+		   chan ? chan->inst : 0, nvkm_client_name(chan),
+		   subc, mthd, data);
 }
 
+static const struct nvkm_falcon_func
+g98_sec_func = {
+	.intr = g98_sec_intr,
+};
+
 static int
 g98_sec_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
 	     struct nvkm_oclass *oclass, void *data, u32 size,
@@ -117,14 +101,13 @@
 	struct nvkm_falcon *sec;
 	int ret;
 
-	ret = nvkm_falcon_create(parent, engine, oclass, 0x087000, true,
-				 "PSEC", "sec", &sec);
+	ret = nvkm_falcon_create(&g98_sec_func, parent, engine, oclass,
+				 0x087000, true, "PSEC", "sec", &sec);
 	*pobject = nv_object(sec);
 	if (ret)
 		return ret;
 
 	nv_subdev(sec)->unit = 0x00004000;
-	nv_subdev(sec)->intr = g98_sec_intr;
 	nv_engine(sec)->cclass = &g98_sec_cclass;
 	nv_engine(sec)->sclass = g98_sec_sclass;
 	nv_falcon(sec)->code.data = g98_sec_code;