drivers/mmc/host/sunxi-mmc.c
Source file repositories/reference/linux-study-clean/drivers/mmc/host/sunxi-mmc.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/mmc/host/sunxi-mmc.c- Extension
.c- Size
- 42913 bytes
- Lines
- 1554
- 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/clk.hlinux/clk/sunxi-ng.hlinux/delay.hlinux/device.hlinux/dma-mapping.hlinux/err.hlinux/interrupt.hlinux/io.hlinux/kernel.hlinux/mmc/card.hlinux/mmc/core.hlinux/mmc/host.hlinux/mmc/mmc.hlinux/mmc/sd.hlinux/mmc/sdio.hlinux/mmc/slot-gpio.hlinux/module.hlinux/mod_devicetable.hlinux/of_address.hlinux/of_platform.hlinux/platform_device.hlinux/pm_runtime.hlinux/regulator/consumer.hlinux/reset.hlinux/scatterlist.hlinux/slab.hlinux/spinlock.h
Detected Declarations
struct sunxi_mmc_clk_delaystruct sunxi_idma_desstruct sunxi_mmc_cfgstruct sunxi_mmc_hostfunction sunxi_mmc_reset_hostfunction sunxi_mmc_init_hostfunction sunxi_mmc_init_idma_desfunction sunxi_mmc_map_dmafunction for_each_sgfunction sunxi_mmc_start_dmafunction sunxi_mmc_send_manual_stopfunction sunxi_mmc_dump_errinfofunction sunxi_mmc_finalize_requestfunction sunxi_mmc_irqfunction sunxi_mmc_handle_manual_stopfunction sunxi_mmc_oclk_onofffunction sunxi_mmc_calibratefunction sunxi_mmc_clk_set_phasefunction sunxi_mmc_clk_set_ratefunction sunxi_mmc_set_bus_widthfunction sunxi_mmc_set_clkfunction sunxi_mmc_card_powerfunction sunxi_mmc_set_iosfunction sunxi_mmc_volt_switchfunction sunxi_mmc_enable_sdio_irqfunction sunxi_mmc_hw_resetfunction sunxi_mmc_requestfunction sunxi_mmc_card_busyfunction sunxi_mmc_enablefunction sunxi_mmc_disablefunction sunxi_mmc_resource_requestfunction sunxi_mmc_probefunction mmc_of_parsefunction sunxi_mmc_removefunction sunxi_mmc_runtime_resumefunction sunxi_mmc_runtime_suspend
Annotated Snippet
struct sunxi_mmc_clk_delay {
u32 output;
u32 sample;
};
struct sunxi_idma_des {
__le32 config;
__le32 buf_size;
__le32 buf_addr_ptr1;
__le32 buf_addr_ptr2;
};
struct sunxi_mmc_cfg {
u32 idma_des_size_bits;
u32 idma_des_shift;
const struct sunxi_mmc_clk_delay *clk_delays;
/* does the IP block support autocalibration? */
bool can_calibrate;
/* Does DATA0 needs to be masked while the clock is updated */
bool mask_data0;
/*
* hardware only supports new timing mode, either due to lack of
* a mode switch in the clock controller, or the mmc controller
* is permanently configured in the new timing mode, without the
* NTSR mode switch.
*/
bool needs_new_timings;
/* clock hardware can switch between old and new timing modes */
bool ccu_has_timings_switch;
};
struct sunxi_mmc_host {
struct device *dev;
struct mmc_host *mmc;
struct reset_control *reset;
const struct sunxi_mmc_cfg *cfg;
/* IO mapping base */
void __iomem *reg_base;
/* clock management */
struct clk *clk_ahb;
struct clk *clk_mmc;
struct clk *clk_sample;
struct clk *clk_output;
/* irq */
spinlock_t lock;
int irq;
u32 int_sum;
u32 sdio_imask;
/* dma */
dma_addr_t sg_dma;
void *sg_cpu;
bool wait_dma;
struct mmc_request *mrq;
struct mmc_request *manual_stop_mrq;
int ferror;
/* vqmmc */
bool vqmmc_enabled;
/* timings */
bool use_new_timings;
};
static int sunxi_mmc_reset_host(struct sunxi_mmc_host *host)
{
unsigned long expire = jiffies + msecs_to_jiffies(250);
u32 rval;
mmc_writel(host, REG_GCTRL, SDXC_HARDWARE_RESET);
do {
rval = mmc_readl(host, REG_GCTRL);
} while (time_before(jiffies, expire) && (rval & SDXC_HARDWARE_RESET));
if (rval & SDXC_HARDWARE_RESET) {
dev_err(mmc_dev(host->mmc), "fatal err reset timeout\n");
return -EIO;
}
return 0;
}
Annotation
- Immediate include surface: `linux/clk.h`, `linux/clk/sunxi-ng.h`, `linux/delay.h`, `linux/device.h`, `linux/dma-mapping.h`, `linux/err.h`, `linux/interrupt.h`, `linux/io.h`.
- Detected declarations: `struct sunxi_mmc_clk_delay`, `struct sunxi_idma_des`, `struct sunxi_mmc_cfg`, `struct sunxi_mmc_host`, `function sunxi_mmc_reset_host`, `function sunxi_mmc_init_host`, `function sunxi_mmc_init_idma_des`, `function sunxi_mmc_map_dma`, `function for_each_sg`, `function sunxi_mmc_start_dma`.
- 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.