From: Ben Skeggs <bskeggs@redhat.com>
Date: Thu, 20 Aug 2015 04:54:16 +0000 (+1000)
Subject: drm/nouveau/object: implement support for new-style nvkm_object
X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=cbea21e2ab658ca1256bfe5f4c535b2b1b9e4060;p=GitHub%2FLineageOS%2Fandroid_kernel_motorola_exynos9610.git

drm/nouveau/object: implement support for new-style nvkm_object

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
---

diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/gpuobj.h b/drivers/gpu/drm/nouveau/include/nvkm/core/gpuobj.h
index 46975785ba3c..2260aef3ec3e 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/core/gpuobj.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/core/gpuobj.h
@@ -68,8 +68,12 @@ void _nvkm_gpuobj_wr32(struct nvkm_object *, u64, u32);
 	struct nvkm_gpuobj *_gpuobj = (o);                                     \
 	(void)_gpuobj;                                                         \
 } while(0)
-#define nvkm_ro32(o,a)   nv_ofuncs(o)->rd32(&(o)->object, (a))
-#define nvkm_wo32(o,a,d) nv_ofuncs(o)->wr32(&(o)->object, (a), (d))
+#define nvkm_ro32(o,a) ({                                                      \
+	u32 _data;                                                             \
+	nvkm_object_rd32(&(o)->object, (a), &_data);                           \
+	_data;                                                                 \
+})
+#define nvkm_wo32(o,a,d) nvkm_object_wr32(&(o)->object, (a), (d))
 #define nvkm_mo32(o,a,m,d) ({                                                  \
 	u32 _addr = (a), _data = nvkm_ro32((o), _addr);                        \
 	nvkm_wo32((o), _addr, (_data & ~(m)) | (d));                           \
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/object.h b/drivers/gpu/drm/nouveau/include/nvkm/core/object.h
index 39a4962d3982..84040a336036 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/core/object.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/core/object.h
@@ -2,6 +2,8 @@
 #define __NVKM_OBJECT_H__
 #include <core/os.h>
 #include <core/debug.h>
+struct nvkm_event;
+struct nvkm_gpuobj;
 
 #define NV_PARENT_CLASS 0x80000000
 #define NV_NAMEDB_CLASS 0x40000000
