drivers/media/platform/amphion/vpu_core.c

Source file repositories/reference/linux-study-clean/drivers/media/platform/amphion/vpu_core.c

File Facts

System
Linux kernel
Corpus path
drivers/media/platform/amphion/vpu_core.c
Extension
.c
Size
19674 bytes
Lines
862
Domain
Driver Families
Bucket
drivers/media
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

if (c->state == VPU_CORE_DEINIT) {
			core = c;
			break;
		}
		if (c->state != VPU_CORE_ACTIVE)
			continue;
		if (c->request_count < request_count) {
			request_count = c->request_count;
			core = c;
		}
		if (!request_count)
			break;
	}

	return core;
}

static bool vpu_core_is_exist(struct vpu_dev *vpu, struct vpu_core *core)
{
	struct vpu_core *c;

	list_for_each_entry(c, &vpu->cores, list) {
		if (c == core)
			return true;
	}

	return false;
}

static void vpu_core_get_vpu(struct vpu_core *core)
{
	core->vpu->get_vpu(core->vpu);
	if (core->type == VPU_CORE_TYPE_ENC)
		core->vpu->get_enc(core->vpu);
	if (core->type == VPU_CORE_TYPE_DEC)
		core->vpu->get_dec(core->vpu);
}

static int vpu_core_register(struct device *dev, struct vpu_core *core)
{
	struct vpu_dev *vpu = dev_get_drvdata(dev);
	unsigned int buffer_size;
	int ret = 0;

	dev_dbg(core->dev, "register core %s\n", vpu_core_type_desc(core->type));
	if (vpu_core_is_exist(vpu, core))
		return 0;

	core->workqueue = alloc_ordered_workqueue("vpu", WQ_MEM_RECLAIM);
	if (!core->workqueue) {
		dev_err(core->dev, "fail to alloc workqueue\n");
		return -ENOMEM;
	}
	INIT_WORK(&core->msg_work, vpu_msg_run_work);
	INIT_DELAYED_WORK(&core->msg_delayed_work, vpu_msg_delayed_work);
	buffer_size = roundup_pow_of_two(VPU_MSG_BUFFER_SIZE);
	core->msg_buffer = kzalloc(buffer_size, GFP_KERNEL);
	if (!core->msg_buffer) {
		dev_err(core->dev, "failed allocate buffer for fifo\n");
		ret = -ENOMEM;
		goto error;
	}
	ret = kfifo_init(&core->msg_fifo, core->msg_buffer, buffer_size);
	if (ret) {
		dev_err(core->dev, "failed init kfifo\n");
		goto error;
	}

	list_add_tail(&core->list, &vpu->cores);
	vpu_core_get_vpu(core);

	return 0;
error:
	kfree(core->msg_buffer);
	core->msg_buffer = NULL;
	if (core->workqueue) {
		destroy_workqueue(core->workqueue);
		core->workqueue = NULL;
	}
	return ret;
}

static void vpu_core_put_vpu(struct vpu_core *core)
{
	if (core->type == VPU_CORE_TYPE_ENC)
		core->vpu->put_enc(core->vpu);
	if (core->type == VPU_CORE_TYPE_DEC)
		core->vpu->put_dec(core->vpu);
	core->vpu->put_vpu(core->vpu);
}

Annotation

Implementation Notes