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.
- 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.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/init.hlinux/interconnect.hlinux/ioctl.hlinux/list.hlinux/kernel.hlinux/module.hlinux/of.hlinux/of_reserved_mem.hlinux/platform_device.hlinux/slab.hlinux/types.hlinux/pm_runtime.hlinux/pm_domain.hlinux/firmware.hvpu.hvpu_defs.hvpu_core.hvpu_mbox.hvpu_msgs.hvpu_rpc.hvpu_cmds.h
Detected Declarations
function csr_writelfunction csr_readlfunction vpu_core_load_firmwarefunction vpu_core_boot_donefunction vpu_core_wait_boot_donefunction vpu_core_bootfunction vpu_core_shutdownfunction vpu_core_restorefunction __vpu_alloc_dmafunction vpu_free_dmafunction vpu_alloc_dmafunction vpu_core_set_statefunction vpu_core_update_statefunction list_for_each_entryfunction vpu_core_is_existfunction list_for_each_entryfunction vpu_core_get_vpufunction vpu_core_registerfunction vpu_core_put_vpufunction vpu_core_unregisterfunction vpu_core_acquire_instancefunction vpu_core_release_instancefunction vpu_inst_putfunction vpu_release_corefunction vpu_inst_registerfunction vpu_inst_unregisterfunction vpu_core_parse_dtfunction vpu_core_probefunction vpu_core_removefunction vpu_core_runtime_resumefunction vpu_core_runtime_suspendfunction vpu_core_cancel_workfunction vpu_core_resume_workfunction vpu_core_resumefunction vpu_core_suspendfunction vpu_core_driver_initfunction vpu_core_driver_exit
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
- Immediate include surface: `linux/init.h`, `linux/interconnect.h`, `linux/ioctl.h`, `linux/list.h`, `linux/kernel.h`, `linux/module.h`, `linux/of.h`, `linux/of_reserved_mem.h`.
- Detected declarations: `function csr_writel`, `function csr_readl`, `function vpu_core_load_firmware`, `function vpu_core_boot_done`, `function vpu_core_wait_boot_done`, `function vpu_core_boot`, `function vpu_core_shutdown`, `function vpu_core_restore`, `function __vpu_alloc_dma`, `function vpu_free_dma`.
- Atlas domain: Driver Families / drivers/media.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.