drivers/spi/spi-stm32-qspi.c
Source file repositories/reference/linux-study-clean/drivers/spi/spi-stm32-qspi.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/spi/spi-stm32-qspi.c- Extension
.c- Size
- 24082 bytes
- Lines
- 982
- 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.
- 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.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/bitfield.hlinux/clk.hlinux/dmaengine.hlinux/dma-mapping.hlinux/errno.hlinux/gpio/consumer.hlinux/io.hlinux/iopoll.hlinux/interrupt.hlinux/module.hlinux/mutex.hlinux/of.hlinux/pinctrl/consumer.hlinux/pm_runtime.hlinux/platform_device.hlinux/reset.hlinux/sizes.hlinux/spi/spi-mem.h
Detected Declarations
struct stm32_qspi_flashstruct stm32_qspifunction stm32_qspi_irqfunction stm32_qspi_read_fifofunction stm32_qspi_write_fifofunction stm32_qspi_tx_pollfunction stm32_qspi_tx_mmfunction stm32_qspi_dma_callbackfunction stm32_qspi_tx_dmafunction stm32_qspi_txfunction stm32_qspi_wait_nobusyfunction stm32_qspi_wait_cmdfunction stm32_qspi_wait_poll_statusfunction stm32_qspi_get_modefunction stm32_qspi_sendfunction stm32_qspi_poll_statusfunction stm32_qspi_exec_opfunction stm32_qspi_dirmap_createfunction stm32_qspi_dirmap_readfunction stm32_qspi_transfer_one_messagefunction list_for_each_entryfunction stm32_qspi_setupfunction stm32_qspi_dma_setupfunction stm32_qspi_dma_freefunction stm32_qspi_probefunction stm32_qspi_removefunction stm32_qspi_runtime_suspendfunction stm32_qspi_runtime_resumefunction stm32_qspi_suspendfunction stm32_qspi_resume
Annotated Snippet
struct stm32_qspi_flash {
u32 cs;
u32 presc;
};
struct stm32_qspi {
struct device *dev;
struct spi_controller *ctrl;
phys_addr_t phys_base;
void __iomem *io_base;
void __iomem *mm_base;
resource_size_t mm_size;
struct clk *clk;
u32 clk_rate;
struct stm32_qspi_flash flash[STM32_QSPI_MAX_NORCHIP];
struct completion match_completion;
u32 fmode;
struct dma_chan *dma_chtx;
struct dma_chan *dma_chrx;
struct completion dma_completion;
u32 cr_reg;
u32 dcr_reg;
unsigned long status_timeout;
/*
* to protect device configuration, could be different between
* 2 flash access (bk1, bk2)
*/
struct mutex lock;
};
static irqreturn_t stm32_qspi_irq(int irq, void *dev_id)
{
struct stm32_qspi *qspi = (struct stm32_qspi *)dev_id;
u32 cr, sr;
cr = readl_relaxed(qspi->io_base + QSPI_CR);
sr = readl_relaxed(qspi->io_base + QSPI_SR);
if (sr & SR_SMF) {
/* disable irq */
cr &= ~CR_SMIE;
writel_relaxed(cr, qspi->io_base + QSPI_CR);
complete(&qspi->match_completion);
}
return IRQ_HANDLED;
}
static void stm32_qspi_read_fifo(void *val, void __iomem *addr, u8 len)
{
switch (len) {
case sizeof(u32):
*((u32 *)val) = readl_relaxed(addr);
break;
case sizeof(u16):
*((u16 *)val) = readw_relaxed(addr);
break;
case sizeof(u8):
*((u8 *)val) = readb_relaxed(addr);
}
}
static void stm32_qspi_write_fifo(void *val, void __iomem *addr, u8 len)
{
switch (len) {
case sizeof(u32):
writel_relaxed(*((u32 *)val), addr);
break;
case sizeof(u16):
writew_relaxed(*((u16 *)val), addr);
break;
case sizeof(u8):
writeb_relaxed(*((u8 *)val), addr);
}
}
static int stm32_qspi_tx_poll(struct stm32_qspi *qspi,
const struct spi_mem_op *op)
{
void (*fifo)(void *val, void __iomem *addr, u8 len);
u32 len = op->data.nbytes, sr;
void *buf;
int ret;
u8 step;
if (op->data.dir == SPI_MEM_DATA_IN) {
fifo = stm32_qspi_read_fifo;
Annotation
- Immediate include surface: `linux/bitfield.h`, `linux/clk.h`, `linux/dmaengine.h`, `linux/dma-mapping.h`, `linux/errno.h`, `linux/gpio/consumer.h`, `linux/io.h`, `linux/iopoll.h`.
- Detected declarations: `struct stm32_qspi_flash`, `struct stm32_qspi`, `function stm32_qspi_irq`, `function stm32_qspi_read_fifo`, `function stm32_qspi_write_fifo`, `function stm32_qspi_tx_poll`, `function stm32_qspi_tx_mm`, `function stm32_qspi_dma_callback`, `function stm32_qspi_tx_dma`, `function stm32_qspi_tx`.
- Atlas domain: Driver Families / drivers/spi.
- 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.