drivers/gpu/drm/nouveau/nvkm/engine/disp/chan.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/nouveau/nvkm/engine/disp/chan.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/nouveau/nvkm/engine/disp/chan.c
Extension
.c
Size
6864 bytes
Lines
252
Domain
Driver Families
Bucket
drivers/gpu
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct nvkm_disp_chan_object {
	struct nvkm_oproxy oproxy;
	struct nvkm_disp *disp;
	int hash;
};

static void
nvkm_disp_chan_child_del_(struct nvkm_oproxy *base)
{
	struct nvkm_disp_chan_object *object = container_of(base, typeof(*object), oproxy);

	nvkm_ramht_remove(object->disp->ramht, object->hash);
}

static const struct nvkm_oproxy_func
nvkm_disp_chan_child_func_ = {
	.dtor[0] = nvkm_disp_chan_child_del_,
};

static int
nvkm_disp_chan_child_new(const struct nvkm_oclass *oclass, void *argv, u32 argc,
			 struct nvkm_object **pobject)
{
	struct nvkm_disp_chan *chan = nvkm_disp_chan(oclass->parent);
	struct nvkm_disp *disp = chan->disp;
	struct nvkm_device *device = disp->engine.subdev.device;
	const struct nvkm_device_oclass *sclass = oclass->priv;
	struct nvkm_disp_chan_object *object;
	int ret;

	if (!(object = kzalloc_obj(*object)))
		return -ENOMEM;
	nvkm_oproxy_ctor(&nvkm_disp_chan_child_func_, oclass, &object->oproxy);
	object->disp = disp;
	*pobject = &object->oproxy.base;

	ret = sclass->ctor(device, oclass, argv, argc, &object->oproxy.object);
	if (ret)
		return ret;

	object->hash = chan->func->bind(chan, object->oproxy.object, oclass->handle);
	if (object->hash < 0)
		return object->hash;

	return 0;
}

static int
nvkm_disp_chan_child_get(struct nvkm_object *object, int index, struct nvkm_oclass *sclass)
{
	struct nvkm_disp_chan *chan = nvkm_disp_chan(object);
	struct nvkm_device *device = chan->disp->engine.subdev.device;
	const struct nvkm_device_oclass *oclass = NULL;

	if (chan->func->bind)
		sclass->engine = nvkm_device_engine(device, NVKM_ENGINE_DMAOBJ, 0);
	else
		sclass->engine = NULL;

	if (sclass->engine && sclass->engine->func->base.sclass) {
		sclass->engine->func->base.sclass(sclass, index, &oclass);
		if (oclass) {
			sclass->ctor = nvkm_disp_chan_child_new;
			sclass->priv = oclass;
			return 0;
		}
	}

	return -EINVAL;
}

static int
nvkm_disp_chan_fini(struct nvkm_object *object, enum nvkm_suspend_state suspend)
{
	struct nvkm_disp_chan *chan = nvkm_disp_chan(object);

	chan->func->fini(chan);
	chan->func->intr(chan, false);
	return 0;
}

static int
nvkm_disp_chan_init(struct nvkm_object *object)
{
	struct nvkm_disp_chan *chan = nvkm_disp_chan(object);

	chan->func->intr(chan, true);
	return chan->func->init(chan);
}

Annotation

Implementation Notes