drivers/mmc/host/sdricoh_cs.c

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

File Facts

System
Linux kernel
Corpus path
drivers/mmc/host/sdricoh_cs.c
Extension
.c
Size
13227 bytes
Lines
525
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 sdricoh_host {
	struct device *dev;
	struct mmc_host *mmc;	/* MMC structure */
	unsigned char __iomem *iobase;
	struct pci_dev *pci_dev;
	int app_cmd;
};

/***************** register i/o helper functions *****************************/

static inline unsigned int sdricoh_readl(struct sdricoh_host *host,
					 unsigned int reg)
{
	unsigned int value = readl(host->iobase + reg);
	dev_vdbg(host->dev, "rl %x 0x%x\n", reg, value);
	return value;
}

static inline void sdricoh_writel(struct sdricoh_host *host, unsigned int reg,
				  unsigned int value)
{
	writel(value, host->iobase + reg);
	dev_vdbg(host->dev, "wl %x 0x%x\n", reg, value);

}

static inline void sdricoh_writew(struct sdricoh_host *host, unsigned int reg,
					 unsigned short value)
{
	writew(value, host->iobase + reg);
	dev_vdbg(host->dev, "ww %x 0x%x\n", reg, value);
}

static inline unsigned int sdricoh_readb(struct sdricoh_host *host,
					 unsigned int reg)
{
	unsigned int value = readb(host->iobase + reg);
	dev_vdbg(host->dev, "rb %x 0x%x\n", reg, value);
	return value;
}

static bool sdricoh_status_ok(struct sdricoh_host *host, unsigned int status,
			      unsigned int wanted)
{
	sdricoh_writel(host, R2E4_STATUS_RESP, status);
	return status & wanted;
}

static int sdricoh_query_status(struct sdricoh_host *host, unsigned int wanted)
{
	int ret;
	unsigned int status = 0;
	struct device *dev = host->dev;

	ret = read_poll_timeout(sdricoh_readl, status,
				sdricoh_status_ok(host, status, wanted),
				32, SDRICOH_DATA_TIMEOUT_US, false,
				host, R21C_STATUS);
	if (ret) {
		dev_err(dev, "query_status: timeout waiting for %x\n", wanted);
		return -ETIMEDOUT;
	}

	/* do not do this check in the loop as some commands fail otherwise */
	if (status & 0x7F0000) {
		dev_err(dev, "waiting for status bit %x failed\n", wanted);
		return -EINVAL;
	}
	return 0;

}

static int sdricoh_mmc_cmd(struct sdricoh_host *host, struct mmc_command *cmd)
{
	unsigned int status, timeout_us;
	int ret;
	unsigned char opcode = cmd->opcode;

	/* reset status reg? */
	sdricoh_writel(host, R21C_STATUS, 0x18);

	/* MMC_APP_CMDs need some special handling */
	if (host->app_cmd) {
		opcode |= 64;
		host->app_cmd = 0;
	} else if (opcode == MMC_APP_CMD)
		host->app_cmd = 1;

	/* fill parameters */
	sdricoh_writel(host, R204_CMD_ARG, cmd->arg);

Annotation

Implementation Notes