drivers/spi/spi-stm32-ospi.c
Source file repositories/reference/linux-study-clean/drivers/spi/spi-stm32-ospi.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/spi/spi-stm32-ospi.c- Extension
.c- Size
- 26447 bytes
- Lines
- 1088
- 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/delay.hlinux/dma-mapping.hlinux/dmaengine.hlinux/err.hlinux/errno.hlinux/gpio/consumer.hlinux/interrupt.hlinux/io.hlinux/iopoll.hlinux/mfd/syscon.hlinux/module.hlinux/mutex.hlinux/of.hlinux/of_address.hlinux/of_device.hlinux/of_reserved_mem.hlinux/pinctrl/consumer.hlinux/platform_device.hlinux/pm_runtime.hlinux/reset.hlinux/sizes.hlinux/spi/spi-mem.hlinux/types.h
Detected Declarations
struct stm32_ospifunction stm32_ospi_read_fifofunction stm32_ospi_write_fifofunction stm32_ospi_abortfunction stm32_ospi_pollfunction stm32_ospi_wait_nobusyfunction stm32_ospi_wait_cmdfunction stm32_ospi_dma_callbackfunction stm32_ospi_irqfunction stm32_ospi_dma_setupfunction stm32_ospi_tx_mmfunction stm32_ospi_tx_dmafunction stm32_ospi_xferfunction stm32_ospi_wait_poll_statusfunction stm32_ospi_get_modefunction stm32_ospi_sendfunction stm32_ospi_poll_statusfunction stm32_ospi_exec_opfunction stm32_ospi_dirmap_createfunction stm32_ospi_dirmap_readfunction stm32_ospi_transfer_one_messagefunction list_for_each_entryfunction stm32_ospi_setupfunction stm32_ospi_get_resourcesfunction stm32_ospi_probefunction stm32_ospi_removefunction stm32_ospi_suspendfunction stm32_ospi_resumefunction stm32_ospi_runtime_suspendfunction stm32_ospi_runtime_resume
Annotated Snippet
struct stm32_ospi {
struct device *dev;
struct spi_controller *ctrl;
struct clk *clk;
struct reset_control *rstc;
struct completion match_completion;
struct dma_chan *dma_chtx;
struct dma_chan *dma_chrx;
struct completion dma_completion;
void __iomem *regs_base;
void __iomem *mm_base;
phys_addr_t regs_phys_base;
resource_size_t mm_size;
u32 clk_rate;
u32 fmode;
u32 cr_reg;
u32 dcr_reg;
u32 flash_presc[STM32_OSPI_MAX_NORCHIP];
int irq;
unsigned long status_timeout;
/*
* To protect device configuration, could be different between
* 2 flash access
*/
struct mutex lock;
};
static void stm32_ospi_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_ospi_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_ospi_abort(struct stm32_ospi *ospi)
{
void __iomem *regs_base = ospi->regs_base;
u32 cr;
int timeout;
cr = readl_relaxed(regs_base + OSPI_CR) | CR_ABORT;
writel_relaxed(cr, regs_base + OSPI_CR);
/* wait clear of abort bit by hw */
timeout = readl_relaxed_poll_timeout_atomic(regs_base + OSPI_CR,
cr, !(cr & CR_ABORT), 1,
STM32_ABT_TIMEOUT_US);
if (timeout)
dev_err(ospi->dev, "%s abort timeout:%d\n", __func__, timeout);
return timeout;
}
static int stm32_ospi_poll(struct stm32_ospi *ospi, void *buf, u32 len, bool read)
{
void __iomem *regs_base = ospi->regs_base;
void (*fifo)(void *val, void __iomem *addr, u8 len);
u32 sr;
int ret;
u8 step;
if (read)
fifo = stm32_ospi_read_fifo;
else
Annotation
- Immediate include surface: `linux/bitfield.h`, `linux/clk.h`, `linux/delay.h`, `linux/dma-mapping.h`, `linux/dmaengine.h`, `linux/err.h`, `linux/errno.h`, `linux/gpio/consumer.h`.
- Detected declarations: `struct stm32_ospi`, `function stm32_ospi_read_fifo`, `function stm32_ospi_write_fifo`, `function stm32_ospi_abort`, `function stm32_ospi_poll`, `function stm32_ospi_wait_nobusy`, `function stm32_ospi_wait_cmd`, `function stm32_ospi_dma_callback`, `function stm32_ospi_irq`, `function stm32_ospi_dma_setup`.
- 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.