@@ -13,10 +15,14 @@
 #define NV_ENGCTX_CLASS 0x01000000
 
 struct nvkm_object {
+	const struct nvkm_object_func *func;
+	struct nvkm_client *client;
+	struct nvkm_engine *engine;
+	u32 oclass_name;
+	u32 handle;
+	struct nvkm_object *parent;
 	struct nvkm_oclass *oclass;
 	u32 pclass;
-	struct nvkm_object *parent;
-	struct nvkm_engine *engine;
 	atomic_t refcount;
 	atomic_t usecount;
 #if CONFIG_NOUVEAU_DEBUG >= NV_DBG_PARANOIA
@@ -26,12 +32,44 @@ struct nvkm_object {
 #endif
 };
 
+struct nvkm_object_func {
+	void *(*dtor)(struct nvkm_object *);
+	int (*init)(struct nvkm_object *);
+	int (*fini)(struct nvkm_object *, bool suspend);
+	int (*mthd)(struct nvkm_object *, u32 mthd, void *data, u32 size);
+	int (*ntfy)(struct nvkm_object *, u32 mthd, struct nvkm_event **);
+	int (*map)(struct nvkm_object *, u64 *addr, u32 *size);
+	int (*rd08)(struct nvkm_object *, u64 addr, u8 *data);
+	int (*rd16)(struct nvkm_object *, u64 addr, u16 *data);
+	int (*rd32)(struct nvkm_object *, u64 addr, u32 *data);
+	int (*wr08)(struct nvkm_object *, u64 addr, u8 data);
+	int (*wr16)(struct nvkm_object *, u64 addr, u16 data);
+	int (*wr32)(struct nvkm_object *, u64 addr, u32 data);
+	int (*bind)(struct nvkm_object *, struct nvkm_gpuobj *, int align,
+		    struct nvkm_gpuobj **);
+	int (*sclass)(struct nvkm_object *, int index, struct nvkm_oclass *);
+};
+
+void nvkm_object_ctor(const struct nvkm_object_func *,
+		      const struct nvkm_oclass *, struct nvkm_object *);
+int nvkm_object_new_(const struct nvkm_object_func *,
+		     const struct nvkm_oclass *, void *data, u32 size,
+		     struct nvkm_object **);
+int nvkm_object_new(const struct nvkm_oclass *, void *data, u32 size,
+		    struct nvkm_object **);
+int nvkm_object_init(struct nvkm_object *);
+int nvkm_object_fini(struct nvkm_object *, bool suspend);
+int nvkm_object_mthd(struct nvkm_object *, u32 mthd, void *data, u32 size);
+int nvkm_object_ntfy(struct nvkm_object *, u32 mthd, struct nvkm_event **);
+int nvkm_object_map(struct nvkm_object *, u64 *addr, u32 *size);
 int nvkm_object_rd08(struct nvkm_object *, u64 addr, u8  *data);
 int nvkm_object_rd16(struct nvkm_object *, u64 addr, u16 *data);
 int nvkm_object_rd32(struct nvkm_object *, u64 addr, u32 *data);
 int nvkm_object_wr08(struct nvkm_object *, u64 addr, u8   data);
 int nvkm_object_wr16(struct nvkm_object *, u64 addr, u16  data);
 int nvkm_object_wr32(struct nvkm_object *, u64 addr, u32  data);
+int nvkm_object_bind(struct nvkm_object *, struct nvkm_gpuobj *, int align,
+		     struct nvkm_gpuobj **);
 
 static inline struct nvkm_object *
 nv_object(void *obj)
@@ -59,6 +97,15 @@ int _nvkm_object_ctor(struct nvkm_object *, struct nvkm_object *,
 
 extern struct nvkm_ofuncs nvkm_object_ofuncs;
 
+struct nvkm_sclass {
+	int minver;
+	int maxver;
+	s32 oclass;
+	const struct nvkm_object_func *func;
+	int (*ctor)(const struct nvkm_oclass *, void *data, u32 size,
+		    struct nvkm_object **);
+};
+
 /* Don't allocate dynamically, because lockdep needs lock_class_keys to be in
  * ".data". */
 struct nvkm_oclass {
@@ -66,6 +113,16 @@ struct nvkm_oclass {
 	struct nvkm_ofuncs * const ofuncs;
 	struct nvkm_omthds * const omthds;
 	struct lock_class_key lock_class_key;
+
+	int (*ctor)(const struct nvkm_oclass *, void *data, u32 size,
+		    struct nvkm_object **);
+	struct nvkm_sclass base;
+	const void *priv;
+	const void *engn;
+	u64 object;
+	struct nvkm_client *client;
+	struct nvkm_object *parent;
+	struct nvkm_engine *engine;
 };
 
 #define nv_oclass(o)    nv_object(o)->oclass
@@ -87,7 +144,6 @@ struct nvkm_omthds {
 	int (*call)(struct nvkm_object *, u32, void *, u32);
 };
 
-struct nvkm_event;
 struct nvkm_ofuncs {
 	int  (*ctor)(struct nvkm_object *, struct nvkm_object *,
 		     struct nvkm_oclass *, void *data, u32 size,
diff --git a/drivers/gpu/drm/nouveau/nvkm/core/gpuobj.c b/drivers/gpu/drm/nouveau/nvkm/core/gpuobj.c
index 1ca5479ee38b..bc4b3c2d075e 100644
--- a/drivers/gpu/drm/nouveau/nvkm/core/gpuobj.c
+++ b/drivers/gpu/drm/nouveau/nvkm/core/gpuobj.c
@@ -182,20 +182,20 @@ u32
 _nvkm_gpuobj_rd32(struct nvkm_object *object, u64 addr)
 {
 	struct nvkm_gpuobj *gpuobj = nv_gpuobj(object);
-	struct nvkm_ofuncs *pfuncs = nv_ofuncs(gpuobj->parent);
+	u32 data;
 	if (gpuobj->node)
 		addr += gpuobj->node->offset;
-	return pfuncs->rd32(gpuobj->parent, addr);
+	nvkm_object_rd32(gpuobj->parent, addr, &data);
+	return data;
 }
 
 void
 _nvkm_gpuobj_wr32(struct nvkm_object *object, u64 addr, u32 data)
 {
 	struct nvkm_gpuobj *gpuobj = nv_gpuobj(object);
-	struct nvkm_ofuncs *pfuncs = nv_ofuncs(gpuobj->parent);
 	if (gpuobj->node)
 		addr += gpuobj->node->offset;
-	pfuncs->wr32(gpuobj->parent, addr, data);
+	nvkm_object_wr32(gpuobj->parent, addr, data);
 }
 
 static struct nvkm_oclass
diff --git a/drivers/gpu/drm/nouveau/nvkm/core/ioctl.c b/drivers/gpu/drm/nouveau/nvkm/core/ioctl.c
index 7a15b15bfce0..6e5ff942a6da 100644
--- a/drivers/gpu/drm/nouveau/nvkm/core/ioctl.c
+++ b/drivers/gpu/drm/nouveau/nvkm/core/ioctl.c
@@ -152,6 +152,8 @@ nvkm_ioctl_new(struct nvkm_handle *handle, void *data, u32 size)
 	if (ret)
 		goto fail_ctor;
 
+	object->handle = _handle;
+
 	ret = nvkm_object_inc(object);
 	if (ret)
 		goto fail_init;
@@ -205,7 +207,6 @@ static int
 nvkm_ioctl_mthd(struct nvkm_handle *handle, void *data, u32 size)
 {
 	struct nvkm_object *object = handle->object;
-	struct nvkm_ofuncs *ofuncs = object->oclass->ofuncs;
 	union {
 		struct nvif_ioctl_mthd_v0 v0;
 	} *args = data;
@@ -215,8 +216,7 @@ nvkm_ioctl_mthd(struct nvkm_handle *handle, void *data, u32 size)
 	if (nvif_unpack(args->v0, 0, 0, true)) {
 		nvif_ioctl(object, "mthd vers %d mthd %02x\n",
 			   args->v0.version, args->v0.method);
-		if (ret = -ENODEV, ofuncs->mthd)
-			ret = ofuncs->mthd(object, args->v0.method, data, size);
+		ret = nvkm_object_mthd(object, args->v0.method, data, size);
 	}
 
 	return ret;
@@ -296,7 +296,6 @@ static int
 nvkm_ioctl_map(struct nvkm_handle *handle, void *data, u32 size)
 {
 	struct nvkm_object *object = handle->object;
-	struct nvkm_ofuncs *ofuncs = object->oclass->ofuncs;
 	union {
 		struct nvif_ioctl_map_v0 v0;
 	} *args = data;
@@ -305,10 +304,8 @@ nvkm_ioctl_map(struct nvkm_handle *handle, void *data, u32 size)
 	nvif_ioctl(object, "map size %d\n", size);
 	if (nvif_unpack(args->v0, 0, 0, false)) {
 		nvif_ioctl(object, "map vers %d\n", args->v0.version);
-		if (ret = -ENODEV, ofuncs->map) {
-			ret = ofuncs->map(object, &args->v0.handle,
-						  &args->v0.length);
-		}
+		ret = nvkm_object_map(object, &args->v0.handle,
+					      &args->v0.length);
 	}
 
 	return ret;
@@ -335,7 +332,6 @@ static int
 nvkm_ioctl_ntfy_new(struct nvkm_handle *handle, void *data, u32 size)
 {
 	struct nvkm_object *object = handle->object;
-	struct nvkm_ofuncs *ofuncs = object->oclass->ofuncs;
 	union {
 		struct nvif_ioctl_ntfy_new_v0 v0;
 	} *args = data;
@@ -346,8 +342,7 @@ nvkm_ioctl_ntfy_new(struct nvkm_handle *handle, void *data, u32 size)
 	if (nvif_unpack(args->v0, 0, 0, true)) {
 		nvif_ioctl(object, "ntfy new vers %d event %02x\n",
 			   args->v0.version, args->v0.event);
-		if (ret = -ENODEV, ofuncs->ntfy)
-			ret = ofuncs->ntfy(object, args->v0.event, &event);
+		ret = nvkm_object_ntfy(object, args->v0.event, &event);
 		if (ret == 0) {
 			ret = nvkm_client_notify_new(object, event, data, size);
 			if (ret >= 0) {
diff --git a/drivers/gpu/drm/nouveau/nvkm/core/object.c b/drivers/gpu/drm/nouveau/nvkm/core/object.c
index 1c117f0a7245..0abee7816874 100644
--- a/drivers/gpu/drm/nouveau/nvkm/core/object.c
+++ b/drivers/gpu/drm/nouveau/nvkm/core/object.c
@@ -24,75 +24,232 @@
 #include <core/object.h>
 #include <core/engine.h>
 
+int
+nvkm_object_mthd(struct nvkm_object *object, u32 mthd, void *data, u32 size)
+{
+	if (object->oclass) {
+		if (object->oclass->ofuncs->mthd)
+			return object->oclass->ofuncs->mthd(object, mthd, data, size);
+		return -ENODEV;
+	}
+	if (likely(object->func->mthd))
+		return object->func->mthd(object, mthd, data, size);
+	return -ENODEV;
+}
+
+int
+nvkm_object_ntfy(struct nvkm_object *object, u32 mthd,
+		 struct nvkm_event **pevent)
+{
+	if (object->oclass) {
+		if (object->oclass->ofuncs->ntfy)
+			return object->oclass->ofuncs->ntfy(object, mthd, pevent);
+		return -ENODEV;
+	}
+	if (likely(object->func->ntfy))
+		return object->func->ntfy(object, mthd, pevent);
+	return -ENODEV;
+}
+
+int
+nvkm_object_map(struct nvkm_object *object, u64 *addr, u32 *size)
+{
+	if (object->oclass) {
+		if (object->oclass->ofuncs->map)
+			return object->oclass->ofuncs->map(object, addr, size);
+		return -ENODEV;
+	}
+	if (likely(object->func->map))
+		return object->func->map(object, addr, size);
+	return -ENODEV;
+}
+
 int
 nvkm_object_rd08(struct nvkm_object *object, u64 addr, u8 *data)
 {
-	const struct nvkm_oclass *oclass = object->oclass;
-	if (oclass->ofuncs && oclass->ofuncs->rd08) {
-		*data = oclass->ofuncs->rd08(object, addr);
-		return 0;
+	if (object->oclass) {
+		if (object->oclass->ofuncs->rd08) {
+			*data = object->oclass->ofuncs->rd08(object, addr);
+			return 0;
+		}
+		*data = 0x00;
+		return -ENODEV;
 	}
-	*data = 0x00;
+	if (likely(object->func->rd08))
+		return object->func->rd08(object, addr, data);
 	return -ENODEV;
 }
 
 int
 nvkm_object_rd16(struct nvkm_object *object, u64 addr, u16 *data)
 {
-	const struct nvkm_oclass *oclass = object->oclass;
-	if (oclass->ofuncs && oclass->ofuncs->rd16) {
-		*data = oclass->ofuncs->rd16(object, addr);
-		return 0;
+	if (object->oclass) {
+		if (object->oclass->ofuncs->rd16) {
+			*data = object->oclass->ofuncs->rd16(object, addr);
+			return 0;
+		}
+		*data = 0x0000;
+		return -ENODEV;
 	}
-	*data = 0x0000;
+	if (likely(object->func->rd16))
+		return object->func->rd16(object, addr, data);
 	return -ENODEV;
 }
 
 int
 nvkm_object_rd32(struct nvkm_object *object, u64 addr, u32 *data)
 {
-	const struct nvkm_oclass *oclass = object->oclass;
-	if (oclass->ofuncs && oclass->ofuncs->rd32) {
-		*data = oclass->ofuncs->rd32(object, addr);
-		return 0;
+	if (object->oclass) {
+		if (object->oclass->ofuncs->rd32) {
+			*data = object->oclass->ofuncs->rd32(object, addr);
+			return 0;
+		}
+		*data = 0x00000000;
+		return -ENODEV;
 	}
-	*data = 0x0000;
+	if (likely(object->func->rd32))
+		return object->func->rd32(object, addr, data);
 	return -ENODEV;
 }
 
 int
 nvkm_object_wr08(struct nvkm_object *object, u64 addr, u8 data)
 {
-	const struct nvkm_oclass *oclass = object->oclass;
-	if (oclass->ofuncs && oclass->ofuncs->wr08) {
-		oclass->ofuncs->wr08(object, addr, data);
-		return 0;
+	if (object->oclass) {
+		if (object->oclass->ofuncs->wr08) {
+			object->oclass->ofuncs->wr08(object, addr, data);
+			return 0;
+		}
+		return -ENODEV;
 	}
+	if (likely(object->func->wr08))
+		return object->func->wr08(object, addr, data);
 	return -ENODEV;
 }
 
 int
 nvkm_object_wr16(struct nvkm_object *object, u64 addr, u16 data)
 {
-	const struct nvkm_oclass *oclass = object->oclass;
-	if (oclass->ofuncs && oclass->ofuncs->wr16) {
-		oclass->ofuncs->wr16(object, addr, data);
-		return 0;
+	if (object->oclass) {
+		if (object->oclass->ofuncs->wr16) {
+			object->oclass->ofuncs->wr16(object, addr, data);
+			return 0;
+		}
+		return -ENODEV;
 	}
+	if (likely(object->func->wr16))
+		return object->func->wr16(object, addr, data);
 	return -ENODEV;
 }
 
 int
 nvkm_object_wr32(struct nvkm_object *object, u64 addr, u32 data)
 {
-	const struct nvkm_oclass *oclass = object->oclass;
-	if (oclass->ofuncs && oclass->ofuncs->wr32) {
-		oclass->ofuncs->wr32(object, addr, data);
-		return 0;
+	if (object->oclass) {
+		if (object->oclass->ofuncs->wr32) {
+			object->oclass->ofuncs->wr32(object, addr, data);
+			return 0;
+		}
+		return -ENODEV;
 	}
+	if (likely(object->func->wr32))
+		return object->func->wr32(object, addr, data);
 	return -ENODEV;
 }
 
+int
+nvkm_object_bind(struct nvkm_object *object, struct nvkm_gpuobj *gpuobj,
+		 int align, struct nvkm_gpuobj **pgpuobj)
+{
+	if (object->oclass)
+		return -ENODEV;
+	if (object->func->bind)
+		return object->func->bind(object, gpuobj, align, pgpuobj);
+	return -ENODEV;
+}
+
+int
+nvkm_object_fini(struct nvkm_object *object, bool suspend)
+{
+	if (object->oclass)
+		return object->oclass->ofuncs->fini(object, suspend);
+	if (object->func->fini)
+		return object->func->fini(object, suspend);
+	return 0;
+}
+
+int
+nvkm_object_init(struct nvkm_object *object)
+{
+	if (object->oclass)
+		return object->oclass->ofuncs->init(object);
+	if (object->func->init)
+		return object->func->init(object);
+	return 0;
+}
+
+static void
+nvkm_object_del(struct nvkm_object **pobject)
+{
+	struct nvkm_object *object = *pobject;
+
+	if (object && object->oclass) {
+		object->oclass->ofuncs->dtor(object);
+		return;
+	}
+
+	if (object && !WARN_ON(!object->func)) {
+		if (object->func->dtor)
+			*pobject = object->func->dtor(object);
+		kfree(*pobject);
+		*pobject = NULL;
+	}
+}
+
+void
+nvkm_object_ctor(const struct nvkm_object_func *func,
+		 const struct nvkm_oclass *oclass, struct nvkm_object *object)
+{
+	object->func = func;
+	object->client = oclass->client;
+	object->engine = oclass->engine;
+	object->oclass_name = oclass->base.oclass;
+	object->handle = oclass->handle;
+	object->parent = oclass->parent;
+	atomic_set(&object->refcount, 1);
+	atomic_set(&object->usecount, 0);
+#ifdef NVKM_OBJECT_MAGIC
+	object->_magic = NVKM_OBJECT_MAGIC;
+#endif
+}
+
+int
+nvkm_object_new_(const struct nvkm_object_func *func,
+		 const struct nvkm_oclass *oclass, void *data, u32 size,
+		 struct nvkm_object **pobject)
+{
+	if (size == 0) {
+		if (!(*pobject = kzalloc(sizeof(**pobject), GFP_KERNEL)))
+			return -ENOMEM;
+		nvkm_object_ctor(func, oclass, *pobject);
+		return 0;
+	}
+	return -ENOSYS;
+}
+
+static const struct nvkm_object_func
+nvkm_object_func = {
+};
+
+int
+nvkm_object_new(const struct nvkm_oclass *oclass, void *data, u32 size,
+		struct nvkm_object **pobject)
+{
+	const struct nvkm_object_func *func =
+		oclass->base.func ? oclass->base.func : &nvkm_object_func;
+	return nvkm_object_new_(func, oclass, data, size, pobject);
+}
+
 int
 nvkm_object_create_(struct nvkm_object *parent, struct nvkm_object *engine,
 		    struct nvkm_oclass *oclass, u32 pclass,
@@ -182,12 +339,6 @@ nvkm_object_old(struct nvkm_object *parent, struct nvkm_object *engine,
 	return 0;
 }
 
-static void
-nvkm_object_dtor(struct nvkm_object *object)
-{
-	nv_ofuncs(object)->dtor(object);
-}
-
 void
 nvkm_object_ref(struct nvkm_object *obj, struct nvkm_object **ref)
 {
@@ -198,7 +349,7 @@ nvkm_object_ref(struct nvkm_object *obj, struct nvkm_object **ref)
 	if (*ref) {
 		int dead = atomic_dec_and_test(&(*ref)->refcount);
 		if (dead)
-			nvkm_object_dtor(*ref);
+			nvkm_object_del(ref);
 	}
 
 	*ref = obj;
@@ -227,7 +378,7 @@ nvkm_object_inc(struct nvkm_object *object)
 			goto fail_engine;
 	}
 
-	ret = nv_ofuncs(object)->init(object);
+	ret = nvkm_object_init(object);
 	atomic_set(&object->usecount, 1);
 	if (ret)
 		goto fail_self;
@@ -251,7 +402,7 @@ fail_parent:
 static int
 nvkm_object_decf(struct nvkm_object *object)
 {
-	nv_ofuncs(object)->fini(object, false);
+	nvkm_object_fini(object, false);
 	atomic_set(&object->usecount, 0);
 
 	if (object->engine) {
@@ -271,7 +422,7 @@ nvkm_object_decs(struct nvkm_object *object)
 {
 	int ret;
 
-	ret = nv_ofuncs(object)->fini(object, true);
+	ret = nvkm_object_fini(object, true);
 	atomic_set(&object->usecount, 0);
 	if (ret)
 		return ret;
@@ -300,7 +451,7 @@ fail_parent:
 	}
 
 fail_engine:
-	nv_ofuncs(object)->init(object);
+	nvkm_object_init(object);
 
 	return ret;
 }
diff --git a/drivers/gpu/drm/nouveau/nvkm/core/ramht.c b/drivers/gpu/drm/nouveau/nvkm/core/ramht.c
index c61bb0fa93f6..4717af0800e9 100644
--- a/drivers/gpu/drm/nouveau/nvkm/core/ramht.c
+++ b/drivers/gpu/drm/nouveau/nvkm/core/ramht.c
@@ -102,7 +102,7 @@ nvkm_ramht_new(struct nvkm_object *parent, struct nvkm_object *pargpu,
 	int ret;
 
 	ret = nvkm_gpuobj_create(parent, parent->engine ?
-				 &parent->engine->subdev.object : parent, /* <nv50 ramht */
+				 &parent->engine->subdev.object : NULL, /* <nv50 ramht */
 				 &nvkm_ramht_oclass, 0, pargpu, size,
 				 align, NVOBJ_FLAG_ZERO_ALLOC, &ramht);
 	*pramht = ramht;
diff --git a/drivers/gpu/drm/nouveau/nvkm/core/subdev.c b/drivers/gpu/drm/nouveau/nvkm/core/subdev.c
index 3f6795f51218..9e9e0cadaefc 100644
--- a/drivers/gpu/drm/nouveau/nvkm/core/subdev.c
+++ b/drivers/gpu/drm/nouveau/nvkm/core/subdev.c
@@ -41,7 +41,7 @@ nvkm_subdev_reset(struct nvkm_object *obj)
 {
 	struct nvkm_subdev *subdev = container_of(obj, typeof(*subdev), object);
 	nvkm_trace(subdev, "resetting...\n");
-	nv_ofuncs(subdev)->fini(&subdev->object, false);
+	nvkm_object_fini(&subdev->object, false);
 	nvkm_trace(subdev, "reset\n");
 }
 
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c
index 1fa38227059f..dd7fe30edf46 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c
@@ -451,8 +451,8 @@ gf100_fifo_recover_work(struct work_struct *work)
 
 	for (todo = mask; engn = __ffs64(todo), todo; todo &= ~(1 << engn)) {
 		if ((engine = (void *)nvkm_engine(fifo, engn))) {
-			nv_ofuncs(engine)->fini(engine, false);
-			WARN_ON(nv_ofuncs(engine)->init(engine));
+			nvkm_object_fini(engine, false);
+			WARN_ON(nvkm_object_init(engine));
 		}
 	}
 
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c
index 3562b791162f..9d75dbaa01c0 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c
@@ -497,8 +497,8 @@ gk104_fifo_recover_work(struct work_struct *work)
 
 	for (todo = mask; engn = __ffs64(todo), todo; todo &= ~(1 << engn)) {
 		if ((engine = (void *)nvkm_engine(fifo, engn))) {
-			nv_ofuncs(engine)->fini(engine, false);
-			WARN_ON(nv_ofuncs(engine)->init(engine));
+			nvkm_object_fini(engine, false);
+			WARN_ON(nvkm_object_init(engine));
 		}
 		gk104_fifo_runlist_update(fifo, gk104_fifo_engidx(fifo, engn));
 	}
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/nv50.c
index bbcc3080a478..bf40509cda94 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/nv50.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/devinit/nv50.c
@@ -117,7 +117,7 @@ nv50_devinit_init(struct nvkm_object *object)
 	 * the vbios engineers didn't make the scripts just work...
 	 */
 	if (init->base.post && ibus)
-		nv_ofuncs(ibus)->init(nv_object(ibus));
+		nvkm_object_init(&ibus->object);
 
 	ret = nvkm_devinit_init(&init->base);
 	if (ret)