drivers/spi/spi-mem.c
Source file repositories/reference/linux-study-clean/drivers/spi/spi-mem.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/spi/spi-mem.c- Extension
.c- Size
- 31539 bytes
- Lines
- 1120
- Domain
- Driver Families
- Bucket
- drivers/spi
- Inferred role
- Driver Families: operation-table or driver-model contract
- Status
- pattern 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.
- Defines an operation table; this is where Linux turns generic core objects into subsystem-specific behavior.
- 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/dmaengine.hlinux/iopoll.hlinux/pm_runtime.hlinux/spi/spi.hlinux/spi/spi-mem.hlinux/sched/task_stack.htrace/events/spi-mem.hinternals.h
Detected Declarations
function Copyrightfunction spi_controller_dma_unmap_mem_op_datafunction spi_check_buswidth_reqfunction spi_mem_check_buswidthfunction spi_mem_default_supports_opfunction spi_mem_buswidth_is_validfunction spi_mem_check_opfunction spi_mem_internal_supports_opfunction spi_mem_supports_opfunction spi_mem_access_startfunction spi_mem_access_endfunction spi_mem_add_op_statsfunction spi_mem_exec_opfunction pathsfunction spi_mem_get_namefunction spi_mem_adjust_op_sizefunction spi_mem_adjust_op_freqfunction spi_mem_calc_op_durationfunction spi_mem_no_dirmap_readfunction spi_mem_no_dirmap_writefunction spi_mem_dirmap_createfunction spi_mem_dirmap_destroyfunction devm_spi_mem_dirmap_releasefunction devm_spi_mem_dirmap_createfunction devm_spi_mem_dirmap_matchfunction devm_spi_mem_dirmap_destroyfunction spi_mem_dirmap_readfunction spi_mem_dirmap_writefunction spi_mem_read_statusfunction spi_mem_poll_statusfunction spi_mem_probefunction spi_mem_removefunction spi_mem_shutdownfunction spi_mem_driver_register_with_ownerfunction spi_mem_driver_unregisterexport spi_controller_dma_map_mem_op_dataexport spi_controller_dma_unmap_mem_op_dataexport spi_mem_default_supports_opexport spi_mem_supports_opexport spi_mem_exec_opexport spi_mem_get_nameexport spi_mem_adjust_op_sizeexport spi_mem_adjust_op_freqexport spi_mem_calc_op_durationexport spi_mem_dirmap_createexport spi_mem_dirmap_destroyexport devm_spi_mem_dirmap_createexport devm_spi_mem_dirmap_destroy
Annotated Snippet
static inline struct spi_mem_driver *to_spi_mem_drv(struct device_driver *drv)
{
return container_of(drv, struct spi_mem_driver, spidrv.driver);
}
static int spi_mem_read_status(struct spi_mem *mem,
const struct spi_mem_op *op,
u16 *status)
{
const u8 *bytes = (u8 *)op->data.buf.in;
int ret;
ret = spi_mem_exec_op(mem, op);
if (ret)
return ret;
if (op->data.nbytes > 1)
*status = ((u16)bytes[0] << 8) | bytes[1];
else
*status = bytes[0];
return 0;
}
/**
* spi_mem_poll_status() - Poll memory device status
* @mem: SPI memory device
* @op: the memory operation to execute
* @mask: status bitmask to ckeck
* @match: (status & mask) expected value
* @initial_delay_us: delay in us before starting to poll
* @polling_delay_us: time to sleep between reads in us
* @timeout_ms: timeout in milliseconds
*
* This function polls a status register and returns when
* (status & mask) == match or when the timeout has expired.
*
* Return: 0 in case of success, -ETIMEDOUT in case of error,
* -EOPNOTSUPP if not supported.
*/
int spi_mem_poll_status(struct spi_mem *mem,
const struct spi_mem_op *op,
u16 mask, u16 match,
unsigned long initial_delay_us,
unsigned long polling_delay_us,
u16 timeout_ms)
{
struct spi_controller *ctlr = mem->spi->controller;
int ret = -EOPNOTSUPP;
int read_status_ret;
u16 status;
if (op->data.nbytes < 1 || op->data.nbytes > 2 ||
op->data.dir != SPI_MEM_DATA_IN)
return -EINVAL;
if (ctlr->mem_ops && ctlr->mem_ops->poll_status && !spi_get_csgpiod(mem->spi, 0)) {
ret = spi_mem_access_start(mem);
if (ret)
return ret;
ret = ctlr->mem_ops->poll_status(mem, op, mask, match,
initial_delay_us, polling_delay_us,
timeout_ms);
spi_mem_access_end(mem);
}
if (ret == -EOPNOTSUPP) {
if (!spi_mem_supports_op(mem, op))
return ret;
if (initial_delay_us < 10)
udelay(initial_delay_us);
else
usleep_range((initial_delay_us >> 2) + 1,
initial_delay_us);
ret = read_poll_timeout(spi_mem_read_status, read_status_ret,
(read_status_ret || ((status) & mask) == match),
polling_delay_us, timeout_ms * 1000, false, mem,
op, &status);
if (read_status_ret)
return read_status_ret;
}
return ret;
}
EXPORT_SYMBOL_GPL(spi_mem_poll_status);
Annotation
- Immediate include surface: `linux/dmaengine.h`, `linux/iopoll.h`, `linux/pm_runtime.h`, `linux/spi/spi.h`, `linux/spi/spi-mem.h`, `linux/sched/task_stack.h`, `trace/events/spi-mem.h`, `internals.h`.
- Detected declarations: `function Copyright`, `function spi_controller_dma_unmap_mem_op_data`, `function spi_check_buswidth_req`, `function spi_mem_check_buswidth`, `function spi_mem_default_supports_op`, `function spi_mem_buswidth_is_valid`, `function spi_mem_check_op`, `function spi_mem_internal_supports_op`, `function spi_mem_supports_op`, `function spi_mem_access_start`.
- Atlas domain: Driver Families / drivers/spi.
- Implementation status: pattern 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.