drivers/dma/dw-edma/dw-edma-v0-core.c
Source file repositories/reference/linux-study-clean/drivers/dma/dw-edma/dw-edma-v0-core.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/dma/dw-edma/dw-edma-v0-core.c- Extension
.c- Size
- 13595 bytes
- Lines
- 547
- 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.
- 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.
- 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-edma-v0-core.hdw-edma-v0-regs.hdw-edma-v0-debugfs.h
Detected Declarations
enum dw_edma_controlfunction __dw_ch_regsfunction writel_chfunction readl_chfunction dw_edma_v0_core_offfunction dw_edma_v0_core_ch_countfunction dw_edma_v0_core_ch_statusfunction dw_edma_v0_core_clear_done_intfunction dw_edma_v0_core_clear_abort_intfunction dw_edma_v0_core_status_done_intfunction dw_edma_v0_core_status_abort_intfunction dw_edma_v0_core_handle_intfunction dw_edma_v0_write_ll_datafunction dw_edma_v0_write_ll_linkfunction dw_edma_v0_core_write_chunkfunction dw_edma_v0_sync_ll_datafunction dw_edma_v0_core_startfunction dw_edma_v0_core_ch_configfunction dw_edma_v0_core_debugfs_onfunction dw_edma_v0_core_ack_emulated_irqfunction dw_edma_v0_core_db_offsetfunction dw_edma_v0_core_register
Annotated Snippet
if (!j) {
control |= DW_EDMA_V0_LIE;
if (!(chan->dw->chip->flags & DW_EDMA_CHIP_LOCAL))
control |= DW_EDMA_V0_RIE;
}
dw_edma_v0_write_ll_data(chunk, i++, control, child->sz,
child->sar, child->dar);
}
control = DW_EDMA_V0_LLP | DW_EDMA_V0_TCB;
if (!chunk->cb)
control |= DW_EDMA_V0_CB;
dw_edma_v0_write_ll_link(chunk, i, control, chunk->ll_region.paddr);
}
static void dw_edma_v0_sync_ll_data(struct dw_edma_chunk *chunk)
{
/*
* In case of remote eDMA 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);
}
static void dw_edma_v0_core_start(struct dw_edma_chunk *chunk, bool first)
{
struct dw_edma_chan *chan = chunk->chan;
struct dw_edma *dw = chan->dw;
u32 tmp;
dw_edma_v0_core_write_chunk(chunk);
if (first) {
/* Enable engine */
SET_RW_32(dw, chan->dir, engine_en, BIT(0));
if (dw->chip->mf == EDMA_MF_HDMA_COMPAT) {
switch (chan->id) {
case 0:
SET_RW_COMPAT(dw, chan->dir, ch0_pwr_en,
BIT(0));
break;
case 1:
SET_RW_COMPAT(dw, chan->dir, ch1_pwr_en,
BIT(0));
break;
case 2:
SET_RW_COMPAT(dw, chan->dir, ch2_pwr_en,
BIT(0));
break;
case 3:
SET_RW_COMPAT(dw, chan->dir, ch3_pwr_en,
BIT(0));
break;
case 4:
SET_RW_COMPAT(dw, chan->dir, ch4_pwr_en,
BIT(0));
break;
case 5:
SET_RW_COMPAT(dw, chan->dir, ch5_pwr_en,
BIT(0));
break;
case 6:
SET_RW_COMPAT(dw, chan->dir, ch6_pwr_en,
BIT(0));
break;
case 7:
SET_RW_COMPAT(dw, chan->dir, ch7_pwr_en,
BIT(0));
break;
}
}
/* Interrupt unmask - done, abort */
tmp = GET_RW_32(dw, chan->dir, int_mask);
tmp &= ~FIELD_PREP(EDMA_V0_DONE_INT_MASK, BIT(chan->id));
tmp &= ~FIELD_PREP(EDMA_V0_ABORT_INT_MASK, BIT(chan->id));
SET_RW_32(dw, chan->dir, int_mask, tmp);
/* Linked list error */
tmp = GET_RW_32(dw, chan->dir, linked_list_err_en);
tmp |= FIELD_PREP(EDMA_V0_LINKED_LIST_ERR_MASK, BIT(chan->id));
SET_RW_32(dw, chan->dir, linked_list_err_en, tmp);
/* Channel control */
SET_CH_32(dw, chan->dir, chan->id, ch_control1,
(DW_EDMA_V0_CCS | DW_EDMA_V0_LLE));
Annotation
- Immediate include surface: `linux/bitfield.h`, `linux/irqreturn.h`, `linux/io-64-nonatomic-lo-hi.h`, `dw-edma-core.h`, `dw-edma-v0-core.h`, `dw-edma-v0-regs.h`, `dw-edma-v0-debugfs.h`.
- Detected declarations: `enum dw_edma_control`, `function __dw_ch_regs`, `function writel_ch`, `function readl_ch`, `function dw_edma_v0_core_off`, `function dw_edma_v0_core_ch_count`, `function dw_edma_v0_core_ch_status`, `function dw_edma_v0_core_clear_done_int`, `function dw_edma_v0_core_clear_abort_int`, `function dw_edma_v0_core_status_done_int`.
- Atlas domain: Driver Families / drivers/dma.
- 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.