static int nvkm_udevice_child_get(struct nvkm_object *object, int index, struct nvkm_oclass *oclass) { struct nvkm_udevice *udev = nvkm_udevice(object); struct nvkm_device *device = udev->device; struct nvkm_engine *engine; u64 mask = (1ULL << NVKM_ENGINE_DMAOBJ) | (1ULL << NVKM_ENGINE_FIFO) | (1ULL << NVKM_ENGINE_DISP) | (1ULL << NVKM_ENGINE_PM); const struct nvkm_device_oclass *sclass = NULL; int i; for (; i = __ffs64(mask), mask && !sclass; mask &= ~(1ULL << i)) { if (!(engine = nvkm_device_engine(device, i)) || !(engine->func->base.sclass)) continue; oclass->engine = engine; index -= engine->func->base.sclass(oclass, index, &sclass); } if (!sclass) { switch (index) { case 0: sclass = &nvkm_control_oclass; break; default: return -EINVAL; } oclass->base = sclass->base; } oclass->ctor = nvkm_udevice_child_new; oclass->priv = sclass; return 0; }
static int nv50_disp_chan_child_get(struct nvkm_object *object, int index, struct nvkm_oclass *sclass) { struct nv50_disp_chan *chan = nv50_disp_chan(object); struct nvkm_device *device = chan->disp->base.engine.subdev.device; const struct nvkm_device_oclass *oclass = NULL; if (chan->func->bind) sclass->engine = nvkm_device_engine(device, NVKM_ENGINE_DMAOBJ); else sclass->engine = NULL; if (sclass->engine && sclass->engine->func->base.sclass) { sclass->engine->func->base.sclass(sclass, index, &oclass); if (oclass) { sclass->ctor = nv50_disp_chan_child_new, sclass->priv = oclass; return 0; } } return -EINVAL; }