drivers/dma/dw-edma/dw-edma-core.c
Source file repositories/reference/linux-study-clean/drivers/dma/dw-edma/dw-edma-core.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/dma/dw-edma/dw-edma-core.c- Extension
.c- Size
- 30105 bytes
- Lines
- 1195
- Domain
- Driver Families
- Bucket
- drivers/dma
- Inferred role
- Driver Families: exported/initcall integration point
- Status
- integration 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.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- 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/module.hlinux/device.hlinux/kernel.hlinux/dmaengine.hlinux/err.hlinux/interrupt.hlinux/irq.hlinux/dma/edma.hlinux/dma-mapping.hlinux/string_choices.hdw-edma-core.hdw-edma-v0-core.hdw-hdma-v0-core.h../dmaengine.h../virt-dma.h
Detected Declarations
function Copyrightfunction dw_edma_get_pci_addressfunction dw_edma_free_burstfunction dw_edma_free_chunkfunction dw_edma_free_descfunction vchan_free_descfunction dw_edma_start_transferfunction dw_edma_device_capsfunction dw_edma_device_configfunction dw_edma_device_pausefunction dw_edma_device_resumefunction dw_edma_device_terminate_allfunction dw_edma_device_issue_pendingfunction dw_edma_device_tx_statusfunction dw_edma_device_transferfunction operationsfunction portionfunction portionfunction dw_edma_device_prep_slave_sgfunction dw_edma_device_prep_dma_cyclicfunction dw_edma_device_prep_interleaved_dmafunction dw_hdma_set_callback_resultfunction dw_edma_done_interruptfunction dw_edma_abort_interruptfunction dw_edma_emul_irq_ackfunction dw_edma_emul_irq_allocfunction dw_edma_emul_irq_freefunction dw_edma_interrupt_emulatedfunction dw_edma_interrupt_write_innerfunction dw_edma_interrupt_read_innerfunction dw_edma_interrupt_writefunction dw_edma_interrupt_readfunction dw_edma_interrupt_commonfunction dw_edma_alloc_chan_resourcesfunction dw_edma_free_chan_resourcesfunction dw_edma_channel_setupfunction dw_edma_dec_irq_allocfunction dw_edma_add_irq_maskfunction dw_edma_irq_requestfunction dw_edma_probefunction dw_edma_removeexport dw_edma_probeexport dw_edma_remove
Annotated Snippet
if (!dw_edma_alloc_burst(chunk)) {
kfree(chunk);
return NULL;
}
desc->chunks_alloc++;
list_add_tail(&chunk->list, &desc->chunk->list);
} else {
/* List head */
chunk->burst = NULL;
desc->chunks_alloc = 0;
desc->chunk = chunk;
}
return chunk;
}
static struct dw_edma_desc *dw_edma_alloc_desc(struct dw_edma_chan *chan)
{
struct dw_edma_desc *desc;
desc = kzalloc_obj(*desc, GFP_NOWAIT);
if (unlikely(!desc))
return NULL;
desc->chan = chan;
if (!dw_edma_alloc_chunk(desc)) {
kfree(desc);
return NULL;
}
return desc;
}
static void dw_edma_free_burst(struct dw_edma_chunk *chunk)
{
struct dw_edma_burst *child, *_next;
/* Remove all the list elements */
list_for_each_entry_safe(child, _next, &chunk->burst->list, list) {
list_del(&child->list);
kfree(child);
chunk->bursts_alloc--;
}
/* Remove the list head */
kfree(child);
chunk->burst = NULL;
}
static void dw_edma_free_chunk(struct dw_edma_desc *desc)
{
struct dw_edma_chunk *child, *_next;
if (!desc->chunk)
return;
/* Remove all the list elements */
list_for_each_entry_safe(child, _next, &desc->chunk->list, list) {
dw_edma_free_burst(child);
list_del(&child->list);
kfree(child);
desc->chunks_alloc--;
}
/* Remove the list head */
kfree(child);
desc->chunk = NULL;
}
static void dw_edma_free_desc(struct dw_edma_desc *desc)
{
dw_edma_free_chunk(desc);
kfree(desc);
}
static void vchan_free_desc(struct virt_dma_desc *vdesc)
{
dw_edma_free_desc(vd2dw_edma_desc(vdesc));
}
static int dw_edma_start_transfer(struct dw_edma_chan *chan)
{
struct dw_edma *dw = chan->dw;
struct dw_edma_chunk *child;
struct dw_edma_desc *desc;
struct virt_dma_desc *vd;
vd = vchan_next_desc(&chan->vc);
if (!vd)
return 0;
Annotation
- Immediate include surface: `linux/module.h`, `linux/device.h`, `linux/kernel.h`, `linux/dmaengine.h`, `linux/err.h`, `linux/interrupt.h`, `linux/irq.h`, `linux/dma/edma.h`.
- Detected declarations: `function Copyright`, `function dw_edma_get_pci_address`, `function dw_edma_free_burst`, `function dw_edma_free_chunk`, `function dw_edma_free_desc`, `function vchan_free_desc`, `function dw_edma_start_transfer`, `function dw_edma_device_caps`, `function dw_edma_device_config`, `function dw_edma_device_pause`.
- Atlas domain: Driver Families / drivers/dma.
- Implementation status: integration 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.