drivers/mmc/host/sdhci-sprd.c
Source file repositories/reference/linux-study-clean/drivers/mmc/host/sdhci-sprd.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/mmc/host/sdhci-sprd.c- Extension
.c- Size
- 25800 bytes
- Lines
- 973
- 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.
- 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.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/delay.hlinux/dma-mapping.hlinux/highmem.hlinux/iopoll.hlinux/mmc/host.hlinux/mmc/mmc.hlinux/module.hlinux/of.hlinux/pinctrl/consumer.hlinux/platform_device.hlinux/pm_runtime.hlinux/regulator/consumer.hlinux/slab.hsdhci-pltfm.hmmc_hsq.h
Detected Declarations
struct sdhci_sprd_hoststruct sdhci_sprd_phy_cfgenum sdhci_sprd_tuning_typefunction sdhci_sprd_init_configfunction sdhci_sprd_readlfunction sdhci_sprd_writelfunction sdhci_sprd_writewfunction sdhci_sprd_writebfunction sdhci_sprd_sd_clk_offfunction sdhci_sprd_sd_clk_onfunction sdhci_sprd_set_dll_invertfunction sdhci_sprd_calc_divfunction _sdhci_sprd_set_clockfunction sdhci_sprd_enable_phy_dllfunction sdhci_sprd_set_clockfunction sdhci_sprd_get_max_clockfunction sdhci_sprd_get_min_clockfunction sdhci_sprd_set_uhs_signalingfunction sdhci_sprd_hw_resetfunction sdhci_sprd_get_max_timeout_countfunction sdhci_sprd_get_rofunction sdhci_sprd_request_donefunction sdhci_sprd_set_powerfunction sdhci_sprd_check_auto_cmd23function sdhci_sprd_requestfunction sdhci_sprd_request_atomicfunction sdhci_sprd_voltage_switchfunction sdhci_sprd_hs400_enhanced_strobefunction mmc_send_tuning_cmdfunction mmc_send_tuning_datafunction sdhci_sprd_get_best_clk_samplefunction sdhci_sprd_tuningfunction sdhci_sprd_prepare_sd_hs_cmd_tuningfunction sdhci_sprd_execute_sd_hs_data_tuningfunction sdhci_sprd_phy_param_parsefunction sdhci_sprd_probefunction sdhci_sprd_removefunction sdhci_sprd_runtime_suspendfunction sdhci_sprd_runtime_resume
Annotated Snippet
struct sdhci_sprd_host {
u32 version;
struct clk *clk_sdio;
struct clk *clk_enable;
struct clk *clk_2x_enable;
struct pinctrl *pinctrl;
struct pinctrl_state *pins_uhs;
struct pinctrl_state *pins_default;
u32 base_rate;
int flags; /* backup of host attribute */
u32 phy_delay[MMC_TIMING_MMC_HS400 + 2];
};
enum sdhci_sprd_tuning_type {
SDHCI_SPRD_TUNING_SD_HS_CMD,
SDHCI_SPRD_TUNING_SD_HS_DATA,
};
struct sdhci_sprd_phy_cfg {
const char *property;
u8 timing;
};
static const struct sdhci_sprd_phy_cfg sdhci_sprd_phy_cfgs[] = {
{ "sprd,phy-delay-legacy", MMC_TIMING_LEGACY, },
{ "sprd,phy-delay-sd-highspeed", MMC_TIMING_SD_HS, },
{ "sprd,phy-delay-sd-uhs-sdr50", MMC_TIMING_UHS_SDR50, },
{ "sprd,phy-delay-sd-uhs-sdr104", MMC_TIMING_UHS_SDR104, },
{ "sprd,phy-delay-mmc-highspeed", MMC_TIMING_MMC_HS, },
{ "sprd,phy-delay-mmc-ddr52", MMC_TIMING_MMC_DDR52, },
{ "sprd,phy-delay-mmc-hs200", MMC_TIMING_MMC_HS200, },
{ "sprd,phy-delay-mmc-hs400", MMC_TIMING_MMC_HS400, },
{ "sprd,phy-delay-mmc-hs400es", MMC_TIMING_MMC_HS400 + 1, },
};
#define TO_SPRD_HOST(host) sdhci_pltfm_priv(sdhci_priv(host))
static void sdhci_sprd_init_config(struct sdhci_host *host)
{
u16 val;
/* set dll backup mode */
val = sdhci_readl(host, SDHCI_SPRD_REG_DEBOUNCE);
val |= SDHCI_SPRD_BIT_DLL_BAK | SDHCI_SPRD_BIT_DLL_VAL;
sdhci_writel(host, val, SDHCI_SPRD_REG_DEBOUNCE);
}
static inline u32 sdhci_sprd_readl(struct sdhci_host *host, int reg)
{
if (unlikely(reg == SDHCI_MAX_CURRENT))
return SDHCI_SPRD_MAX_CUR;
return readl_relaxed(host->ioaddr + reg);
}
static inline void sdhci_sprd_writel(struct sdhci_host *host, u32 val, int reg)
{
/* SDHCI_MAX_CURRENT is reserved on Spreadtrum's platform */
if (unlikely(reg == SDHCI_MAX_CURRENT))
return;
if (unlikely(reg == SDHCI_SIGNAL_ENABLE || reg == SDHCI_INT_ENABLE))
val = val & SDHCI_SPRD_INT_SIGNAL_MASK;
writel_relaxed(val, host->ioaddr + reg);
}
static inline void sdhci_sprd_writew(struct sdhci_host *host, u16 val, int reg)
{
/* SDHCI_BLOCK_COUNT is Read Only on Spreadtrum's platform */
if (unlikely(reg == SDHCI_BLOCK_COUNT))
return;
writew_relaxed(val, host->ioaddr + reg);
}
static inline void sdhci_sprd_writeb(struct sdhci_host *host, u8 val, int reg)
{
/*
* Since BIT(3) of SDHCI_SOFTWARE_RESET is reserved according to the
* standard specification, sdhci_reset() write this register directly
* without checking other reserved bits, that will clear BIT(3) which
* is defined as hardware reset on Spreadtrum's platform and clearing
* it by mistake will lead the card not work. So here we need to work
* around it.
*/
if (unlikely(reg == SDHCI_SOFTWARE_RESET)) {
if (readb_relaxed(host->ioaddr + reg) & SDHCI_HW_RESET_CARD)
val |= SDHCI_HW_RESET_CARD;
}
Annotation
- Immediate include surface: `linux/delay.h`, `linux/dma-mapping.h`, `linux/highmem.h`, `linux/iopoll.h`, `linux/mmc/host.h`, `linux/mmc/mmc.h`, `linux/module.h`, `linux/of.h`.
- Detected declarations: `struct sdhci_sprd_host`, `struct sdhci_sprd_phy_cfg`, `enum sdhci_sprd_tuning_type`, `function sdhci_sprd_init_config`, `function sdhci_sprd_readl`, `function sdhci_sprd_writel`, `function sdhci_sprd_writew`, `function sdhci_sprd_writeb`, `function sdhci_sprd_sd_clk_off`, `function sdhci_sprd_sd_clk_on`.
- Atlas domain: Driver Families / drivers/mmc.
- Implementation status: source implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.