drivers/mmc/host/sdhci-of-esdhc.c

Source file repositories/reference/linux-study-clean/drivers/mmc/host/sdhci-of-esdhc.c

File Facts

System
Linux kernel
Corpus path
drivers/mmc/host/sdhci-of-esdhc.c
Extension
.c
Size
41708 bytes
Lines
1522
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 esdhc_clk_fixup {
	const unsigned int sd_dflt_max_clk;
	const unsigned int max_clk[MMC_TIMING_NUM];
};

static const struct esdhc_clk_fixup ls1021a_esdhc_clk = {
	.sd_dflt_max_clk = 25000000,
	.max_clk[MMC_TIMING_MMC_HS] = 46500000,
	.max_clk[MMC_TIMING_SD_HS] = 46500000,
};

static const struct esdhc_clk_fixup ls1043a_esdhc_clk = {
	.sd_dflt_max_clk = 25000000,
	.max_clk[MMC_TIMING_UHS_SDR104] = 116700000,
	.max_clk[MMC_TIMING_MMC_HS200] = 116700000,
};

static const struct esdhc_clk_fixup ls1046a_esdhc_clk = {
	.sd_dflt_max_clk = 25000000,
	.max_clk[MMC_TIMING_UHS_SDR104] = 167000000,
	.max_clk[MMC_TIMING_MMC_HS200] = 167000000,
};

static const struct esdhc_clk_fixup ls1012a_esdhc_clk = {
	.sd_dflt_max_clk = 25000000,
	.max_clk[MMC_TIMING_UHS_SDR104] = 125000000,
	.max_clk[MMC_TIMING_MMC_HS200] = 125000000,
};

static const struct esdhc_clk_fixup p1010_esdhc_clk = {
	.sd_dflt_max_clk = 20000000,
	.max_clk[MMC_TIMING_LEGACY] = 20000000,
	.max_clk[MMC_TIMING_MMC_HS] = 42000000,
	.max_clk[MMC_TIMING_SD_HS] = 40000000,
};

static const struct of_device_id sdhci_esdhc_of_match[] = {
	{ .compatible = "fsl,ls1021a-esdhc", .data = &ls1021a_esdhc_clk},
	{ .compatible = "fsl,ls1043a-esdhc", .data = &ls1043a_esdhc_clk},
	{ .compatible = "fsl,ls1046a-esdhc", .data = &ls1046a_esdhc_clk},
	{ .compatible = "fsl,ls1012a-esdhc", .data = &ls1012a_esdhc_clk},
	{ .compatible = "fsl,p1010-esdhc",   .data = &p1010_esdhc_clk},
	{ .compatible = "fsl,mpc8379-esdhc" },
	{ .compatible = "fsl,mpc8536-esdhc" },
	{ .compatible = "fsl,esdhc" },
	{ }
};
MODULE_DEVICE_TABLE(of, sdhci_esdhc_of_match);

struct sdhci_esdhc {
	u8 vendor_ver;
	u8 spec_ver;
	bool quirk_incorrect_hostver;
	bool quirk_limited_clk_division;
	bool quirk_unreliable_pulse_detection;
	bool quirk_tuning_erratum_type1;
	bool quirk_tuning_erratum_type2;
	bool quirk_ignore_data_inhibit;
	bool quirk_delay_before_data_reset;
	bool quirk_trans_complete_erratum;
	bool in_sw_tuning;
	unsigned int peripheral_clock;
	const struct esdhc_clk_fixup *clk_fixup;
	u32 div_ratio;
};

/**
 * esdhc_readl_fixup - Fixup the value read from incompatible eSDHC register
 *		       to make it compatible with SD spec.
 *
 * @host: pointer to sdhci_host
 * @spec_reg: SD spec register address
 * @value: 32bit eSDHC register value on spec_reg address
 *
 * In SD spec, there are 8/16/32/64 bits registers, while all of eSDHC
 * registers are 32 bits. There are differences in register size, register
 * address, register function, bit position and function between eSDHC spec
 * and SD spec.
 *
 * Return a fixed up register value
 */
static u32 esdhc_readl_fixup(struct sdhci_host *host,
				     int spec_reg, u32 value)
{
	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
	struct sdhci_esdhc *esdhc = sdhci_pltfm_priv(pltfm_host);
	u32 ret;

	/*
	 * The bit of ADMA flag in eSDHC is not compatible with standard

Annotation

Implementation Notes