drivers/spi/spi-atcspi200.c
Source file repositories/reference/linux-study-clean/drivers/spi/spi-atcspi200.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/spi/spi-atcspi200.c- Extension
.c- Size
- 17890 bytes
- Lines
- 659
- 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/bitfield.hlinux/clk.hlinux/completion.hlinux/dev_printk.hlinux/dmaengine.hlinux/err.hlinux/errno.hlinux/jiffies.hlinux/minmax.hlinux/module.hlinux/mod_devicetable.hlinux/mutex.hlinux/platform_device.hlinux/regmap.hlinux/spi/spi.hlinux/spi/spi-mem.h
Detected Declarations
struct atcspi_devfunction atcspi_wait_fifo_readyfunction atcspi_xfer_data_pollfunction atcspi_set_trans_ctlfunction atcspi_set_trans_fmtfunction atcspi_prepare_transfunction atcspi_adjust_op_sizefunction atcspi_dma_configfunction atcspi_dma_callbackfunction atcspi_dma_transfunction atcspi_exec_mem_opfunction atcspi_setupfunction atcspi_init_resourcesfunction atcspi_configure_dmafunction atcspi_enable_clkfunction atcspi_init_controllerfunction atcspi_probefunction atcspi_suspendfunction atcspi_resume
Annotated Snippet
struct atcspi_dev {
struct spi_controller *host;
struct mutex mutex_lock;
struct completion dma_completion;
struct device *dev;
struct regmap *regmap;
struct clk *clk;
dma_addr_t dma_addr;
unsigned int clk_rate;
unsigned int sclk_rate;
unsigned int txfifo_size;
unsigned int rxfifo_size;
bool data_merge;
bool use_dma;
};
static int atcspi_wait_fifo_ready(struct atcspi_dev *spi,
enum spi_mem_data_dir dir)
{
unsigned int val;
unsigned int mask;
int ret;
mask = (dir == SPI_MEM_DATA_OUT) ? ATCSPI_TX_FULL : ATCSPI_RX_EMPTY;
ret = regmap_read_poll_timeout(spi->regmap,
ATCSPI_STATUS,
val,
!(val & mask),
0,
ATCSPI_RDY_TIMEOUT_US);
if (ret)
dev_info(spi->dev, "Timed out waiting for FIFO ready\n");
return ret;
}
static int atcspi_xfer_data_poll(struct atcspi_dev *spi,
const struct spi_mem_op *op)
{
void *rx_buf = op->data.buf.in;
const void *tx_buf = op->data.buf.out;
unsigned int val;
int trans_bytes = op->data.nbytes;
int num_byte;
int ret = 0;
num_byte = spi->data_merge ? 4 : 1;
while (trans_bytes) {
if (op->data.dir == SPI_MEM_DATA_OUT) {
ret = atcspi_wait_fifo_ready(spi, SPI_MEM_DATA_OUT);
if (ret)
return ret;
if (spi->data_merge)
val = *(unsigned int *)tx_buf;
else
val = *(unsigned char *)tx_buf;
regmap_write(spi->regmap, ATCSPI_DATA, val);
tx_buf = (unsigned char *)tx_buf + num_byte;
} else {
ret = atcspi_wait_fifo_ready(spi, SPI_MEM_DATA_IN);
if (ret)
return ret;
regmap_read(spi->regmap, ATCSPI_DATA, &val);
if (spi->data_merge)
*(unsigned int *)rx_buf = val;
else
*(unsigned char *)rx_buf = (unsigned char)val;
rx_buf = (unsigned char *)rx_buf + num_byte;
}
trans_bytes -= num_byte;
}
return ret;
}
static void atcspi_set_trans_ctl(struct atcspi_dev *spi,
const struct spi_mem_op *op)
{
unsigned int tc = 0;
if (op->cmd.nbytes)
tc |= TRANS_CMD_EN;
if (op->addr.nbytes)
tc |= TRANS_ADDR_EN;
if (op->addr.buswidth > 1)
tc |= TRANS_ADDR_FMT;
if (op->data.nbytes) {
unsigned int width_code;
Annotation
- Immediate include surface: `linux/bitfield.h`, `linux/clk.h`, `linux/completion.h`, `linux/dev_printk.h`, `linux/dmaengine.h`, `linux/err.h`, `linux/errno.h`, `linux/jiffies.h`.
- Detected declarations: `struct atcspi_dev`, `function atcspi_wait_fifo_ready`, `function atcspi_xfer_data_poll`, `function atcspi_set_trans_ctl`, `function atcspi_set_trans_fmt`, `function atcspi_prepare_trans`, `function atcspi_adjust_op_size`, `function atcspi_dma_config`, `function atcspi_dma_callback`, `function atcspi_dma_trans`.
- 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.