drivers/accel/ivpu/ivpu_ipc.c
Source file repositories/reference/linux-study-clean/drivers/accel/ivpu/ivpu_ipc.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/accel/ivpu/ivpu_ipc.c- Extension
.c- Size
- 16016 bytes
- Lines
- 598
- Domain
- Driver Families
- Bucket
- drivers/accel
- 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/genalloc.hlinux/highmem.hlinux/pm_runtime.hlinux/wait.hivpu_drv.hivpu_gem.hivpu_hw.hivpu_hw_reg_io.hivpu_ipc.hivpu_jsm_msg.hivpu_pm.hivpu_trace.h
Detected Declarations
struct ivpu_ipc_tx_buffunction ivpu_ipc_msg_dumpfunction ivpu_jsm_msg_dumpfunction ivpu_ipc_rx_mark_freefunction ivpu_ipc_mem_finifunction ivpu_ipc_tx_preparefunction ivpu_ipc_tx_releasefunction ivpu_ipc_txfunction ivpu_ipc_rx_msg_addfunction ivpu_ipc_rx_msg_delfunction ivpu_ipc_consumer_addfunction ivpu_ipc_consumer_delfunction ivpu_ipc_sendfunction ivpu_ipc_rx_need_wakeupfunction ivpu_ipc_receivefunction ivpu_ipc_send_receive_internalfunction ivpu_ipc_send_receivefunction ivpu_ipc_send_and_waitfunction ivpu_ipc_match_consumerfunction ivpu_ipc_irq_handlerfunction list_for_each_entryfunction ivpu_ipc_irq_work_fnfunction list_for_each_entry_safefunction ivpu_ipc_initfunction ivpu_ipc_finifunction ivpu_ipc_enablefunction ivpu_ipc_disablefunction ivpu_ipc_reset
Annotated Snippet
struct ivpu_ipc_tx_buf {
struct ivpu_ipc_hdr ipc;
struct vpu_jsm_msg jsm;
};
static void ivpu_ipc_msg_dump(struct ivpu_device *vdev, char *c,
struct ivpu_ipc_hdr *ipc_hdr, u32 vpu_addr)
{
ivpu_dbg(vdev, IPC,
"%s: vpu:0x%x (data_addr:0x%08x, data_size:0x%x, channel:0x%x, src_node:0x%x, dst_node:0x%x, status:0x%x)",
c, vpu_addr, ipc_hdr->data_addr, ipc_hdr->data_size, ipc_hdr->channel,
ipc_hdr->src_node, ipc_hdr->dst_node, ipc_hdr->status);
}
static void ivpu_jsm_msg_dump(struct ivpu_device *vdev, char *c,
struct vpu_jsm_msg *jsm_msg, u32 vpu_addr)
{
u32 *payload = (u32 *)&jsm_msg->payload;
ivpu_dbg(vdev, JSM,
"%s: vpu:0x%08x (type:%s, status:0x%x, id: 0x%x, result: 0x%x, payload:0x%x 0x%x 0x%x 0x%x 0x%x)\n",
c, vpu_addr, ivpu_jsm_msg_type_to_str(jsm_msg->type),
jsm_msg->status, jsm_msg->request_id, jsm_msg->result,
payload[0], payload[1], payload[2], payload[3], payload[4]);
}
static void
ivpu_ipc_rx_mark_free(struct ivpu_device *vdev, struct ivpu_ipc_hdr *ipc_hdr,
struct vpu_jsm_msg *jsm_msg)
{
ipc_hdr->status = IVPU_IPC_HDR_FREE;
if (jsm_msg)
jsm_msg->status = VPU_JSM_MSG_FREE;
wmb(); /* Flush WC buffers for message statuses */
}
static void ivpu_ipc_mem_fini(struct ivpu_device *vdev)
{
struct ivpu_ipc_info *ipc = vdev->ipc;
ivpu_bo_free(ipc->mem_rx);
ivpu_bo_free(ipc->mem_tx);
}
static int
ivpu_ipc_tx_prepare(struct ivpu_device *vdev, struct ivpu_ipc_consumer *cons,
struct vpu_jsm_msg *req)
{
struct ivpu_ipc_info *ipc = vdev->ipc;
struct ivpu_ipc_tx_buf *tx_buf;
u32 tx_buf_vpu_addr;
u32 jsm_vpu_addr;
tx_buf_vpu_addr = gen_pool_alloc(ipc->mm_tx, sizeof(*tx_buf));
if (!tx_buf_vpu_addr) {
ivpu_err_ratelimited(vdev, "Failed to reserve IPC buffer, size %ld\n",
sizeof(*tx_buf));
return -ENOMEM;
}
tx_buf = ivpu_to_cpu_addr(ipc->mem_tx, tx_buf_vpu_addr);
if (drm_WARN_ON(&vdev->drm, !tx_buf)) {
gen_pool_free(ipc->mm_tx, tx_buf_vpu_addr, sizeof(*tx_buf));
return -EIO;
}
jsm_vpu_addr = tx_buf_vpu_addr + offsetof(struct ivpu_ipc_tx_buf, jsm);
if (tx_buf->ipc.status != IVPU_IPC_HDR_FREE)
ivpu_warn_ratelimited(vdev, "IPC message vpu:0x%x not released by firmware\n",
tx_buf_vpu_addr);
if (tx_buf->jsm.status != VPU_JSM_MSG_FREE)
ivpu_warn_ratelimited(vdev, "JSM message vpu:0x%x not released by firmware\n",
jsm_vpu_addr);
memset(tx_buf, 0, sizeof(*tx_buf));
tx_buf->ipc.data_addr = jsm_vpu_addr;
/*
* Firmware expects full JSM message size regardless of the payload size.
* Unused fields must be zeroed to allow future extensions of existing
* commands without breaking compatibility.
*/
tx_buf->ipc.data_size = sizeof(*req);
tx_buf->ipc.channel = cons->channel;
tx_buf->ipc.src_node = 0;
tx_buf->ipc.dst_node = 1;
tx_buf->ipc.status = IVPU_IPC_HDR_ALLOCATED;
tx_buf->jsm.type = req->type;
tx_buf->jsm.status = VPU_JSM_MSG_ALLOCATED;
Annotation
- Immediate include surface: `linux/genalloc.h`, `linux/highmem.h`, `linux/pm_runtime.h`, `linux/wait.h`, `ivpu_drv.h`, `ivpu_gem.h`, `ivpu_hw.h`, `ivpu_hw_reg_io.h`.
- Detected declarations: `struct ivpu_ipc_tx_buf`, `function ivpu_ipc_msg_dump`, `function ivpu_jsm_msg_dump`, `function ivpu_ipc_rx_mark_free`, `function ivpu_ipc_mem_fini`, `function ivpu_ipc_tx_prepare`, `function ivpu_ipc_tx_release`, `function ivpu_ipc_tx`, `function ivpu_ipc_rx_msg_add`, `function ivpu_ipc_rx_msg_del`.
- Atlas domain: Driver Families / drivers/accel.
- 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.