drivers/mmc/host/sdhci-pci-o2micro.c
Source file repositories/reference/linux-study-clean/drivers/mmc/host/sdhci-pci-o2micro.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/mmc/host/sdhci-pci-o2micro.c- Extension
.c- Size
- 30972 bytes
- Lines
- 1100
- 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/pci.hlinux/mmc/host.hlinux/mmc/mmc.hlinux/delay.hlinux/iopoll.hlinux/bitfield.hsdhci.hsdhci-pci.h
Detected Declarations
struct o2_hostfunction sdhci_o2_wait_card_detect_stablefunction sdhci_o2_enable_internal_clockfunction sdhci_o2_get_cdfunction o2_pci_set_baseclkfunction sdhci_o2_pll_dll_wdt_controlfunction sdhci_o2_wait_dll_detect_lockfunction sdhci_o2_set_tuning_modefunction __sdhci_o2_execute_tuningfunction sdhci_o2_dll_recoveryfunction sdhci_o2_execute_tuningfunction o2_pci_led_enablefunction sdhci_pci_o2_fujin2_pci_initfunction sdhci_pci_o2_enable_msifunction sdhci_o2_enable_clkfunction sdhci_pci_o2_set_clockfunction sdhci_pci_o2_init_sd_expressfunction sdhci_pci_o2_set_powerfunction sdhci_pci_o2_probe_slotfunction sdhci_pci_o2_probefunction sdhci_pci_o2_resume
Annotated Snippet
struct o2_host {
u8 dll_adjust_count;
};
static void sdhci_o2_wait_card_detect_stable(struct sdhci_host *host)
{
ktime_t timeout;
u32 scratch32;
/* Wait max 50 ms */
timeout = ktime_add_ms(ktime_get(), 50);
while (1) {
bool timedout = ktime_after(ktime_get(), timeout);
scratch32 = sdhci_readl(host, SDHCI_PRESENT_STATE);
if ((scratch32 & SDHCI_CARD_PRESENT) >> SDHCI_CARD_PRES_SHIFT
== (scratch32 & SDHCI_CD_LVL) >> SDHCI_CD_LVL_SHIFT)
break;
if (timedout) {
pr_err("%s: Card Detect debounce never finished.\n",
mmc_hostname(host->mmc));
sdhci_dumpregs(host);
return;
}
udelay(10);
}
}
static void sdhci_o2_enable_internal_clock(struct sdhci_host *host)
{
ktime_t timeout;
u16 scratch;
u32 scratch32;
/* PLL software reset */
scratch32 = sdhci_readl(host, O2_PLL_DLL_WDT_CONTROL1);
scratch32 |= O2_PLL_SOFT_RESET;
sdhci_writel(host, scratch32, O2_PLL_DLL_WDT_CONTROL1);
udelay(1);
scratch32 &= ~(O2_PLL_SOFT_RESET);
sdhci_writel(host, scratch32, O2_PLL_DLL_WDT_CONTROL1);
/* PLL force active */
scratch32 |= O2_PLL_FORCE_ACTIVE;
sdhci_writel(host, scratch32, O2_PLL_DLL_WDT_CONTROL1);
/* Wait max 20 ms */
timeout = ktime_add_ms(ktime_get(), 20);
while (1) {
bool timedout = ktime_after(ktime_get(), timeout);
scratch = sdhci_readw(host, O2_PLL_DLL_WDT_CONTROL1);
if (scratch & O2_PLL_LOCK_STATUS)
break;
if (timedout) {
pr_err("%s: Internal clock never stabilised.\n",
mmc_hostname(host->mmc));
sdhci_dumpregs(host);
goto out;
}
udelay(10);
}
/* Wait for card detect finish */
udelay(1);
sdhci_o2_wait_card_detect_stable(host);
out:
/* Cancel PLL force active */
scratch32 = sdhci_readl(host, O2_PLL_DLL_WDT_CONTROL1);
scratch32 &= ~O2_PLL_FORCE_ACTIVE;
sdhci_writel(host, scratch32, O2_PLL_DLL_WDT_CONTROL1);
}
static int sdhci_o2_get_cd(struct mmc_host *mmc)
{
struct sdhci_host *host = mmc_priv(mmc);
if (!(sdhci_readw(host, O2_PLL_DLL_WDT_CONTROL1) & O2_PLL_LOCK_STATUS))
sdhci_o2_enable_internal_clock(host);
else
sdhci_o2_wait_card_detect_stable(host);
return !!(sdhci_readl(host, SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT);
}
static void o2_pci_set_baseclk(struct sdhci_pci_chip *chip, u32 value)
{
u32 scratch_32;
Annotation
- Immediate include surface: `linux/pci.h`, `linux/mmc/host.h`, `linux/mmc/mmc.h`, `linux/delay.h`, `linux/iopoll.h`, `linux/bitfield.h`, `sdhci.h`, `sdhci-pci.h`.
- Detected declarations: `struct o2_host`, `function sdhci_o2_wait_card_detect_stable`, `function sdhci_o2_enable_internal_clock`, `function sdhci_o2_get_cd`, `function o2_pci_set_baseclk`, `function sdhci_o2_pll_dll_wdt_control`, `function sdhci_o2_wait_dll_detect_lock`, `function sdhci_o2_set_tuning_mode`, `function __sdhci_o2_execute_tuning`, `function sdhci_o2_dll_recovery`.
- 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.