drivers/mmc/host/jz4740_mmc.c

Source file repositories/reference/linux-study-clean/drivers/mmc/host/jz4740_mmc.c

File Facts

System
Linux kernel
Corpus path
drivers/mmc/host/jz4740_mmc.c
Extension
.c
Size
30845 bytes
Lines
1195
Domain
Driver Families
Bucket
drivers/mmc
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 jz4740_mmc_host {
	struct mmc_host *mmc;
	struct platform_device *pdev;
	struct clk *clk;

	enum jz4740_mmc_version version;

	int irq;

	void __iomem *base;
	struct resource *mem_res;
	struct mmc_request *req;
	struct mmc_command *cmd;

	bool vqmmc_enabled;

	unsigned long waiting;

	uint32_t cmdat;

	uint32_t irq_mask;

	spinlock_t lock;

	struct timer_list timeout_timer;
	struct sg_mapping_iter miter;
	enum jz4740_mmc_state state;

	/* DMA support */
	struct dma_chan *dma_rx;
	struct dma_chan *dma_tx;
	bool use_dma;

/* The DMA trigger level is 8 words, that is to say, the DMA read
 * trigger is when data words in MSC_RXFIFO is >= 8 and the DMA write
 * trigger is when data words in MSC_TXFIFO is < 8.
 */
#define JZ4740_MMC_FIFO_HALF_SIZE 8
};

static void jz4740_mmc_write_irq_mask(struct jz4740_mmc_host *host,
				      uint32_t val)
{
	if (host->version >= JZ_MMC_JZ4725B)
		return writel(val, host->base + JZ_REG_MMC_IMASK);
	else
		return writew(val, host->base + JZ_REG_MMC_IMASK);
}

static void jz4740_mmc_write_irq_reg(struct jz4740_mmc_host *host,
				     uint32_t val)
{
	if (host->version >= JZ_MMC_JZ4780)
		writel(val, host->base + JZ_REG_MMC_IREG);
	else
		writew(val, host->base + JZ_REG_MMC_IREG);
}

static uint32_t jz4740_mmc_read_irq_reg(struct jz4740_mmc_host *host)
{
	if (host->version >= JZ_MMC_JZ4780)
		return readl(host->base + JZ_REG_MMC_IREG);
	else
		return readw(host->base + JZ_REG_MMC_IREG);
}

/*----------------------------------------------------------------------------*/
/* DMA infrastructure */

static void jz4740_mmc_release_dma_channels(struct jz4740_mmc_host *host)
{
	if (!host->use_dma)
		return;

	dma_release_channel(host->dma_tx);
	if (host->dma_rx)
		dma_release_channel(host->dma_rx);
}

static int jz4740_mmc_acquire_dma_channels(struct jz4740_mmc_host *host)
{
	struct device *dev = mmc_dev(host->mmc);

	host->dma_tx = dma_request_chan(dev, "tx-rx");
	if (!IS_ERR(host->dma_tx))
		return 0;

	if (PTR_ERR(host->dma_tx) != -ENODEV) {
		dev_err(dev, "Failed to get dma tx-rx channel\n");
		return PTR_ERR(host->dma_tx);

Annotation

Implementation Notes