drivers/dma/dw-edma/dw-edma-v0-debugfs.c

Source file repositories/reference/linux-study-clean/drivers/dma/dw-edma/dw-edma-v0-debugfs.c

File Facts

System
Linux kernel
Corpus path
drivers/dma/dw-edma/dw-edma-v0-debugfs.c
Extension
.c
Size
8715 bytes
Lines
293
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.

Dependency Surface

Detected Declarations

Annotated Snippet

struct dw_edma_debugfs_entry {
	struct dw_edma				*dw;
	const char				*name;
	void __iomem				*reg;
	enum dw_edma_dir			dir;
	u16					ch;
};

static int dw_edma_debugfs_u32_get(void *data, u64 *val)
{
	struct dw_edma_debugfs_entry *entry = data;
	struct dw_edma *dw = entry->dw;
	void __iomem *reg = entry->reg;

	if (dw->chip->mf == EDMA_MF_EDMA_LEGACY &&
	    reg >= REGS_ADDR(dw, type.legacy.ch)) {
		unsigned long flags;
		u32 viewport_sel;

		viewport_sel = entry->dir == EDMA_DIR_READ ? BIT(31) : 0;
		viewport_sel |= FIELD_PREP(EDMA_V0_VIEWPORT_MASK, entry->ch);

		raw_spin_lock_irqsave(&dw->lock, flags);

		writel(viewport_sel, REGS_ADDR(dw, type.legacy.viewport_sel));
		*val = readl(reg);

		raw_spin_unlock_irqrestore(&dw->lock, flags);
	} else {
		*val = readl(reg);
	}

	return 0;
}
DEFINE_DEBUGFS_ATTRIBUTE(fops_x32, dw_edma_debugfs_u32_get, NULL, "0x%08llx\n");

static void dw_edma_debugfs_create_x32(struct dw_edma *dw,
				       const struct dw_edma_debugfs_entry ini[],
				       int nr_entries, struct dentry *dent)
{
	struct dw_edma_debugfs_entry *entries;
	int i;

	entries = devm_kcalloc(dw->chip->dev, nr_entries, sizeof(*entries),
			       GFP_KERNEL);
	if (!entries)
		return;

	for (i = 0; i < nr_entries; i++) {
		entries[i] = ini[i];

		debugfs_create_file_unsafe(entries[i].name, 0444, dent,
					   &entries[i], &fops_x32);
	}
}

static void dw_edma_debugfs_regs_ch(struct dw_edma *dw, enum dw_edma_dir dir,
				    u16 ch, struct dentry *dent)
{
	struct dw_edma_debugfs_entry debugfs_regs[] = {
		CTX_REGISTER(dw, ch_control1, dir, ch),
		CTX_REGISTER(dw, ch_control2, dir, ch),
		CTX_REGISTER(dw, transfer_size, dir, ch),
		CTX_REGISTER(dw, sar.lsb, dir, ch),
		CTX_REGISTER(dw, sar.msb, dir, ch),
		CTX_REGISTER(dw, dar.lsb, dir, ch),
		CTX_REGISTER(dw, dar.msb, dir, ch),
		CTX_REGISTER(dw, llp.lsb, dir, ch),
		CTX_REGISTER(dw, llp.msb, dir, ch),
	};
	int nr_entries;

	nr_entries = ARRAY_SIZE(debugfs_regs);
	dw_edma_debugfs_create_x32(dw, debugfs_regs, nr_entries, dent);
}

static noinline_for_stack void
dw_edma_debugfs_regs_wr(struct dw_edma *dw, struct dentry *dent)
{
	const struct dw_edma_debugfs_entry debugfs_regs[] = {
		/* eDMA global registers */
		WR_REGISTER(dw, engine_en),
		WR_REGISTER(dw, doorbell),
		WR_REGISTER(dw, ch_arb_weight.lsb),
		WR_REGISTER(dw, ch_arb_weight.msb),
		/* eDMA interrupts registers */
		WR_REGISTER(dw, int_status),
		WR_REGISTER(dw, int_mask),
		WR_REGISTER(dw, int_clear),
		WR_REGISTER(dw, err_status),

Annotation

Implementation Notes