drivers/mmc/host/sdhci-spear.c
Source file repositories/reference/linux-study-clean/drivers/mmc/host/sdhci-spear.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/mmc/host/sdhci-spear.c- Extension
.c- Size
- 4370 bytes
- Lines
- 188
- 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/clk.hlinux/delay.hlinux/highmem.hlinux/module.hlinux/interrupt.hlinux/irq.hlinux/of.hlinux/platform_device.hlinux/pm.hlinux/slab.hlinux/mmc/host.hlinux/mmc/slot-gpio.hlinux/io.hsdhci.h
Detected Declarations
struct spear_sdhcifunction sdhci_probefunction sdhci_removefunction sdhci_suspendfunction sdhci_resume
Annotated Snippet
struct spear_sdhci {
struct clk *clk;
};
/* sdhci ops */
static const struct sdhci_ops sdhci_pltfm_ops = {
.set_clock = sdhci_set_clock,
.set_bus_width = sdhci_set_bus_width,
.reset = sdhci_reset,
.set_uhs_signaling = sdhci_set_uhs_signaling,
};
static int sdhci_probe(struct platform_device *pdev)
{
struct sdhci_host *host;
struct spear_sdhci *sdhci;
struct device *dev;
int ret;
dev = pdev->dev.parent ? pdev->dev.parent : &pdev->dev;
host = sdhci_alloc_host(dev, sizeof(*sdhci));
if (IS_ERR(host)) {
ret = PTR_ERR(host);
dev_dbg(&pdev->dev, "cannot allocate memory for sdhci\n");
goto err;
}
host->ioaddr = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(host->ioaddr)) {
ret = PTR_ERR(host->ioaddr);
dev_dbg(&pdev->dev, "unable to map iomem: %d\n", ret);
goto err;
}
host->hw_name = "sdhci";
host->ops = &sdhci_pltfm_ops;
host->irq = platform_get_irq(pdev, 0);
if (host->irq < 0) {
ret = host->irq;
goto err;
}
host->quirks = SDHCI_QUIRK_BROKEN_ADMA;
sdhci = sdhci_priv(host);
/* clk enable */
sdhci->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(sdhci->clk)) {
ret = PTR_ERR(sdhci->clk);
dev_dbg(&pdev->dev, "Error getting clock\n");
goto err;
}
ret = clk_prepare_enable(sdhci->clk);
if (ret) {
dev_dbg(&pdev->dev, "Error enabling clock\n");
goto err;
}
ret = clk_set_rate(sdhci->clk, 50000000);
if (ret)
dev_dbg(&pdev->dev, "Error setting desired clk, clk=%lu\n",
clk_get_rate(sdhci->clk));
/*
* It is optional to use GPIOs for sdhci card detection. If we
* find a descriptor using slot GPIO, we use it.
*/
ret = mmc_gpiod_request_cd(host->mmc, "cd", 0, false, 0);
if (ret == -EPROBE_DEFER)
goto disable_clk;
ret = sdhci_add_host(host);
if (ret)
goto disable_clk;
platform_set_drvdata(pdev, host);
return 0;
disable_clk:
clk_disable_unprepare(sdhci->clk);
err:
dev_err(&pdev->dev, "spear-sdhci probe failed: %d\n", ret);
return ret;
}
static void sdhci_remove(struct platform_device *pdev)
{
struct sdhci_host *host = platform_get_drvdata(pdev);
Annotation
- Immediate include surface: `linux/clk.h`, `linux/delay.h`, `linux/highmem.h`, `linux/module.h`, `linux/interrupt.h`, `linux/irq.h`, `linux/of.h`, `linux/platform_device.h`.
- Detected declarations: `struct spear_sdhci`, `function sdhci_probe`, `function sdhci_remove`, `function sdhci_suspend`, `function sdhci_resume`.
- 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.