drivers/mmc/host/rtsx_pci_sdmmc.c

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

File Facts

System
Linux kernel
Corpus path
drivers/mmc/host/rtsx_pci_sdmmc.c
Extension
.c
Size
39479 bytes
Lines
1566
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 realtek_pci_sdmmc {
	struct platform_device	*pdev;
	struct rtsx_pcr		*pcr;
	struct mmc_host		*mmc;
	struct mmc_request	*mrq;
#define SDMMC_WORKQ_NAME	"rtsx_pci_sdmmc_workq"

	struct work_struct	work;
	struct mutex		host_mutex;

	u8			ssc_depth;
	unsigned int		clock;
	bool			vpclk;
	bool			double_clk;
	bool			eject;
	bool			initial_mode;
	int			prev_power_state;
	int			sg_count;
	s32			cookie;
	int			cookie_sg_count;
	bool			using_cookie;
};

static int sdmmc_init_sd_express(struct mmc_host *mmc, struct mmc_ios *ios);

static inline struct device *sdmmc_dev(struct realtek_pci_sdmmc *host)
{
	return &(host->pdev->dev);
}

static inline void sd_clear_error(struct realtek_pci_sdmmc *host)
{
	rtsx_pci_write_register(host->pcr, CARD_STOP,
			SD_STOP | SD_CLR_ERR, SD_STOP | SD_CLR_ERR);
}

#ifdef DEBUG
static void dump_reg_range(struct realtek_pci_sdmmc *host, u16 start, u16 end)
{
	u16 len = end - start + 1;
	int i;
	u8 data[8];

	for (i = 0; i < len; i += 8) {
		int j;
		int n = min(8, len - i);

		memset(&data, 0, sizeof(data));
		for (j = 0; j < n; j++)
			rtsx_pci_read_register(host->pcr, start + i + j,
				data + j);
		dev_dbg(sdmmc_dev(host), "0x%04X(%d): %8ph\n",
			start + i, n, data);
	}
}

static void sd_print_debug_regs(struct realtek_pci_sdmmc *host)
{
	dump_reg_range(host, 0xFDA0, 0xFDB3);
	dump_reg_range(host, 0xFD52, 0xFD69);
}
#else
#define sd_print_debug_regs(host)
#endif /* DEBUG */

static inline int sd_get_cd_int(struct realtek_pci_sdmmc *host)
{
	return rtsx_pci_readl(host->pcr, RTSX_BIPR) & SD_EXIST;
}

static void sd_cmd_set_sd_cmd(struct rtsx_pcr *pcr, struct mmc_command *cmd)
{
	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_CMD0, 0xFF,
		SD_CMD_START | cmd->opcode);
	rtsx_pci_write_be32(pcr, SD_CMD1, cmd->arg);
}

static void sd_cmd_set_data_len(struct rtsx_pcr *pcr, u16 blocks, u16 blksz)
{
	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BLOCK_CNT_L, 0xFF, blocks);
	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BLOCK_CNT_H, 0xFF, blocks >> 8);
	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BYTE_CNT_L, 0xFF, blksz);
	rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, SD_BYTE_CNT_H, 0xFF, blksz >> 8);
}

static int sd_response_type(struct mmc_command *cmd)
{
	switch (mmc_resp_type(cmd)) {
	case MMC_RSP_NONE:
		return SD_RSP_TYPE_R0;

Annotation

Implementation Notes