drivers/mmc/host/mmci.c
Source file repositories/reference/linux-study-clean/drivers/mmc/host/mmci.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/mmc/host/mmci.c- Extension
.c- Size
- 69813 bytes
- Lines
- 2689
- 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.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- 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/module.hlinux/moduleparam.hlinux/init.hlinux/ioport.hlinux/device.hlinux/io.hlinux/interrupt.hlinux/kernel.hlinux/slab.hlinux/delay.hlinux/err.hlinux/highmem.hlinux/log2.hlinux/mmc/mmc.hlinux/mmc/pm.hlinux/mmc/host.hlinux/mmc/card.hlinux/mmc/sd.hlinux/mmc/slot-gpio.hlinux/amba/bus.hlinux/clk.hlinux/scatterlist.hlinux/of.hlinux/regulator/consumer.hlinux/dmaengine.hlinux/dma-mapping.hlinux/amba/mmci.hlinux/pm_runtime.hlinux/types.hlinux/pinctrl/consumer.hlinux/reset.hlinux/gpio/consumer.h
Detected Declarations
struct mmci_dmae_nextstruct mmci_dmae_privfunction mmci_card_busyfunction mmci_reg_delayfunction mmci_write_clkregfunction mmci_write_pwrregfunction mmci_write_datactrlregfunction mmci_set_clkregfunction mmci_dma_releasefunction mmci_dma_setupfunction mmci_validate_datafunction mmci_prep_datafunction mmci_unprep_datafunction mmci_get_next_datafunction mmci_dma_startfunction mmci_dma_finalizefunction mmci_dma_errorfunction mmci_request_endfunction mmci_set_mask1function mmci_stop_datafunction mmci_init_sgfunction mmci_get_dctrl_cfgfunction ux500v2_get_dctrl_cfgfunction ux500_busy_clear_mask_donefunction ux500_busy_completefunction mmci_dmae_setupfunction mmci_dmae_releasefunction mmci_dma_unmapfunction mmci_dmae_errorfunction mmci_dmae_finalizefunction _mmci_dmae_prep_datafunction mmci_dmae_prep_datafunction mmci_dmae_startfunction mmci_dmae_get_next_datafunction mmci_dmae_unprep_datafunction mmci_variant_initfunction ux500_variant_initfunction ux500v2_variant_initfunction mmci_pre_requestfunction mmci_post_requestfunction mmci_start_datafunction mmci_start_commandfunction mmci_stop_commandfunction mmci_data_irqfunction mmci_cmd_irqfunction ux500_busy_timeout_workfunction mmci_get_rx_fifocntfunction mmci_qcom_get_rx_fifocnt
Annotated Snippet
struct mmci_dmae_next {
struct dma_async_tx_descriptor *desc;
struct dma_chan *chan;
};
struct mmci_dmae_priv {
struct dma_chan *cur;
struct dma_chan *rx_channel;
struct dma_chan *tx_channel;
struct dma_async_tx_descriptor *desc_current;
struct mmci_dmae_next next_data;
};
int mmci_dmae_setup(struct mmci_host *host)
{
const char *rxname, *txname;
struct mmci_dmae_priv *dmae;
dmae = devm_kzalloc(mmc_dev(host->mmc), sizeof(*dmae), GFP_KERNEL);
if (!dmae)
return -ENOMEM;
host->dma_priv = dmae;
dmae->rx_channel = dma_request_chan(mmc_dev(host->mmc), "rx");
if (IS_ERR(dmae->rx_channel)) {
int ret = PTR_ERR(dmae->rx_channel);
dmae->rx_channel = NULL;
return ret;
}
dmae->tx_channel = dma_request_chan(mmc_dev(host->mmc), "tx");
if (IS_ERR(dmae->tx_channel)) {
if (PTR_ERR(dmae->tx_channel) == -EPROBE_DEFER)
dev_warn(mmc_dev(host->mmc),
"Deferred probe for TX channel ignored\n");
dmae->tx_channel = NULL;
}
/*
* If only an RX channel is specified, the driver will
* attempt to use it bidirectionally, however if it
* is specified but cannot be located, DMA will be disabled.
*/
if (dmae->rx_channel && !dmae->tx_channel)
dmae->tx_channel = dmae->rx_channel;
if (dmae->rx_channel)
rxname = dma_chan_name(dmae->rx_channel);
else
rxname = "none";
if (dmae->tx_channel)
txname = dma_chan_name(dmae->tx_channel);
else
txname = "none";
dev_info(mmc_dev(host->mmc), "DMA channels RX %s, TX %s\n",
rxname, txname);
/*
* Limit the maximum segment size in any SG entry according to
* the parameters of the DMA engine device.
*/
if (dmae->tx_channel) {
struct device *dev = dmae->tx_channel->device->dev;
unsigned int max_seg_size = dma_get_max_seg_size(dev);
if (max_seg_size < host->mmc->max_seg_size)
host->mmc->max_seg_size = max_seg_size;
}
if (dmae->rx_channel) {
struct device *dev = dmae->rx_channel->device->dev;
unsigned int max_seg_size = dma_get_max_seg_size(dev);
if (max_seg_size < host->mmc->max_seg_size)
host->mmc->max_seg_size = max_seg_size;
}
if (!dmae->tx_channel || !dmae->rx_channel) {
mmci_dmae_release(host);
return -EINVAL;
}
return 0;
}
/*
* This is used in or so inline it
* so it can be discarded.
Annotation
- Immediate include surface: `linux/module.h`, `linux/moduleparam.h`, `linux/init.h`, `linux/ioport.h`, `linux/device.h`, `linux/io.h`, `linux/interrupt.h`, `linux/kernel.h`.
- Detected declarations: `struct mmci_dmae_next`, `struct mmci_dmae_priv`, `function mmci_card_busy`, `function mmci_reg_delay`, `function mmci_write_clkreg`, `function mmci_write_pwrreg`, `function mmci_write_datactrlreg`, `function mmci_set_clkreg`, `function mmci_dma_release`, `function mmci_dma_setup`.
- Atlas domain: Driver Families / drivers/mmc.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
- 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.