drivers/mmc/host/sh_mmcif.c
Source file repositories/reference/linux-study-clean/drivers/mmc/host/sh_mmcif.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/mmc/host/sh_mmcif.c- Extension
.c- Size
- 42318 bytes
- Lines
- 1601
- 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/bitops.hlinux/clk.hlinux/completion.hlinux/delay.hlinux/dma-mapping.hlinux/dmaengine.hlinux/mmc/card.hlinux/mmc/core.hlinux/mmc/host.hlinux/mmc/mmc.hlinux/mmc/sdio.hlinux/mmc/slot-gpio.hlinux/mod_devicetable.hlinux/mutex.hlinux/pagemap.hlinux/platform_data/sh_mmcif.hlinux/platform_device.hlinux/pm_qos.hlinux/pm_runtime.hlinux/sh_dma.hlinux/spinlock.hlinux/module.h
Detected Declarations
struct sh_mmcif_hostenum sh_mmcif_stateenum sh_mmcif_wait_forfunction sh_mmcif_bitsetfunction sh_mmcif_bitclrfunction sh_mmcif_dma_completefunction sh_mmcif_start_dma_rxfunction sh_mmcif_start_dma_txfunction sh_mmcif_request_dma_pdatafunction sh_mmcif_dma_slave_configfunction sh_mmcif_request_dmafunction sh_mmcif_release_dmafunction sh_mmcif_clock_controlfunction sh_mmcif_sync_resetfunction sh_mmcif_error_managefunction sh_mmcif_single_readfunction sh_mmcif_read_blockfunction sh_mmcif_multi_readfunction sh_mmcif_mread_blockfunction sh_mmcif_single_writefunction sh_mmcif_write_blockfunction sh_mmcif_multi_writefunction sh_mmcif_mwrite_blockfunction sh_mmcif_get_responsefunction sh_mmcif_get_cmd12responsefunction sh_mmcif_set_cmdfunction sh_mmcif_data_transfunction sh_mmcif_start_cmdfunction sh_mmcif_stop_cmdfunction sh_mmcif_requestfunction sh_mmcif_clk_setupfunction sh_mmcif_set_iosfunction sh_mmcif_end_cmdfunction sh_mmcif_irqtfunction sh_mmcif_intrfunction sh_mmcif_timeout_workfunction cancel_delayed_workfunction sh_mmcif_init_ocrfunction sh_mmcif_probefunction sh_mmcif_removefunction sh_mmcif_suspend
Annotated Snippet
struct sh_mmcif_host {
struct mmc_host *mmc;
struct mmc_request *mrq;
struct platform_device *pd;
struct clk *clk;
int bus_width;
unsigned char timing;
bool sd_error;
bool dying;
long timeout;
void __iomem *addr;
spinlock_t lock; /* protect sh_mmcif_host::state */
enum sh_mmcif_state state;
enum sh_mmcif_wait_for wait_for;
struct delayed_work timeout_work;
size_t blocksize;
struct sg_mapping_iter sg_miter;
bool power;
bool ccs_enable; /* Command Completion Signal support */
bool clk_ctrl2_enable;
struct mutex thread_lock;
u32 clkdiv_map; /* see CE_CLK_CTRL::CLKDIV */
/* DMA support */
struct dma_chan *chan_rx;
struct dma_chan *chan_tx;
struct completion dma_complete;
bool dma_active;
};
static const struct of_device_id sh_mmcif_of_match[] = {
{ .compatible = "renesas,sh-mmcif" },
{ }
};
MODULE_DEVICE_TABLE(of, sh_mmcif_of_match);
#define sh_mmcif_host_to_dev(host) (&host->pd->dev)
static inline void sh_mmcif_bitset(struct sh_mmcif_host *host,
unsigned int reg, u32 val)
{
writel(val | readl(host->addr + reg), host->addr + reg);
}
static inline void sh_mmcif_bitclr(struct sh_mmcif_host *host,
unsigned int reg, u32 val)
{
writel(~val & readl(host->addr + reg), host->addr + reg);
}
static void sh_mmcif_dma_complete(void *arg)
{
struct sh_mmcif_host *host = arg;
struct mmc_request *mrq = host->mrq;
struct device *dev = sh_mmcif_host_to_dev(host);
dev_dbg(dev, "Command completed\n");
if (WARN(!mrq || !mrq->data, "%s: NULL data in DMA completion!\n",
dev_name(dev)))
return;
complete(&host->dma_complete);
}
static void sh_mmcif_start_dma_rx(struct sh_mmcif_host *host)
{
struct mmc_data *data = host->mrq->data;
struct scatterlist *sg = data->sg;
struct dma_async_tx_descriptor *desc = NULL;
struct dma_chan *chan = host->chan_rx;
struct device *dev = sh_mmcif_host_to_dev(host);
dma_cookie_t cookie = -EINVAL;
int ret;
ret = dma_map_sg(chan->device->dev, sg, data->sg_len,
DMA_FROM_DEVICE);
if (ret > 0) {
host->dma_active = true;
desc = dmaengine_prep_slave_sg(chan, sg, ret,
DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
}
if (desc) {
desc->callback = sh_mmcif_dma_complete;
desc->callback_param = host;
cookie = dmaengine_submit(desc);
sh_mmcif_bitset(host, MMCIF_CE_BUF_ACC, BUF_ACC_DMAREN);
dma_async_issue_pending(chan);
}
Annotation
- Immediate include surface: `linux/bitops.h`, `linux/clk.h`, `linux/completion.h`, `linux/delay.h`, `linux/dma-mapping.h`, `linux/dmaengine.h`, `linux/mmc/card.h`, `linux/mmc/core.h`.
- Detected declarations: `struct sh_mmcif_host`, `enum sh_mmcif_state`, `enum sh_mmcif_wait_for`, `function sh_mmcif_bitset`, `function sh_mmcif_bitclr`, `function sh_mmcif_dma_complete`, `function sh_mmcif_start_dma_rx`, `function sh_mmcif_start_dma_tx`, `function sh_mmcif_request_dma_pdata`, `function sh_mmcif_dma_slave_config`.
- 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.