drivers/media/platform/mediatek/vcodec/decoder/vdec_msg_queue.c
Source file repositories/reference/linux-study-clean/drivers/media/platform/mediatek/vcodec/decoder/vdec_msg_queue.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/media/platform/mediatek/vcodec/decoder/vdec_msg_queue.c- Extension
.c- Size
- 10657 bytes
- Lines
- 373
- 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.
- 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/freezer.hlinux/interrupt.hlinux/kthread.hmtk_vcodec_dec_drv.hmtk_vcodec_dec_pm.hvdec_msg_queue.h
Detected Declarations
function Copyrightfunction vdec_msg_queue_init_ctxfunction vdec_msg_queue_incfunction vdec_msg_queue_decfunction vdec_msg_queue_qbuffunction vdec_msg_queue_wait_eventfunction vdec_msg_queue_update_ube_rptrfunction vdec_msg_queue_update_ube_wptrfunction vdec_msg_queue_wait_lat_buf_fullfunction vdec_msg_queue_deinitfunction vdec_msg_queue_core_workfunction vdec_msg_queue_init
Annotated Snippet
if (!(buf->ctx->msg_queue.status & CONTEXT_LIST_QUEUED)) {
queue_work(buf->ctx->dev->core_workqueue, &buf->ctx->msg_queue.core_work);
buf->ctx->msg_queue.status |= CONTEXT_LIST_QUEUED;
}
}
mtk_v4l2_vdec_dbg(3, buf->ctx, "enqueue buf type: %d addr: 0x%p num: %d",
msg_ctx->hardware_index, buf, msg_ctx->ready_num);
spin_unlock(&msg_ctx->ready_lock);
return 0;
}
static bool vdec_msg_queue_wait_event(struct vdec_msg_queue_ctx *msg_ctx)
{
int ret;
ret = wait_event_timeout(msg_ctx->ready_to_use,
!list_empty(&msg_ctx->ready_queue),
msecs_to_jiffies(VDEC_MSG_QUEUE_TIMEOUT_MS));
if (!ret)
return false;
return true;
}
struct vdec_lat_buf *vdec_msg_queue_dqbuf(struct vdec_msg_queue_ctx *msg_ctx)
{
struct vdec_lat_buf *buf;
struct list_head *head;
int ret;
spin_lock(&msg_ctx->ready_lock);
if (list_empty(&msg_ctx->ready_queue)) {
spin_unlock(&msg_ctx->ready_lock);
if (msg_ctx->hardware_index == MTK_VDEC_CORE)
return NULL;
ret = vdec_msg_queue_wait_event(msg_ctx);
if (!ret)
return NULL;
spin_lock(&msg_ctx->ready_lock);
}
if (msg_ctx->hardware_index == MTK_VDEC_CORE)
buf = list_first_entry(&msg_ctx->ready_queue,
struct vdec_lat_buf, core_list);
else
buf = list_first_entry(&msg_ctx->ready_queue,
struct vdec_lat_buf, lat_list);
head = vdec_get_buf_list(msg_ctx->hardware_index, buf);
if (!head) {
spin_unlock(&msg_ctx->ready_lock);
mtk_v4l2_vdec_err(buf->ctx, "fail to dqbuf: %d", msg_ctx->hardware_index);
return NULL;
}
list_del(head);
vdec_msg_queue_dec(&buf->ctx->msg_queue, msg_ctx->hardware_index);
msg_ctx->ready_num--;
mtk_v4l2_vdec_dbg(3, buf->ctx, "dqueue buf type:%d addr: 0x%p num: %d",
msg_ctx->hardware_index, buf, msg_ctx->ready_num);
spin_unlock(&msg_ctx->ready_lock);
return buf;
}
void vdec_msg_queue_update_ube_rptr(struct vdec_msg_queue *msg_queue, uint64_t ube_rptr)
{
spin_lock(&msg_queue->lat_ctx.ready_lock);
msg_queue->wdma_rptr_addr = ube_rptr;
mtk_v4l2_vdec_dbg(3, msg_queue->ctx, "update ube rprt (0x%llx)", ube_rptr);
spin_unlock(&msg_queue->lat_ctx.ready_lock);
}
void vdec_msg_queue_update_ube_wptr(struct vdec_msg_queue *msg_queue, uint64_t ube_wptr)
{
spin_lock(&msg_queue->lat_ctx.ready_lock);
msg_queue->wdma_wptr_addr = ube_wptr;
mtk_v4l2_vdec_dbg(3, msg_queue->ctx, "update ube wprt: (0x%llx 0x%llx) offset: 0x%llx",
msg_queue->wdma_rptr_addr, msg_queue->wdma_wptr_addr,
ube_wptr);
spin_unlock(&msg_queue->lat_ctx.ready_lock);
}
bool vdec_msg_queue_wait_lat_buf_full(struct vdec_msg_queue *msg_queue)
{
if (atomic_read(&msg_queue->lat_list_cnt) == NUM_BUFFER_COUNT) {
Annotation
- Immediate include surface: `linux/freezer.h`, `linux/interrupt.h`, `linux/kthread.h`, `mtk_vcodec_dec_drv.h`, `mtk_vcodec_dec_pm.h`, `vdec_msg_queue.h`.
- Detected declarations: `function Copyright`, `function vdec_msg_queue_init_ctx`, `function vdec_msg_queue_inc`, `function vdec_msg_queue_dec`, `function vdec_msg_queue_qbuf`, `function vdec_msg_queue_wait_event`, `function vdec_msg_queue_update_ube_rptr`, `function vdec_msg_queue_update_ube_wptr`, `function vdec_msg_queue_wait_lat_buf_full`, `function vdec_msg_queue_deinit`.
- 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.
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.