drivers/spi/spi-mpfs.c
Source file repositories/reference/linux-study-clean/drivers/spi/spi-mpfs.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/spi/spi-mpfs.c- Extension
.c- Size
- 17037 bytes
- Lines
- 629
- Domain
- Driver Families
- Bucket
- drivers/spi
- 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/clk.hlinux/delay.hlinux/err.hlinux/init.hlinux/interrupt.hlinux/io.hlinux/module.hlinux/of.hlinux/platform_device.hlinux/spi/spi.h
Detected Declarations
struct mpfs_spifunction mpfs_spi_readfunction mpfs_spi_writefunction mpfs_spi_disablefunction mpfs_spi_read_fifofunction mpfs_spi_enable_intsfunction mpfs_spi_disable_intsfunction mpfs_spi_set_xfer_sizefunction mpfs_spi_write_fifofunction mpfs_spi_set_framesizefunction mpfs_spi_set_csfunction mpfs_spi_setupfunction mpfs_spi_initfunction mpfs_spi_set_clk_genfunction mpfs_spi_set_modefunction mpfs_spi_interruptfunction mpfs_spi_calculate_clkgenfunction mpfs_spi_transfer_onefunction mpfs_spi_prepare_messagefunction mpfs_spi_probefunction mpfs_spi_remove
Annotated Snippet
struct mpfs_spi {
void __iomem *regs;
struct clk *clk;
const u8 *tx_buf;
u8 *rx_buf;
u32 clk_gen; /* divider for spi output clock generated by the controller */
u32 clk_mode;
u32 pending_slave_select;
int irq;
int tx_len;
int rx_len;
int n_bytes;
};
static inline u32 mpfs_spi_read(struct mpfs_spi *spi, unsigned int reg)
{
return readl(spi->regs + reg);
}
static inline void mpfs_spi_write(struct mpfs_spi *spi, unsigned int reg, u32 val)
{
writel(val, spi->regs + reg);
}
static inline void mpfs_spi_disable(struct mpfs_spi *spi)
{
u32 control = mpfs_spi_read(spi, REG_CONTROL);
control &= ~CONTROL_ENABLE;
mpfs_spi_write(spi, REG_CONTROL, control);
}
static inline void mpfs_spi_read_fifo(struct mpfs_spi *spi, int fifo_max)
{
for (int i = 0; i < fifo_max; i++) {
u32 data;
while (mpfs_spi_read(spi, REG_STATUS) & STATUS_RXFIFO_EMPTY)
;
data = mpfs_spi_read(spi, REG_RX_DATA);
spi->rx_len -= spi->n_bytes;
if (!spi->rx_buf)
continue;
if (spi->n_bytes == 4)
*((u32 *)spi->rx_buf) = data;
else if (spi->n_bytes == 2)
*((u16 *)spi->rx_buf) = data;
else
*spi->rx_buf = data;
spi->rx_buf += spi->n_bytes;
}
}
static void mpfs_spi_enable_ints(struct mpfs_spi *spi)
{
u32 control = mpfs_spi_read(spi, REG_CONTROL);
control |= INT_ENABLE_MASK;
mpfs_spi_write(spi, REG_CONTROL, control);
}
static void mpfs_spi_disable_ints(struct mpfs_spi *spi)
{
u32 control = mpfs_spi_read(spi, REG_CONTROL);
control &= ~INT_ENABLE_MASK;
mpfs_spi_write(spi, REG_CONTROL, control);
}
static inline void mpfs_spi_set_xfer_size(struct mpfs_spi *spi, int len)
{
u32 control;
u32 lenpart;
u32 frames = mpfs_spi_read(spi, REG_FRAMESUP);
/*
* Writing to FRAMECNT in REG_CONTROL will reset the frame count, taking
* a shortcut requires an explicit clear.
*/
if (frames == len) {
mpfs_spi_write(spi, REG_COMMAND, COMMAND_CLRFRAMECNT);
return;
}
Annotation
- Immediate include surface: `linux/clk.h`, `linux/delay.h`, `linux/err.h`, `linux/init.h`, `linux/interrupt.h`, `linux/io.h`, `linux/module.h`, `linux/of.h`.
- Detected declarations: `struct mpfs_spi`, `function mpfs_spi_read`, `function mpfs_spi_write`, `function mpfs_spi_disable`, `function mpfs_spi_read_fifo`, `function mpfs_spi_enable_ints`, `function mpfs_spi_disable_ints`, `function mpfs_spi_set_xfer_size`, `function mpfs_spi_write_fifo`, `function mpfs_spi_set_framesize`.
- Atlas domain: Driver Families / drivers/spi.
- 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.