drivers/spi/spi-fsl-espi.c
Source file repositories/reference/linux-study-clean/drivers/spi/spi-fsl-espi.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/spi/spi-fsl-espi.c- Extension
.c- Size
- 21583 bytes
- Lines
- 842
- 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/delay.hlinux/err.hlinux/fsl_devices.hlinux/interrupt.hlinux/module.hlinux/mm.hlinux/of.hlinux/of_address.hlinux/of_irq.hlinux/of_platform.hlinux/platform_device.hlinux/spi/spi.hlinux/pm_runtime.hsysdev/fsl_soc.h
Detected Declarations
struct fsl_espistruct fsl_espi_csfunction fsl_espi_read_regfunction fsl_espi_read_reg16function fsl_espi_read_reg8function fsl_espi_write_regfunction fsl_espi_write_reg16function fsl_espi_write_reg8function fsl_espi_check_messagefunction list_for_each_entryfunction fsl_espi_check_rxskip_modefunction fsl_espi_fill_tx_fifofunction fsl_espi_read_rx_fifofunction fsl_espi_setup_transferfunction fsl_espi_bufsfunction fsl_espi_transfunction fsl_espi_do_one_msgfunction list_for_each_entryfunction fsl_espi_setupfunction fsl_espi_cleanupfunction fsl_espi_cpu_irqfunction fsl_espi_irqfunction fsl_espi_runtime_suspendfunction fsl_espi_runtime_resumefunction fsl_espi_max_message_sizefunction fsl_espi_init_regsfunction fsl_espi_probefunction of_fsl_espi_get_chipselectsfunction of_fsl_espi_probefunction of_fsl_espi_removefunction of_fsl_espi_suspendfunction of_fsl_espi_resume
Annotated Snippet
struct fsl_espi {
struct device *dev;
void __iomem *reg_base;
struct list_head *m_transfers;
struct spi_transfer *tx_t;
unsigned int tx_pos;
bool tx_done;
struct spi_transfer *rx_t;
unsigned int rx_pos;
bool rx_done;
bool swab;
unsigned int rxskip;
spinlock_t lock;
u32 spibrg; /* SPIBRG input clock */
struct completion done;
};
struct fsl_espi_cs {
u32 hw_mode;
};
static inline u32 fsl_espi_read_reg(struct fsl_espi *espi, int offset)
{
return ioread32be(espi->reg_base + offset);
}
static inline u16 fsl_espi_read_reg16(struct fsl_espi *espi, int offset)
{
return ioread16be(espi->reg_base + offset);
}
static inline u8 fsl_espi_read_reg8(struct fsl_espi *espi, int offset)
{
return ioread8(espi->reg_base + offset);
}
static inline void fsl_espi_write_reg(struct fsl_espi *espi, int offset,
u32 val)
{
iowrite32be(val, espi->reg_base + offset);
}
static inline void fsl_espi_write_reg16(struct fsl_espi *espi, int offset,
u16 val)
{
iowrite16be(val, espi->reg_base + offset);
}
static inline void fsl_espi_write_reg8(struct fsl_espi *espi, int offset,
u8 val)
{
iowrite8(val, espi->reg_base + offset);
}
static int fsl_espi_check_message(struct spi_message *m)
{
struct fsl_espi *espi = spi_controller_get_devdata(m->spi->controller);
struct spi_transfer *t, *first;
if (m->frame_length > SPCOM_TRANLEN_MAX) {
dev_err(espi->dev, "message too long, size is %u bytes\n",
m->frame_length);
return -EMSGSIZE;
}
first = list_first_entry(&m->transfers, struct spi_transfer,
transfer_list);
list_for_each_entry(t, &m->transfers, transfer_list) {
if (first->bits_per_word != t->bits_per_word ||
first->speed_hz != t->speed_hz) {
dev_err(espi->dev, "bits_per_word/speed_hz should be the same for all transfers\n");
return -EINVAL;
}
}
/* ESPI supports MSB-first transfers for word size 8 / 16 only */
if (!(m->spi->mode & SPI_LSB_FIRST) && first->bits_per_word != 8 &&
first->bits_per_word != 16) {
dev_err(espi->dev,
"MSB-first transfer not supported for wordsize %u\n",
first->bits_per_word);
return -EINVAL;
}
Annotation
- Immediate include surface: `linux/delay.h`, `linux/err.h`, `linux/fsl_devices.h`, `linux/interrupt.h`, `linux/module.h`, `linux/mm.h`, `linux/of.h`, `linux/of_address.h`.
- Detected declarations: `struct fsl_espi`, `struct fsl_espi_cs`, `function fsl_espi_read_reg`, `function fsl_espi_read_reg16`, `function fsl_espi_read_reg8`, `function fsl_espi_write_reg`, `function fsl_espi_write_reg16`, `function fsl_espi_write_reg8`, `function fsl_espi_check_message`, `function list_for_each_entry`.
- 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.