drivers/mmc/host/moxart-mmc.c

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

File Facts

System
Linux kernel
Corpus path
drivers/mmc/host/moxart-mmc.c
Extension
.c
Size
17808 bytes
Lines
723
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 moxart_host {
	spinlock_t			lock;

	void __iomem			*base;

	phys_addr_t			reg_phys;

	struct dma_chan			*dma_chan_tx;
	struct dma_chan                 *dma_chan_rx;
	struct dma_async_tx_descriptor	*tx_desc;
	struct mmc_host			*mmc;
	struct mmc_request		*mrq;
	struct scatterlist		*cur_sg;
	struct completion		dma_complete;
	struct completion		pio_complete;

	u32				num_sg;
	u32				data_remain;
	u32				data_len;
	u32				fifo_width;
	u32				timeout;
	u32				rate;

	long				sysclk;

	bool				have_dma;
	bool				is_removed;
};

static inline void moxart_init_sg(struct moxart_host *host,
				  struct mmc_data *data)
{
	host->cur_sg = data->sg;
	host->num_sg = data->sg_len;
	host->data_remain = host->cur_sg->length;

	if (host->data_remain > host->data_len)
		host->data_remain = host->data_len;
}

static inline int moxart_next_sg(struct moxart_host *host)
{
	int remain;
	struct mmc_data *data = host->mrq->cmd->data;

	host->cur_sg++;
	host->num_sg--;

	if (host->num_sg > 0) {
		host->data_remain = host->cur_sg->length;
		remain = host->data_len - data->bytes_xfered;
		if (remain > 0 && remain < host->data_remain)
			host->data_remain = remain;
	}

	return host->num_sg;
}

static int moxart_wait_for_status(struct moxart_host *host,
				  u32 mask, u32 *status)
{
	int ret = -ETIMEDOUT;
	u32 i;

	for (i = 0; i < MAX_RETRIES; i++) {
		*status = readl(host->base + REG_STATUS);
		if (!(*status & mask)) {
			udelay(5);
			continue;
		}
		writel(*status & mask, host->base + REG_CLEAR);
		ret = 0;
		break;
	}

	if (ret)
		dev_err(mmc_dev(host->mmc), "timed out waiting for status\n");

	return ret;
}


static void moxart_send_command(struct moxart_host *host,
	struct mmc_command *cmd)
{
	u32 status, cmdctrl;

	writel(RSP_TIMEOUT  | RSP_CRC_OK |
	       RSP_CRC_FAIL | CMD_SENT, host->base + REG_CLEAR);
	writel(cmd->arg, host->base + REG_ARGUMENT);

Annotation

Implementation Notes