drivers/media/platform/chips-media/wave5/wave5-vpu.c
Source file repositories/reference/linux-study-clean/drivers/media/platform/chips-media/wave5/wave5-vpu.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/media/platform/chips-media/wave5/wave5-vpu.c- Extension
.c- Size
- 12799 bytes
- Lines
- 485
- 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/kernel.hlinux/module.hlinux/platform_device.hlinux/clk.hlinux/firmware.hlinux/interrupt.hlinux/pm_runtime.hlinux/reset.hwave5-vpu.hwave5-regdefine.hwave5-vpuconfig.hwave5.h
Detected Declarations
struct wave5_match_datafunction wave5_vpu_wait_interruptfunction wave5_vpu_handle_irqfunction wave5_vpu_irqfunction wave5_vpu_irq_threadfunction wave5_vpu_irq_work_fnfunction wave5_vpu_timer_callbackfunction irq_threadfunction list_for_each_entry_safefunction wave5_vpu_load_firmwarefunction wave5_pm_suspendfunction wave5_pm_resumefunction wave5_vpu_probefunction wave5_vpu_remove
Annotated Snippet
struct wave5_match_data {
int flags;
const char *fw_name;
u32 sram_size;
};
static int vpu_poll_interval = 5;
module_param(vpu_poll_interval, int, 0644);
int wave5_vpu_wait_interrupt(struct vpu_instance *inst, unsigned int timeout)
{
int ret;
ret = wait_for_completion_timeout(&inst->irq_done,
msecs_to_jiffies(timeout));
if (!ret)
return -ETIMEDOUT;
reinit_completion(&inst->irq_done);
return 0;
}
static void wave5_vpu_handle_irq(void *dev_id)
{
u32 seq_done;
u32 cmd_done;
u32 irq_reason;
u32 irq_subreason;
struct vpu_instance *inst, *tmp;
struct vpu_device *dev = dev_id;
int val;
unsigned long flags;
irq_reason = wave5_vdi_read_register(dev, W5_VPU_VINT_REASON);
seq_done = wave5_vdi_read_register(dev, W5_RET_SEQ_DONE_INSTANCE_INFO);
cmd_done = wave5_vdi_read_register(dev, W5_RET_QUEUE_CMD_DONE_INST);
wave5_vdi_write_register(dev, W5_VPU_VINT_REASON_CLR, irq_reason);
wave5_vdi_write_register(dev, W5_VPU_VINT_CLEAR, 0x1);
spin_lock_irqsave(&dev->irq_spinlock, flags);
list_for_each_entry_safe(inst, tmp, &dev->instances, list) {
if (irq_reason & BIT(INT_WAVE5_INIT_SEQ) ||
irq_reason & BIT(INT_WAVE5_ENC_SET_PARAM)) {
if (dev->product_code == WAVE515_CODE &&
(cmd_done & BIT(inst->id))) {
cmd_done &= ~BIT(inst->id);
wave5_vdi_write_register(dev, W5_RET_QUEUE_CMD_DONE_INST,
cmd_done);
complete(&inst->irq_done);
} else if (seq_done & BIT(inst->id)) {
seq_done &= ~BIT(inst->id);
wave5_vdi_write_register(dev, W5_RET_SEQ_DONE_INSTANCE_INFO,
seq_done);
complete(&inst->irq_done);
}
}
if (irq_reason & BIT(INT_WAVE5_DEC_PIC) ||
irq_reason & BIT(INT_WAVE5_ENC_PIC)) {
if (cmd_done & BIT(inst->id)) {
cmd_done &= ~BIT(inst->id);
if (dev->irq >= 0) {
irq_subreason =
wave5_vdi_read_register(dev, W5_VPU_VINT_REASON);
if (!(irq_subreason & BIT(INT_WAVE5_DEC_PIC)))
wave5_vdi_write_register(dev,
W5_RET_QUEUE_CMD_DONE_INST,
cmd_done);
}
val = BIT(INT_WAVE5_DEC_PIC);
kfifo_in(&inst->irq_status, &val, sizeof(int));
}
}
}
spin_unlock_irqrestore(&dev->irq_spinlock, flags);
if (dev->irq < 0)
up(&dev->irq_sem);
}
static irqreturn_t wave5_vpu_irq(int irq, void *dev_id)
{
struct vpu_device *dev = dev_id;
if (wave5_vdi_read_register(dev, W5_VPU_VPU_INT_STS)) {
wave5_vpu_handle_irq(dev);
return IRQ_WAKE_THREAD;
}
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/module.h`, `linux/platform_device.h`, `linux/clk.h`, `linux/firmware.h`, `linux/interrupt.h`, `linux/pm_runtime.h`, `linux/reset.h`.
- Detected declarations: `struct wave5_match_data`, `function wave5_vpu_wait_interrupt`, `function wave5_vpu_handle_irq`, `function wave5_vpu_irq`, `function wave5_vpu_irq_thread`, `function wave5_vpu_irq_work_fn`, `function wave5_vpu_timer_callback`, `function irq_thread`, `function list_for_each_entry_safe`, `function wave5_vpu_load_firmware`.
- 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.