drivers/dma/dw-edma/dw-hdma-v0-core.c
Source file repositories/reference/linux-study-clean/drivers/dma/dw-edma/dw-hdma-v0-core.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/dma/dw-edma/dw-hdma-v0-core.c- Extension
.c- Size
- 10092 bytes
- Lines
- 369
- Domain
- Driver Families
- Bucket
- drivers/dma
- 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.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/bitfield.hlinux/irqreturn.hlinux/io-64-nonatomic-lo-hi.hdw-edma-core.hdw-hdma-v0-core.hdw-hdma-v0-regs.hdw-hdma-v0-debugfs.h
Detected Declarations
enum dw_hdma_controlfunction __dw_ch_regsfunction dw_hdma_v0_core_offfunction dw_hdma_v0_core_ch_countfunction dw_hdma_v0_core_ch_statusfunction dw_hdma_v0_core_clear_done_intfunction dw_hdma_v0_core_clear_abort_intfunction dw_hdma_v0_core_status_intfunction dw_hdma_v0_core_handle_intfunction for_each_set_bitfunction dw_hdma_v0_write_ll_datafunction dw_hdma_v0_write_ll_linkfunction dw_hdma_v0_core_write_chunkfunction dw_hdma_v0_sync_ll_datafunction dw_hdma_v0_core_ll_startfunction dw_hdma_v0_core_non_ll_startfunction dw_hdma_v0_core_startfunction dw_hdma_v0_core_ch_configfunction dw_hdma_v0_core_debugfs_onfunction dw_hdma_v0_core_db_offsetfunction dw_hdma_v0_core_register
Annotated Snippet
if (FIELD_GET(HDMA_V0_STOP_INT_MASK, val)) {
dw_hdma_v0_core_clear_done_int(chan);
done(chan);
ret = IRQ_HANDLED;
}
if (FIELD_GET(HDMA_V0_ABORT_INT_MASK, val)) {
dw_hdma_v0_core_clear_abort_int(chan);
abort(chan);
ret = IRQ_HANDLED;
}
}
return ret;
}
static void dw_hdma_v0_write_ll_data(struct dw_edma_chunk *chunk, int i,
u32 control, u32 size, u64 sar, u64 dar)
{
ptrdiff_t ofs = i * sizeof(struct dw_hdma_v0_lli);
if (chunk->chan->dw->chip->flags & DW_EDMA_CHIP_LOCAL) {
struct dw_hdma_v0_lli *lli = chunk->ll_region.vaddr.mem + ofs;
lli->control = control;
lli->transfer_size = size;
lli->sar.reg = sar;
lli->dar.reg = dar;
} else {
struct dw_hdma_v0_lli __iomem *lli = chunk->ll_region.vaddr.io + ofs;
writel(control, &lli->control);
writel(size, &lli->transfer_size);
writeq(sar, &lli->sar.reg);
writeq(dar, &lli->dar.reg);
}
}
static void dw_hdma_v0_write_ll_link(struct dw_edma_chunk *chunk,
int i, u32 control, u64 pointer)
{
ptrdiff_t ofs = i * sizeof(struct dw_hdma_v0_lli);
if (chunk->chan->dw->chip->flags & DW_EDMA_CHIP_LOCAL) {
struct dw_hdma_v0_llp *llp = chunk->ll_region.vaddr.mem + ofs;
llp->control = control;
llp->llp.reg = pointer;
} else {
struct dw_hdma_v0_llp __iomem *llp = chunk->ll_region.vaddr.io + ofs;
writel(control, &llp->control);
writeq(pointer, &llp->llp.reg);
}
}
static void dw_hdma_v0_core_write_chunk(struct dw_edma_chunk *chunk)
{
struct dw_edma_burst *child;
u32 control = 0, i = 0;
if (chunk->cb)
control = DW_HDMA_V0_CB;
list_for_each_entry(child, &chunk->burst->list, list)
dw_hdma_v0_write_ll_data(chunk, i++, control, child->sz,
child->sar, child->dar);
control = DW_HDMA_V0_LLP | DW_HDMA_V0_TCB;
if (!chunk->cb)
control |= DW_HDMA_V0_CB;
dw_hdma_v0_write_ll_link(chunk, i, control, chunk->ll_region.paddr);
}
static void dw_hdma_v0_sync_ll_data(struct dw_edma_chunk *chunk)
{
/*
* In case of remote HDMA engine setup, the DW PCIe RP/EP internal
* configuration registers and application memory are normally accessed
* over different buses. Ensure LL-data reaches the memory before the
* doorbell register is toggled by issuing the dummy-read from the remote
* LL memory in a hope that the MRd TLP will return only after the
* last MWr TLP is completed
*/
if (!(chunk->chan->dw->chip->flags & DW_EDMA_CHIP_LOCAL))
readl(chunk->ll_region.vaddr.io);
}
Annotation
- Immediate include surface: `linux/bitfield.h`, `linux/irqreturn.h`, `linux/io-64-nonatomic-lo-hi.h`, `dw-edma-core.h`, `dw-hdma-v0-core.h`, `dw-hdma-v0-regs.h`, `dw-hdma-v0-debugfs.h`.
- Detected declarations: `enum dw_hdma_control`, `function __dw_ch_regs`, `function dw_hdma_v0_core_off`, `function dw_hdma_v0_core_ch_count`, `function dw_hdma_v0_core_ch_status`, `function dw_hdma_v0_core_clear_done_int`, `function dw_hdma_v0_core_clear_abort_int`, `function dw_hdma_v0_core_status_int`, `function dw_hdma_v0_core_handle_int`, `function for_each_set_bit`.
- Atlas domain: Driver Families / drivers/dma.
- Implementation status: source implementation candidate.
- 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.