drivers/mmc/core/mmc_ops.c

Source file repositories/reference/linux-study-clean/drivers/mmc/core/mmc_ops.c

File Facts

System
Linux kernel
Corpus path
drivers/mmc/core/mmc_ops.c
Extension
.c
Size
27872 bytes
Lines
1152
Domain
Driver Families
Bucket
drivers/mmc
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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 mmc_busy_data {
	struct mmc_card *card;
	bool retry_crc_err;
	enum mmc_busy_cmd busy_cmd;
};

struct mmc_op_cond_busy_data {
	struct mmc_host *host;
	u32 ocr;
	struct mmc_command *cmd;
};

int __mmc_send_status(struct mmc_card *card, u32 *status, unsigned int retries)
{
	int err;
	struct mmc_command cmd = {};

	cmd.opcode = MMC_SEND_STATUS;
	if (!mmc_host_is_spi(card->host))
		cmd.arg = card->rca << 16;
	cmd.flags = MMC_RSP_SPI_R2 | MMC_RSP_R1 | MMC_CMD_AC;

	err = mmc_wait_for_cmd(card->host, &cmd, retries);
	if (err)
		return err;

	/* NOTE: callers are required to understand the difference
	 * between "native" and SPI format status words!
	 */
	if (status)
		*status = cmd.resp[0];

	return 0;
}
EXPORT_SYMBOL_GPL(__mmc_send_status);

int mmc_send_status(struct mmc_card *card, u32 *status)
{
	return __mmc_send_status(card, status, MMC_CMD_RETRIES);
}
EXPORT_SYMBOL_GPL(mmc_send_status);

static int _mmc_select_card(struct mmc_host *host, struct mmc_card *card)
{
	struct mmc_command cmd = {};

	cmd.opcode = MMC_SELECT_CARD;

	if (card) {
		cmd.arg = card->rca << 16;
		cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
	} else {
		cmd.arg = 0;
		cmd.flags = MMC_RSP_NONE | MMC_CMD_AC;
	}

	return mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES);
}

int mmc_select_card(struct mmc_card *card)
{

	return _mmc_select_card(card->host, card);
}

int mmc_deselect_cards(struct mmc_host *host)
{
	return _mmc_select_card(host, NULL);
}

/*
 * Write the value specified in the device tree or board code into the optional
 * 16 bit Driver Stage Register. This can be used to tune raise/fall times and
 * drive strength of the DAT and CMD outputs. The actual meaning of a given
 * value is hardware dependant.
 * The presence of the DSR register can be determined from the CSD register,
 * bit 76.
 */
int mmc_set_dsr(struct mmc_host *host)
{
	struct mmc_command cmd = {};

	cmd.opcode = MMC_SET_DSR;

	cmd.arg = (host->dsr << 16) | 0xffff;
	cmd.flags = MMC_RSP_NONE | MMC_CMD_AC;

	return mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES);
}

Annotation

Implementation Notes