drivers/mmc/host/sdhci-of-bst.c
Source file repositories/reference/linux-study-clean/drivers/mmc/host/sdhci-of-bst.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/mmc/host/sdhci-of-bst.c- Extension
.c- Size
- 15159 bytes
- Lines
- 524
- 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.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/bits.hlinux/bitfield.hlinux/delay.hlinux/dma-mapping.hlinux/iopoll.hlinux/module.hlinux/of.hlinux/of_reserved_mem.hlinux/platform_device.hsdhci.hsdhci-pltfm.h
Detected Declarations
struct sdhci_bst_privfunction sdhci_bst_crm_readfunction sdhci_bst_crm_writefunction sdhci_bst_wait_int_clkfunction sdhci_bst_get_max_clockfunction sdhci_bst_get_min_clockfunction sdhci_bst_enable_clkfunction sdhci_bst_set_clockfunction sdhci_bst_resetfunction sdhci_bst_set_timeoutfunction sdhci_bst_set_powerfunction sdhci_bst_execute_tuningfunction sdhci_bst_voltage_switchfunction sdhci_bst_free_bounce_bufferfunction sdhci_bst_alloc_bounce_bufferfunction sdhci_bst_probefunction sdhci_bst_remove
Annotated Snippet
struct sdhci_bst_priv {
void __iomem *crm_reg_base;
};
union sdhci_bst_rx_ctrl {
struct {
u32 rx_revert:1,
rx_clk_sel_sec:1,
rx_clk_div:4,
rx_clk_phase_inner:2,
rx_clk_sel_first:1,
rx_clk_phase_out:2,
rx_clk_en:1,
res0:20;
};
u32 reg;
};
static u32 sdhci_bst_crm_read(struct sdhci_pltfm_host *pltfm_host, u32 offset)
{
struct sdhci_bst_priv *priv = sdhci_pltfm_priv(pltfm_host);
return readl(priv->crm_reg_base + offset);
}
static void sdhci_bst_crm_write(struct sdhci_pltfm_host *pltfm_host, u32 offset, u32 value)
{
struct sdhci_bst_priv *priv = sdhci_pltfm_priv(pltfm_host);
writel(value, priv->crm_reg_base + offset);
}
static int sdhci_bst_wait_int_clk(struct sdhci_host *host)
{
u16 clk;
if (read_poll_timeout(sdhci_readw, clk, (clk & SDHCI_CLOCK_INT_STABLE),
BST_CLK_STABLE_POLL_US, BST_CLK_STABLE_TIMEOUT_US, false,
host, SDHCI_CLOCK_CONTROL))
return -EBUSY;
return 0;
}
static unsigned int sdhci_bst_get_max_clock(struct sdhci_host *host)
{
return BST_DEFAULT_MAX_FREQ;
}
static unsigned int sdhci_bst_get_min_clock(struct sdhci_host *host)
{
return BST_DEFAULT_MIN_FREQ;
}
static void sdhci_bst_enable_clk(struct sdhci_host *host, unsigned int clk)
{
struct sdhci_pltfm_host *pltfm_host;
unsigned int div;
u32 val;
union sdhci_bst_rx_ctrl rx_reg;
pltfm_host = sdhci_priv(host);
/* Calculate clock divider based on target frequency */
if (clk == 0) {
div = 0;
} else if (clk < BST_DEFAULT_MIN_FREQ) {
/* Below minimum: use max divider to get closest to min freq */
div = BST_DEFAULT_MAX_FREQ / BST_DEFAULT_MIN_FREQ;
} else if (clk <= BST_DEFAULT_MAX_FREQ) {
/* Normal range: calculate divider directly */
div = BST_DEFAULT_MAX_FREQ / clk;
} else {
/* Above maximum: no division needed */
div = 1;
}
clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
clk &= ~SDHCI_CLOCK_CARD_EN;
sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
clk &= ~SDHCI_CLOCK_PLL_EN;
sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
val = sdhci_bst_crm_read(pltfm_host, SDEMMC_CRM_TIMER_DIV_CTRL);
val &= ~BST_TIMER_LOAD_BIT;
sdhci_bst_crm_write(pltfm_host, SDEMMC_CRM_TIMER_DIV_CTRL, val);
val = sdhci_bst_crm_read(pltfm_host, SDEMMC_CRM_TIMER_DIV_CTRL);
val &= ~BST_TIMER_DIV_MASK;
val |= BST_TIMER_DIV_VAL;
Annotation
- Immediate include surface: `linux/bits.h`, `linux/bitfield.h`, `linux/delay.h`, `linux/dma-mapping.h`, `linux/iopoll.h`, `linux/module.h`, `linux/of.h`, `linux/of_reserved_mem.h`.
- Detected declarations: `struct sdhci_bst_priv`, `function sdhci_bst_crm_read`, `function sdhci_bst_crm_write`, `function sdhci_bst_wait_int_clk`, `function sdhci_bst_get_max_clock`, `function sdhci_bst_get_min_clock`, `function sdhci_bst_enable_clk`, `function sdhci_bst_set_clock`, `function sdhci_bst_reset`, `function sdhci_bst_set_timeout`.
- Atlas domain: Driver Families / drivers/mmc.
- Implementation status: source implementation candidate.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
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.