diff --git a/drivers/gpu/drm/nouveau/core/core/parent.c b/drivers/gpu/drm/nouveau/core/core/parent.c
index dee5d1235e9bb6701e0b5214da3482d5d334fbfb..8701968a9743aa7540cdfc0759919c058a45a3fa 100644
--- a/drivers/gpu/drm/nouveau/core/core/parent.c
+++ b/drivers/gpu/drm/nouveau/core/core/parent.c
@@ -74,6 +74,39 @@ nouveau_parent_sclass(struct nouveau_object *parent, u16 handle,
 	return -EINVAL;
 }
 
+int
+nouveau_parent_lclass(struct nouveau_object *parent, u32 *lclass, int size)
+{
+	struct nouveau_sclass *sclass;
+	struct nouveau_engine *engine;
+	struct nouveau_oclass *oclass;
+	int nr = -1, i;
+	u64 mask;
+
+	sclass = nv_parent(parent)->sclass;
+	while (sclass) {
+		if (++nr < size)
+			lclass[nr] = sclass->oclass->handle;
+		sclass = sclass->sclass;
+	}
+
+	mask = nv_parent(parent)->engine;
+	while (i = __ffs64(mask), mask) {
+		engine = nouveau_engine(parent, i);
+		if (engine && (oclass = engine->sclass)) {
+			while (oclass->ofuncs) {
+				if (++nr < size)
+					lclass[nr] = oclass->handle;
+				oclass++;
+			}
+		}
+
+		mask &= ~(1ULL << i);
+	}
+
+	return nr + 1;
+}
+
 int
 nouveau_parent_create_(struct nouveau_object *parent,
 		       struct nouveau_object *engine,
diff --git a/drivers/gpu/drm/nouveau/core/include/core/parent.h b/drivers/gpu/drm/nouveau/core/include/core/parent.h
index 9f5ea900ff009461d0abcb98e8cad65e29c2cbb9..12da418ec70a2c29ef968aea14f692eb87197ee9 100644
--- a/drivers/gpu/drm/nouveau/core/include/core/parent.h
+++ b/drivers/gpu/drm/nouveau/core/include/core/parent.h
@@ -57,5 +57,6 @@ void _nouveau_parent_dtor(struct nouveau_object *);
 int nouveau_parent_sclass(struct nouveau_object *, u16 handle,
 			  struct nouveau_object **pengine,
 			  struct nouveau_oclass **poclass);
+int nouveau_parent_lclass(struct nouveau_object *, u32 *, int);
 
 #endif