diff --git a/drivers/gpu/drm/nouveau/include/nvif/client.h b/drivers/gpu/drm/nouveau/include/nvif/client.h
index 4d5db8039576baef9da12d27c86f9537383d0bb8..4a7f6f7b836d69dc587d2c1acb0c2f7211812452 100644
--- a/drivers/gpu/drm/nouveau/include/nvif/client.h
+++ b/drivers/gpu/drm/nouveau/include/nvif/client.h
@@ -23,6 +23,6 @@ int  nvif_client_resume(struct nvif_client *);
 #include <core/client.h>
 #define nvxx_client(a) ({                                                      \
 	struct nvif_client *_client = (a);                                     \
-	nvkm_client(_client->object.priv);                                     \
+	(struct nvkm_client *)_client->object.priv;                            \
 })
 #endif
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/client.h b/drivers/gpu/drm/nouveau/include/nvkm/core/client.h
index ff6331d7e9e67506c1536515221feb4bd06e8444..4bb0acca8650a9a18bd6597128d7fa2ed8ee5e52 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/core/client.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/core/client.h
@@ -1,37 +1,29 @@
 #ifndef __NVKM_CLIENT_H__
 #define __NVKM_CLIENT_H__
-#include <core/namedb.h>
+#include <core/object.h>
 
 struct nvkm_client {
-	struct nvkm_namedb namedb;
-	struct nvkm_handle *root;
-	u64 device;
+	struct nvkm_object object;
 	char name[32];
+	u64 device;
 	u32 debug;
-	struct nvkm_vm *vm;
+
+	struct nvkm_client_notify *notify[16];
+	struct rb_root objroot;
+
+	struct nvkm_handle *root;
+
 	bool super;
 	void *data;
-
 	int (*ntfy)(const void *, u32, const void *, u32);
-	struct nvkm_client_notify *notify[16];
 
-	struct rb_root objroot;
+	struct nvkm_vm *vm;
 };
 
 bool nvkm_client_insert(struct nvkm_client *, struct nvkm_handle *);
 void nvkm_client_remove(struct nvkm_client *, struct nvkm_handle *);
 struct nvkm_handle *nvkm_client_search(struct nvkm_client *, u64 handle);
 
-static inline struct nvkm_client *
-nvkm_client(struct nvkm_object *object)
-{
-	while (object && object->parent)
-		object = object->parent;
-	if (object && nv_iclass(object, NV_CLIENT_CLASS))
-		return container_of(object, struct nvkm_client, namedb.parent.object);
-	return NULL;
-}
-
 int  nvkm_client_new(const char *name, u64 device, const char *cfg,
 		     const char *dbg, struct nvkm_client **);
 void nvkm_client_del(struct nvkm_client **);
@@ -39,6 +31,14 @@ int  nvkm_client_init(struct nvkm_client *);
 int  nvkm_client_fini(struct nvkm_client *, bool suspend);
 const char *nvkm_client_name(void *obj);
 
+static inline struct nvkm_client *
+nvkm_client(struct nvkm_object *object)
+{
+	while (object && object->parent)
+		object = object->parent;
+	return container_of(object, struct nvkm_client, object);
+}
+
 int nvkm_client_notify_new(struct nvkm_object *, struct nvkm_event *,
 			   void *data, u32 size);
 int nvkm_client_notify_del(struct nvkm_client *, int index);
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/engctx.h b/drivers/gpu/drm/nouveau/include/nvkm/core/engctx.h
index aa465def4f95f9ddd31ef9f5b7e787edb87e7e34..dfa24d233321aa8e2ec78b237f549376e13ac4b7 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/core/engctx.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/core/engctx.h
@@ -1,6 +1,7 @@
 #ifndef __NVKM_ENGCTX_H__
 #define __NVKM_ENGCTX_H__
 #include <core/gpuobj.h>
+#include <core/parent.h>
 
 #include <subdev/mmu.h>
 
