drivers/mmc/host/sdhci-pci-gli.c
Source file repositories/reference/linux-study-clean/drivers/mmc/host/sdhci-pci-gli.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/mmc/host/sdhci-pci-gli.c- Extension
.c- Size
- 65471 bytes
- Lines
- 2134
- 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.
- 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/bitfield.hlinux/bits.hlinux/pci.hlinux/mmc/mmc.hlinux/delay.hlinux/of.hlinux/iopoll.hsdhci.hsdhci-cqhci.hsdhci-pci.hcqhci.hsdhci-uhs2.h
Detected Declarations
function Copyrightfunction gl9750_wt_onfunction gl9750_wt_offfunction gli_set_9750function gli_set_9750_rx_invfunction __sdhci_execute_tuning_9750function gl9750_execute_tuningfunction gl9750_disable_ssc_pllfunction gl9750_set_pllfunction gl9750_ssc_enablefunction gl9750_set_sscfunction gl9750_set_ssc_pll_205mhzfunction gl9750_set_ssc_pll_100mhzfunction gl9750_set_ssc_pll_50mhzfunction sdhci_gl9750_set_clockfunction gl9750_hw_settingfunction gli_pcie_enable_msifunction gl9755_wt_onfunction gl9755_wt_offfunction gl9755_disable_ssc_pllfunction gl9755_set_pllfunction gl9755_ssc_enablefunction gl9755_set_sscfunction gl9755_set_ssc_pll_205mhzfunction gl9755_set_ssc_pll_100mhzfunction gl9755_set_ssc_pll_50mhzfunction sdhci_gl9755_set_clockfunction gl9755_hw_settingfunction gl9755_vendor_initfunction sdhci_gli_pre_detect_initfunction sdhci_gli_overcurrent_event_enablefunction gl9755_set_powerfunction sdhci_wait_clock_stablefunction sdhci_gli_enable_internal_clockfunction sdhci_gli_wait_software_reset_donefunction sdhci_gli_uhs2_reset_sd_tranfunction sdhci_gl9755_resetfunction gl9767_vhs_readfunction gl9767_vhs_writefunction gl9767_ssc_enablefunction gl9767_set_sscfunction gl9767_set_pllfunction gl9767_set_ssc_pll_205mhzfunction gl9767_disable_ssc_pllfunction gl9767_set_low_power_negotiationfunction sdhci_gl9767_uhs2_phy_resetfunction __gl9767_uhs2_set_powerfunction sdhci_gl9767_set_clock
Annotated Snippet
if (!host->tuning_done) {
sdhci_abort_tuning(host, opcode);
break;
}
ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
if (!(ctrl & SDHCI_CTRL_EXEC_TUNING)) {
if (ctrl & SDHCI_CTRL_TUNED_CLK)
return 0; /* Success! */
break;
}
}
}
if (!host->tuning_done) {
pr_info("%s: Tuning timeout, falling back to fixed sampling clock\n",
mmc_hostname(host->mmc));
return -ETIMEDOUT;
}
pr_info("%s: Tuning failed, falling back to fixed sampling clock\n",
mmc_hostname(host->mmc));
sdhci_reset_tuning(host);
return -EAGAIN;
}
static int gl9750_execute_tuning(struct sdhci_host *host, u32 opcode)
{
host->mmc->retune_period = 0;
if (host->tuning_mode == SDHCI_TUNING_MODE_1)
host->mmc->retune_period = host->tuning_count;
gli_set_9750(host);
host->tuning_err = __sdhci_execute_tuning_9750(host, opcode);
sdhci_end_tuning(host);
return 0;
}
static void gl9750_disable_ssc_pll(struct sdhci_host *host)
{
u32 pll;
gl9750_wt_on(host);
pll = sdhci_readl(host, SDHCI_GLI_9750_PLL);
pll &= ~(SDHCI_GLI_9750_PLL_DIR | SDHCI_GLI_9750_PLLSSC_EN);
sdhci_writel(host, pll, SDHCI_GLI_9750_PLL);
gl9750_wt_off(host);
}
static void gl9750_set_pll(struct sdhci_host *host, u8 dir, u16 ldiv, u8 pdiv)
{
u32 pll;
gl9750_wt_on(host);
pll = sdhci_readl(host, SDHCI_GLI_9750_PLL);
pll &= ~(SDHCI_GLI_9750_PLL_LDIV |
SDHCI_GLI_9750_PLL_PDIV |
SDHCI_GLI_9750_PLL_DIR);
pll |= FIELD_PREP(SDHCI_GLI_9750_PLL_LDIV, ldiv) |
FIELD_PREP(SDHCI_GLI_9750_PLL_PDIV, pdiv) |
FIELD_PREP(SDHCI_GLI_9750_PLL_DIR, dir);
sdhci_writel(host, pll, SDHCI_GLI_9750_PLL);
gl9750_wt_off(host);
/* wait for pll stable */
mdelay(1);
}
static bool gl9750_ssc_enable(struct sdhci_host *host)
{
u32 misc;
u8 off;
gl9750_wt_on(host);
misc = sdhci_readl(host, SDHCI_GLI_9750_MISC);
off = FIELD_GET(SDHCI_GLI_9750_MISC_SSC_OFF, misc);
gl9750_wt_off(host);
return !off;
}
static void gl9750_set_ssc(struct sdhci_host *host, u8 enable, u8 step, u16 ppm)
{
u32 pll;
u32 ssc;
gl9750_wt_on(host);
pll = sdhci_readl(host, SDHCI_GLI_9750_PLL);
ssc = sdhci_readl(host, SDHCI_GLI_9750_PLLSSC);
Annotation
- Immediate include surface: `linux/bitfield.h`, `linux/bits.h`, `linux/pci.h`, `linux/mmc/mmc.h`, `linux/delay.h`, `linux/of.h`, `linux/iopoll.h`, `sdhci.h`.
- Detected declarations: `function Copyright`, `function gl9750_wt_on`, `function gl9750_wt_off`, `function gli_set_9750`, `function gli_set_9750_rx_inv`, `function __sdhci_execute_tuning_9750`, `function gl9750_execute_tuning`, `function gl9750_disable_ssc_pll`, `function gl9750_set_pll`, `function gl9750_ssc_enable`.
- 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.