drivers/dma/xilinx/xilinx_dpdma.c
Source file repositories/reference/linux-study-clean/drivers/dma/xilinx/xilinx_dpdma.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/dma/xilinx/xilinx_dpdma.c- Extension
.c- Size
- 53659 bytes
- Lines
- 1878
- Domain
- Driver Families
- Bucket
- drivers/dma
- Inferred role
- Driver Families: operation-table or driver-model contract
- Status
- pattern 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.
- Defines an operation table; this is where Linux turns generic core objects into subsystem-specific behavior.
- Touches user memory; correctness depends on fault-safe copying and privilege boundary handling.
- 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/bitfield.hlinux/bits.hlinux/clk.hlinux/debugfs.hlinux/delay.hlinux/dma/xilinx_dpdma.hlinux/dmaengine.hlinux/dmapool.hlinux/interrupt.hlinux/module.hlinux/of.hlinux/of_dma.hlinux/platform_device.hlinux/sched.hlinux/slab.hlinux/spinlock.hlinux/wait.hdt-bindings/dma/xlnx-zynqmp-dpdma.h../dmaengine.h../virt-dma.h
Detected Declarations
struct xilinx_dpdma_chanstruct xilinx_dpdma_hw_descstruct xilinx_dpdma_sw_descstruct xilinx_dpdma_tx_descstruct xilinx_dpdma_chanstruct xilinx_dpdma_devicestruct xilinx_dpdma_debugfsstruct xilinx_dpdma_debugfs_requestenum xilinx_dpdma_testcasesfunction xilinx_dpdma_debugfs_desc_done_irqfunction xilinx_dpdma_debugfs_desc_done_irq_readfunction xilinx_dpdma_debugfs_desc_done_irq_writefunction xilinx_dpdma_debugfs_readfunction xilinx_dpdma_debugfs_writefunction xilinx_dpdma_debugfs_initfunction dpdma_readfunction dpdma_writefunction dpdma_clrfunction dpdma_setfunction xilinx_dpdma_sw_desc_set_dma_addrsfunction xilinx_dpdma_chan_alloc_sw_descfunction xilinx_dpdma_chan_free_sw_descfunction xilinx_dpdma_chan_dump_tx_descfunction list_for_each_entryfunction xilinx_dpdma_chan_alloc_tx_descfunction xilinx_dpdma_chan_free_tx_descfunction list_for_each_entry_safefunction xilinx_dpdma_chan_prep_cyclicfunction xilinx_dpdma_chan_prep_interleaved_dmafunction xilinx_dpdma_chan_enablefunction xilinx_dpdma_chan_disablefunction xilinx_dpdma_chan_pausefunction xilinx_dpdma_chan_unpausefunction xilinx_dpdma_chan_video_group_readyfunction xilinx_dpdma_chan_queue_transferfunction xilinx_dpdma_chan_ostandfunction transactionfunction wait_event_interruptible_timeoutfunction xilinx_dpdma_chan_poll_no_ostandfunction xilinx_dpdma_chan_stopfunction descriptorfunction xilinx_dpdma_chan_vsync_irqfunction xilinx_dpdma_chan_errfunction xilinx_dpdma_chan_handle_errfunction list_emptyfunction xilinx_dpdma_prep_dma_cyclicfunction xilinx_dpdma_prep_interleaved_dmafunction xilinx_dpdma_alloc_chan_resources
Annotated Snippet
static const struct file_operations fops_xilinx_dpdma_dbgfs = {
.owner = THIS_MODULE,
.read = xilinx_dpdma_debugfs_read,
.write = xilinx_dpdma_debugfs_write,
};
static void xilinx_dpdma_debugfs_init(struct xilinx_dpdma_device *xdev)
{
struct dentry *dent;
dpdma_debugfs.testcase = DPDMA_TC_NONE;
dent = debugfs_create_file("testcase", 0444, xdev->common.dbg_dev_root,
NULL, &fops_xilinx_dpdma_dbgfs);
if (IS_ERR(dent))
dev_err(xdev->dev, "Failed to create debugfs testcase file\n");
}
/* -----------------------------------------------------------------------------
* I/O Accessors
*/
static inline u32 dpdma_read(void __iomem *base, u32 offset)
{
return ioread32(base + offset);
}
static inline void dpdma_write(void __iomem *base, u32 offset, u32 val)
{
iowrite32(val, base + offset);
}
static inline void dpdma_clr(void __iomem *base, u32 offset, u32 clr)
{
dpdma_write(base, offset, dpdma_read(base, offset) & ~clr);
}
static inline void dpdma_set(void __iomem *base, u32 offset, u32 set)
{
dpdma_write(base, offset, dpdma_read(base, offset) | set);
}
/* -----------------------------------------------------------------------------
* Descriptor Operations
*/
/**
* xilinx_dpdma_sw_desc_set_dma_addrs - Set DMA addresses in the descriptor
* @xdev: DPDMA device
* @sw_desc: The software descriptor in which to set DMA addresses
* @prev: The previous descriptor
* @dma_addr: array of dma addresses
* @num_src_addr: number of addresses in @dma_addr
*
* Set all the DMA addresses in the hardware descriptor corresponding to @dev
* from @dma_addr. If a previous descriptor is specified in @prev, its next
* descriptor DMA address is set to the DMA address of @sw_desc. @prev may be
* identical to @sw_desc for cyclic transfers.
*/
static void xilinx_dpdma_sw_desc_set_dma_addrs(struct xilinx_dpdma_device *xdev,
struct xilinx_dpdma_sw_desc *sw_desc,
struct xilinx_dpdma_sw_desc *prev,
dma_addr_t dma_addr[],
unsigned int num_src_addr)
{
struct xilinx_dpdma_hw_desc *hw_desc = &sw_desc->hw;
unsigned int i;
hw_desc->src_addr = lower_32_bits(dma_addr[0]);
if (xdev->ext_addr)
hw_desc->addr_ext |=
FIELD_PREP(XILINX_DPDMA_DESC_ADDR_EXT_SRC_ADDR_MASK,
upper_32_bits(dma_addr[0]));
for (i = 1; i < num_src_addr; i++) {
u32 *addr = &hw_desc->src_addr2;
addr[i - 1] = lower_32_bits(dma_addr[i]);
if (xdev->ext_addr) {
u32 *addr_ext = &hw_desc->addr_ext_23;
u32 addr_msb;
addr_msb = upper_32_bits(dma_addr[i]) & GENMASK(15, 0);
addr_msb <<= 16 * ((i - 1) % 2);
addr_ext[(i - 1) / 2] |= addr_msb;
}
}
if (!prev)
Annotation
- Immediate include surface: `linux/bitfield.h`, `linux/bits.h`, `linux/clk.h`, `linux/debugfs.h`, `linux/delay.h`, `linux/dma/xilinx_dpdma.h`, `linux/dmaengine.h`, `linux/dmapool.h`.
- Detected declarations: `struct xilinx_dpdma_chan`, `struct xilinx_dpdma_hw_desc`, `struct xilinx_dpdma_sw_desc`, `struct xilinx_dpdma_tx_desc`, `struct xilinx_dpdma_chan`, `struct xilinx_dpdma_device`, `struct xilinx_dpdma_debugfs`, `struct xilinx_dpdma_debugfs_request`, `enum xilinx_dpdma_testcases`, `function xilinx_dpdma_debugfs_desc_done_irq`.
- Atlas domain: Driver Families / drivers/dma.
- Implementation status: pattern implementation candidate.
- This snippet crosses the user/kernel memory boundary; validate fault handling and access checks before translating the pattern.
- 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.