diff --git a/drivers/gpu/drm/nouveau/nvkm/core/client.c b/drivers/gpu/drm/nouveau/nvkm/core/client.c
index 9a7c4bc24a767b53bb80521f59858c94738cddd7..1affa2299a8ce6435d141c3f3c3593a10ac67f9a 100644
--- a/drivers/gpu/drm/nouveau/nvkm/core/client.c
+++ b/drivers/gpu/drm/nouveau/nvkm/core/client.c
@@ -176,11 +176,35 @@ nvkm_client_mthd(struct nvkm_object *object, u32 mthd, void *data, u32 size)
 	return -EINVAL;
 }
 
-static struct nvkm_oclass
-nvkm_client_oclass = {
-	.ofuncs = &(struct nvkm_ofuncs) {
-		.mthd = nvkm_client_mthd,
-	},
+static int
+nvkm_client_child_new(const struct nvkm_oclass *oclass,
+		      void *data, u32 size, struct nvkm_object **pobject)
+{
+	static struct nvkm_oclass devobj = {
+		.handle = NV_DEVICE,
+		.ofuncs = &nvkm_udevice_ofuncs,
+	};
+	return nvkm_object_old(oclass->parent, NULL, &devobj, data, size, pobject);
+}
+
+static int
+nvkm_client_child_get(struct nvkm_object *object, int index,
+		      struct nvkm_oclass *oclass)
+{
+	if (index == 0) {
+		oclass->base.oclass = NV_DEVICE;
+		oclass->base.minver = 0;
+		oclass->base.maxver = 0;
+		oclass->ctor = nvkm_client_child_new;
+		return 0;
+	}
+	return -EINVAL;
+}
+
+static const struct nvkm_object_func
+nvkm_client_object_func = {
+	.mthd = nvkm_client_mthd,
+	.sclass = nvkm_client_child_get,
 };
 
 void
@@ -235,7 +259,7 @@ nvkm_client_search(struct nvkm_client *client, u64 handle)
 int
 nvkm_client_fini(struct nvkm_client *client, bool suspend)
 {
-	struct nvkm_object *object = &client->namedb.parent.object;
+	struct nvkm_object *object = &client->object;
 	const char *name[2] = { "fini", "suspend" };
 	int ret, i;
 	nvif_trace(object, "%s running\n", name[suspend]);
@@ -251,7 +275,7 @@ nvkm_client_fini(struct nvkm_client *client, bool suspend)
 int
 nvkm_client_init(struct nvkm_client *client)
 {
-	struct nvkm_object *object = &client->namedb.parent.object;
+	struct nvkm_object *object = &client->object;
 	int ret;
 	nvif_trace(object, "init running\n");
 	ret = nvkm_handle_init(client->root);
@@ -269,43 +293,33 @@ nvkm_client_del(struct nvkm_client **pclient)
 		for (i = 0; i < ARRAY_SIZE(client->notify); i++)
 			nvkm_client_notify_del(client, i);
 		nvkm_handle_destroy(client->root);
-		nvkm_namedb_destroy(&client->namedb);
+		kfree(*pclient);
 		*pclient = NULL;
 	}
 }
 
-static struct nvkm_oclass
-nvkm_client_sclass[] = {
-	{ NV_DEVICE, &nvkm_udevice_ofuncs },
-	{}
-};
-
 int
 nvkm_client_new(const char *name, u64 device, const char *cfg,
 		const char *dbg, struct nvkm_client **pclient)
 {
+	struct nvkm_oclass oclass = {};
 	struct nvkm_client *client;
 	int ret;
 
-	ret = nvkm_namedb_create(NULL, NULL, &nvkm_client_oclass,
-				 NV_CLIENT_CLASS, nvkm_client_sclass,
-				 0, &client);
-	*pclient = client;
-	if (ret)
-		return ret;
-
-	ret = nvkm_handle_create(NULL, ~0, nv_object(client), &client->root);
-	if (ret)
-		return ret;
-
-	/* prevent init/fini being called, os in in charge of this */
-	atomic_set(&nv_object(client)->usecount, 2);
+	if (!(client = *pclient = kzalloc(sizeof(*client), GFP_KERNEL)))
+		return -ENOMEM;
+	oclass.client = client;
 
-	client->device = device;
+	nvkm_object_ctor(&nvkm_client_object_func, &oclass, &client->object);
 	snprintf(client->name, sizeof(client->name), "%s", name);
+	client->device = device;
 	client->debug = nvkm_dbgopt(dbg, "CLIENT");
 	client->objroot = RB_ROOT;
-	return 0;
+
+	ret = nvkm_handle_create(NULL, ~0, &client->object, &client->root);
+	if (ret)
+		nvkm_client_del(pclient);
+	return ret;
 }
 
 const char *
diff --git a/drivers/gpu/drm/nouveau/nvkm/core/handle.c b/drivers/gpu/drm/nouveau/nvkm/core/handle.c
index 0c7cde900df608e998ed30c259fe483dd3a5fa3e..2b52a655309b71ddc882d0b73b82b1e611814458 100644
--- a/drivers/gpu/drm/nouveau/nvkm/core/handle.c
+++ b/drivers/gpu/drm/nouveau/nvkm/core/handle.c
@@ -23,6 +23,7 @@
  */
 #include <core/handle.h>
 #include <core/client.h>
+#include <core/namedb.h>
 
 #define hprintk(h,l,f,a...) do {                                               \
 	struct nvkm_handle *p = (h)->parent; u32 n = p ? p->name : ~0;         \
diff --git a/drivers/gpu/drm/nouveau/nvkm/core/ioctl.c b/drivers/gpu/drm/nouveau/nvkm/core/ioctl.c
index b9c81369043384ed6f35ce2972ea85decdd5bb5b..04f1bc2d0f8ee8838bc8e98ed3ea6f729535164b 100644
--- a/drivers/gpu/drm/nouveau/nvkm/core/ioctl.c
+++ b/drivers/gpu/drm/nouveau/nvkm/core/ioctl.c
@@ -535,12 +535,12 @@ nvkm_ioctl_path(struct nvkm_client *client, u64 handle, u32 type,
 	else
 		object = client->root;
 	if (unlikely(!object)) {
-		nvif_ioctl(&client->namedb.parent.object, "object not found\n");
+		nvif_ioctl(&client->object, "object not found\n");
 		return -ENOENT;
 	}
 
 	if (owner != NVIF_IOCTL_V0_OWNER_ANY && owner != object->route) {
-		nvif_ioctl(&client->namedb.parent.object, "route != owner\n");
+		nvif_ioctl(&client->object, "route != owner\n");
 		return -EACCES;
 	}
 	*route = object->route;
@@ -558,7 +558,7 @@ int
 nvkm_ioctl(struct nvkm_client *client, bool supervisor,
 	   void *data, u32 size, void **hack)
 {
-	struct nvkm_object *object = &client->namedb.parent.object;
+	struct nvkm_object *object = &client->object;
 	union {
 		struct nvif_ioctl_v0 v0;
 	} *args = data;
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c
index b3f33360258293094e2d610df0f8ee8a999e6d69..a59a8e50706bac815fd5bfb30f7ecf5bcaf56e9c 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c
@@ -1988,7 +1988,7 @@ nv_device(void *obj)
 	if (device->engine == NULL) {
 		while (device && device->parent) {
 			if (!nv_iclass(device, NV_SUBDEV_CLASS) &&
-			    device->parent == &nvkm_client(device)->namedb.parent.object) {
+			    device->parent == &nvkm_client(device)->object) {
 				struct {
 					struct nvkm_parent base;
 					struct nvkm_device *device;
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/user.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/user.c
index 0df54c657469098db21043ef00dc7d5c4c51d8c8..59b28cbe66344995eaf2f9dc953de86558132420 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/device/user.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/user.c
@@ -24,6 +24,7 @@
 #include "priv.h"
 
 #include <core/client.h>
+#include <core/parent.h>
 #include <subdev/fb.h>
 #include <subdev/instmem.h>
 #include <subdev/timer.h>
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/pm/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/pm/base.c
index b3ae0d96ddb05ffa6211297234b50ad63a0b93a8..ae84db1f296bc63b83e853b70b80648f4928a3c8 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/pm/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/pm/base.c
@@ -25,6 +25,7 @@
 
 #include <core/client.h>
 #include <core/option.h>
+#include <core/parent.h>
 
 #include <nvif/class.h>
 #include <nvif/ioctl.h>