drivers/mmc/host/litex_mmc.c
Source file repositories/reference/linux-study-clean/drivers/mmc/host/litex_mmc.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/mmc/host/litex_mmc.c- Extension
.c- Size
- 18149 bytes
- Lines
- 667
- 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/bits.hlinux/clk.hlinux/delay.hlinux/dma-mapping.hlinux/interrupt.hlinux/iopoll.hlinux/litex.hlinux/math.hlinux/mod_devicetable.hlinux/module.hlinux/platform_device.hlinux/mmc/host.hlinux/mmc/mmc.hlinux/mmc/sd.h
Detected Declarations
struct litex_mmc_hostfunction litex_mmc_sdcard_wait_donefunction litex_mmc_send_cmdfunction litex_mmc_send_app_cmdfunction litex_mmc_send_set_bus_w_cmdfunction litex_mmc_set_bus_widthfunction litex_mmc_get_cdfunction litex_mmc_interruptfunction litex_mmc_response_lenfunction litex_mmc_do_dmafunction litex_mmc_requestfunction litex_mmc_setclkfunction litex_mmc_set_iosfunction litex_mmc_irq_initfunction litex_mmc_probefunction litex_mmc_remove
Annotated Snippet
struct litex_mmc_host {
struct mmc_host *mmc;
void __iomem *sdphy;
void __iomem *sdcore;
void __iomem *sdreader;
void __iomem *sdwriter;
void __iomem *sdirq;
void *buffer;
size_t buf_size;
dma_addr_t dma;
struct completion cmd_done;
int irq;
unsigned int ref_clk;
unsigned int sd_clk;
u32 resp[4];
u16 rca;
bool is_bus_width_set;
bool app_cmd;
};
static int litex_mmc_sdcard_wait_done(void __iomem *reg, struct device *dev)
{
u8 evt;
int ret;
ret = readx_poll_timeout(litex_read8, reg, evt, evt & SD_BIT_DONE,
SD_SLEEP_US, SD_TIMEOUT_US);
if (ret)
return ret;
if (evt == SD_BIT_DONE)
return 0;
if (evt & SD_BIT_WR_ERR)
return -EIO;
if (evt & SD_BIT_TIMEOUT)
return -ETIMEDOUT;
if (evt & SD_BIT_CRC_ERR)
return -EILSEQ;
dev_err(dev, "%s: unknown error (evt=%x)\n", __func__, evt);
return -EINVAL;
}
static int litex_mmc_send_cmd(struct litex_mmc_host *host,
u8 cmd, u32 arg, u8 response_len, u8 transfer)
{
struct device *dev = mmc_dev(host->mmc);
void __iomem *reg;
int ret;
u8 evt;
litex_write32(host->sdcore + LITEX_CORE_CMDARG, arg);
litex_write32(host->sdcore + LITEX_CORE_CMDCMD,
cmd << 8 | transfer << 5 | response_len);
litex_write8(host->sdcore + LITEX_CORE_CMDSND, 1);
/*
* Wait for an interrupt if we have an interrupt and either there is
* data to be transferred, or if the card can report busy via DAT0.
*/
if (host->irq > 0 &&
(transfer != SD_CTL_DATA_XFER_NONE ||
response_len == SD_CTL_RESP_SHORT_BUSY)) {
reinit_completion(&host->cmd_done);
litex_write32(host->sdirq + LITEX_IRQ_ENABLE,
SDIRQ_CMD_DONE | SDIRQ_CARD_DETECT);
wait_for_completion(&host->cmd_done);
}
ret = litex_mmc_sdcard_wait_done(host->sdcore + LITEX_CORE_CMDEVT, dev);
if (ret) {
dev_err(dev, "Command (cmd %d) error, status %d\n", cmd, ret);
return ret;
}
if (response_len != SD_CTL_RESP_NONE) {
/*
* NOTE: this matches the semantics of litex_read32()
* regardless of underlying arch endianness!
*/
memcpy_fromio(host->resp,
host->sdcore + LITEX_CORE_CMDRSP, 0x10);
}
if (!host->app_cmd && cmd == SD_SEND_RELATIVE_ADDR)
host->rca = (host->resp[3] >> 16);
Annotation
- Immediate include surface: `linux/bits.h`, `linux/clk.h`, `linux/delay.h`, `linux/dma-mapping.h`, `linux/interrupt.h`, `linux/iopoll.h`, `linux/litex.h`, `linux/math.h`.
- Detected declarations: `struct litex_mmc_host`, `function litex_mmc_sdcard_wait_done`, `function litex_mmc_send_cmd`, `function litex_mmc_send_app_cmd`, `function litex_mmc_send_set_bus_w_cmd`, `function litex_mmc_set_bus_width`, `function litex_mmc_get_cd`, `function litex_mmc_interrupt`, `function litex_mmc_response_len`, `function litex_mmc_do_dma`.
- 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.