STRUCT SPI_CONTROLLER_MEM_OPS(9)
π struct spi_controller_mem_ops β SPI memory operations π
okay so bestie, this is a page from the Kernel API Manual and it's literally the cheat sheet for struct spi_controller_mem_ops. if you're writing a QSPI controller driver, this is your main character document. let's get into it β¨
π NAME π
struct spi_controller_mem_ops β SPI memory operations
πΈ SYNOPSIS πΈ
struct spi_controller_mem_ops {
int (*adjust_op_size)(struct spi_mem *mem, struct spi_mem_op *op);
bool (*supports_op)(struct spi_mem *mem, const struct spi_mem_op *op);
int (*exec_op)(struct spi_mem *mem, const struct spi_mem_op *op);
const char *(*get_name)(struct spi_mem *mem);
int (*dirmap_create)(struct spi_mem_dirmap_desc *desc);
void (*dirmap_destroy)(struct spi_mem_dirmap_desc *desc);
ssize_t (*dirmap_read)(struct spi_mem_dirmap_desc *desc, u64 offs, size_t len, void *buf);
ssize_t (*dirmap_write)(struct spi_mem_dirmap_desc *desc, u64 offs, size_t len, const void *buf);
int (*poll_status)(struct spi_mem *mem, const struct spi_mem_op *op, u16 mask, u16 match, unsigned long initial_delay_us, unsigned long polling_rate_us, unsigned long timeout_ms);
};
like, that's the whole vibe right there. nine function pointers, each one doing its little job π«Ά
π Members π
β¨ the function pointers, one by one β¨
adjust_op_sizeβ this one's job is to shrink the data xfer of an operation so it actually fits what your controller can handle. the limitations in question? could be alignment stuff, could be max RX/TX size stuff. either way, bestie, it's the vibe check for op sizes πsupports_opβ the literal question "is this operation supported by the controller?" yes or no, queen πexec_opβ executes a SPI memory operation. okay so hear me: not all driver providessupports_op, so this one can return-EOPNOTSUPPif the op isn't supported by the driver/controller. no cap, that's the escape hatch π«Άget_nameβ grabs a custom name for the SPI mem device straight from the controller. why would you need this? because if the controller driver has been ported to use the SPI mem layer and a custom name is used to keepmtdpartscompatible, you gotta preserve that name. IMPORTANT NOTE: if your implementation of this function allocates memory dynamically, then it should do so withdevm_xxx, because we don't have a->free_namefunction π so like, don't leak, bestie πdirmap_createβ creates a direct mapping descriptor that can later be used to access the memory device. this method is optional, so no pressure πΈdirmap_destroyβ destroys a memory descriptor previous created by->dirmap_create. cleanup era π§Ήdirmap_readβ reads data from the memory device using the direct mapping created by->dirmap_create. okay so the tea here: the function can return less data than requested (for example when the request is crossing the currently mapped area), and in that case the caller ofspi_mem_dirmap_readis responsible for calling it again. so it's a "come back, i'm not done" situation πdirmap_writeβ writes data to the memory device using the direct mapping created by->dirmap_create. same deal fr fr: the function can return less data than requested (for example when the request is crossing the currently mapped area), and the caller ofspi_mem_dirmap_writeis responsible for calling it again in this case. icon behaviour, honestly πpoll_statusβ polls the memory device status until(status & mask) == matchor when the timeout has expired. it fills the data buffer with the last status value. so you always know what the final answer was β
π¦ Description π¦
so this interface should be implemented by SPI controllers that provide a high-level interface to execute SPI memory operation β which is usually the case for QSPI controllers π
π Note on ->dirmap_{read,write}(): drivers should avoid accessing the direct mapping from the CPU, because doing that can stall the CPU waiting for the SPI mem transaction to finish β and that will make real-time maintainers unhappy π€ and might make your system less reactive. Instead, drivers should use DMA to access this direct mapping. periodt. π
like genuinely, don't do the CPU thing. it's giving "why is my system laggy". use DMA, slay, move on π«Ά
β SEE ALSO β
Kernel file ./include/linux/spi/spi-mem.h, enum spi_mem_data_dir(9), struct spi_mem_op(9), struct spi_mem_dirmap_info(9), struct spi_mem_dirmap_desc(9), struct spi_mem(9), spi_mem_set_drvdata(9), spi_mem_get_drvdata(9), struct spi_controller_mem_caps(9), struct spi_mem_driver(9)
go read those next, bestie, they're all connected iykyk π¦
and that's the whole page π it lives in ./include/linux/spi in the kernel tree, it's part of the Kernel API Manual, and this particular copy is dated October 2026. go forth and write a good QSPI driver, you absolute icon πβ¨π
π¦ 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