STRUCT ATMEL_MCI(9)
π struct atmel_mci π
okay bestie, welcome to the Kernel API Manual, section 9 β this page is literally all about struct atmel_mci, and we're gonna get into every single field without skipping a crumb π
πΈ NAME πΈ
struct atmel_mci β MMC controller state shared between all slots. periodt π
β¨ SYNOPSIS β¨
struct atmel_mci {
spinlock_t lock;
void __iomem *regs;
struct scatterlist *sg;
unsigned int sg_len;
unsigned int pio_offset;
unsigned int *buffer;
unsigned int buf_size;
dma_addr_t buf_phys_addr;
struct atmel_mci_slot *cur_slot;
struct mmc_request *mrq;
struct mmc_command *cmd;
struct mmc_data *data;
unsigned int data_size;
struct atmel_mci_dma dma;
struct dma_chan *data_chan;
struct dma_slave_config dma_conf;
u32 cmd_status;
u32 data_status;
u32 stop_cmdr;
struct work_struct bh_work;
unsigned long pending_events;
unsigned long completed_events;
enum atmel_mci_state state;
struct list_head queue;
bool need_clock_update;
bool need_reset;
struct timer_list timer;
u32 mode_reg;
u32 cfg_reg;
unsigned long bus_hz;
unsigned long mapbase;
struct clk *mck;
struct device *dev;
struct mci_slot_pdata pdata[ATMCI_MAX_NR_SLOTS];
struct atmel_mci_slot *slot[ATMCI_MAX_NR_SLOTS];
struct atmel_mci_caps caps;
u32 (*prepare_data)(struct atmel_mci *host, struct mmc_data *data);
void (*submit_data)(struct atmel_mci *host, struct mmc_data *data);
void (*stop_transfer)(struct atmel_mci *host);
};
π«Ά Members π«Ά
lockβ spinlock protecting the queue and associated data, no cap.regsβ pointer to MMIO registers β¨sgβ scatterlist entry currently being processed by PIO or PDC code.sg_lenβ size of the scatterlist.pio_offsetβ offset into the current scatterlist entry.bufferβ buffer used if we don't have the r/w proof capability. We don't have the time to switch pdc buffers so we have to use only one buffer for the full transaction. it's giving efficiency πbuf_sizeβ size of the buffer.buf_phys_addrβ buffer address needed for pdc.cur_slotβ the slot which is currently using the controller πmrqβ the request currently being processed oncur_slot, orNULLif the controller is idle.cmdβ the command currently being sent to the card, orNULL.dataβ the data currently being transferred, orNULLif no data transfer is in progress.data_sizeβ justdata->blocks * data->blksz.dmaβ DMA client state.data_chanβ DMA channel being used for the current data transfer.dma_confβ configuration for the DMA slave.cmd_statusβ snapshot ofSRtaken upon completion of the current command. Only valid whenEVENT_CMD_COMPLETEis pending. iykyk π₯data_statusβ snapshot ofSRtaken upon completion of the current data transfer. Only valid whenEVENT_DATA_COMPLETEorEVENT_DATA_ERRORis pending.stop_cmdrβ value to be loaded intoCMDRwhen the stop command is to be sent.bh_workβ work running the request state machine.pending_eventsβ bitmask of events flagged by the interrupt handler to be processed by the work.completed_eventsβ bitmask of events which the state machine has processed.stateβ work state.queueβ list of slots waiting for access to the controller.need_clock_updateβ update the clock rate before the next request.need_resetβ reset controller before next request.timerβ timer to balance the data timeout error flag which cannot rise.mode_regβ value of theMRregister.cfg_regβ value of theCFGregister.bus_hzβ the rate ofmckin Hz. This forms the basis for MMC bus rate and timeout calculations.mapbaseβ physical address of the MMIO registers.mckβ the peripheral bus clock hooked up to the MMC controller.devβ device associated with the MMC controller.pdataβ per-slot configuration data.slotβ slots sharing this MMC controller.capsβ MCI capabilities depending on MCI version.prepare_dataβ function to setup MCI before data transfer which depends on MCI capabilities.submit_dataβ function to start data transfer which depends on MCI capabilities.stop_transferβ function to stop data transfer which depends on MCI capabilities.
π Description π
okay so the whole personality of this struct is locking, and it is not playing around about it π
π Locking π
lock is a softirq-safe spinlock protecting queue as well as cur_slot, mrq and state. These must always be updated at the same time while holding lock. no splitting the group chat update, bestie π«Ά
lock also protects mode_reg and need_clock_update since these are used to synchronize mode register updates with the queue processing.
The mrq field of struct atmel_mci_slot is also protected by lock, and must always be written at the same time as the slot is added to queue.
pending_events and completed_events are accessed using atomic bit operations, so they don't need any locking. slay for them β¨
None of the fields touched by the interrupt handler need any locking. However, ordering is important: Before EVENT_DATA_ERROR or EVENT_DATA_COMPLETE is set in pending_events, all data-related interrupts must be disabled and data_status updated with a snapshot of SR. Similarly, before EVENT_CMD_COMPLETE is set, the CMDRDY interrupt must be disabled and cmd_status updated with a snapshot of SR, and before EVENT_XFER_COMPLETE can be set, the bytes_xfered field of data must be written. This is ensured by using barriers. do not skip the barrier order, fr fr π
π¦ SEE ALSO π¦
- Kernel file
./drivers/mmc/host/atmel-mci.c struct mci_slot_pdata(9)struct atmel_mci_slot(9)
mwah π source ./drivers/mmc/host, October 2026, page struct atmel_mci(9) β that's the whole footer vibe, bestie π«Άπ
π¦ where this page comes from
- nixpkgs unstable: linux-manual 7.3.1
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms