drivers/dma/sprd-dma.c

Source file repositories/reference/linux-study-clean/drivers/dma/sprd-dma.c

File Facts

System
Linux kernel
Corpus path
drivers/dma/sprd-dma.c
Extension
.c
Size
35921 bytes
Lines
1314
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 sprd_dma_chn_hw {
	u32 pause;
	u32 req;
	u32 cfg;
	u32 intc;
	u32 src_addr;
	u32 des_addr;
	u32 frg_len;
	u32 blk_len;
	u32 trsc_len;
	u32 trsf_step;
	u32 wrap_ptr;
	u32 wrap_to;
	u32 llist_ptr;
	u32 frg_step;
	u32 src_blk_step;
	u32 des_blk_step;
};

/* dma request description */
struct sprd_dma_desc {
	struct virt_dma_desc	vd;
	struct sprd_dma_chn_hw	chn_hw;
	enum dma_transfer_direction dir;
};

/* dma channel description */
struct sprd_dma_chn {
	struct virt_dma_chan	vc;
	void __iomem		*chn_base;
	struct sprd_dma_linklist	linklist;
	struct dma_slave_config	slave_cfg;
	u32			chn_num;
	u32			dev_id;
	enum sprd_dma_chn_mode	chn_mode;
	enum sprd_dma_trg_mode	trg_mode;
	enum sprd_dma_int_type	int_type;
	struct sprd_dma_desc	*cur_desc;
};

/* SPRD dma device */
struct sprd_dma_dev {
	struct dma_device	dma_dev;
	void __iomem		*glb_base;
	struct clk		*clk;
	struct clk		*ashb_clk;
	int			irq;
	u32			total_chns;
	struct sprd_dma_chn	channels[] __counted_by(total_chns);
};

static void sprd_dma_free_desc(struct virt_dma_desc *vd);
static bool sprd_dma_filter_fn(struct dma_chan *chan, void *param);
static struct of_dma_filter_info sprd_dma_info = {
	.filter_fn = sprd_dma_filter_fn,
};

static inline struct sprd_dma_chn *to_sprd_dma_chan(struct dma_chan *c)
{
	return container_of(c, struct sprd_dma_chn, vc.chan);
}

static inline struct sprd_dma_dev *to_sprd_dma_dev(struct dma_chan *c)
{
	struct sprd_dma_chn *schan = to_sprd_dma_chan(c);

	return container_of(schan, struct sprd_dma_dev, channels[c->chan_id]);
}

static inline struct sprd_dma_desc *to_sprd_dma_desc(struct virt_dma_desc *vd)
{
	return container_of(vd, struct sprd_dma_desc, vd);
}

static void sprd_dma_glb_update(struct sprd_dma_dev *sdev, u32 reg,
				u32 mask, u32 val)
{
	u32 orig = readl(sdev->glb_base + reg);
	u32 tmp;

	tmp = (orig & ~mask) | val;
	writel(tmp, sdev->glb_base + reg);
}

static void sprd_dma_chn_update(struct sprd_dma_chn *schan, u32 reg,
				u32 mask, u32 val)
{
	u32 orig = readl(schan->chn_base + reg);
	u32 tmp;

Annotation

Implementation Notes