drivers/spi/spi-dw-core.c
Source file repositories/reference/linux-study-clean/drivers/spi/spi-dw-core.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/spi/spi-dw-core.c- Extension
.c- Size
- 28602 bytes
- Lines
- 1065
- Domain
- Driver Families
- Bucket
- drivers/spi
- Inferred role
- Driver Families: exported/initcall integration point
- Status
- integration 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.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- 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/bitops.hlinux/dma-mapping.hlinux/interrupt.hlinux/module.hlinux/preempt.hlinux/highmem.hlinux/delay.hlinux/slab.hlinux/spi/spi.hlinux/spi/spi-mem.hlinux/string.hlinux/of.hinternals.hspi-dw.hlinux/debugfs.h
Detected Declarations
struct dw_spi_chip_datafunction dw_spi_debugfs_initfunction dw_spi_debugfs_removefunction dw_spi_debugfs_initfunction dw_spi_tx_maxfunction dw_spi_rx_maxfunction dw_writerfunction dw_readerfunction dw_spi_check_statusfunction dw_spi_transfer_handlerfunction dw_spi_irqfunction dw_spi_prepare_cr0function dw_spi_update_configfunction dw_spi_irq_setupfunction dw_spi_poll_transferfunction dw_spi_transfer_onefunction dw_spi_abortfunction dw_spi_handle_errfunction dw_spi_target_abortfunction dw_spi_adjust_mem_op_sizefunction dw_spi_supports_mem_opfunction dw_spi_init_mem_buffunction dw_spi_free_mem_buffunction dw_spi_write_then_readfunction dw_spi_ctlr_busyfunction dw_spi_wait_mem_op_donefunction dw_spi_stop_mem_opfunction dw_spi_exec_mem_opfunction dw_spi_init_mem_opsfunction dw_spi_setupfunction dw_spi_cleanupfunction dw_spi_hw_initfunction dw_spi_add_controllerfunction dw_spi_remove_controllerfunction dw_spi_suspend_controllerfunction dw_spi_resume_controller
Annotated Snippet
struct dw_spi_chip_data {
u32 cr0;
u32 rx_sample_dly; /* RX sample delay */
};
#ifdef CONFIG_DEBUG_FS
#define DW_SPI_DBGFS_REG(_name, _off) \
{ \
.name = _name, \
.offset = _off, \
}
static const struct debugfs_reg32 dw_spi_dbgfs_regs[] = {
DW_SPI_DBGFS_REG("CTRLR0", DW_SPI_CTRLR0),
DW_SPI_DBGFS_REG("CTRLR1", DW_SPI_CTRLR1),
DW_SPI_DBGFS_REG("SSIENR", DW_SPI_SSIENR),
DW_SPI_DBGFS_REG("SER", DW_SPI_SER),
DW_SPI_DBGFS_REG("BAUDR", DW_SPI_BAUDR),
DW_SPI_DBGFS_REG("TXFTLR", DW_SPI_TXFTLR),
DW_SPI_DBGFS_REG("RXFTLR", DW_SPI_RXFTLR),
DW_SPI_DBGFS_REG("TXFLR", DW_SPI_TXFLR),
DW_SPI_DBGFS_REG("RXFLR", DW_SPI_RXFLR),
DW_SPI_DBGFS_REG("SR", DW_SPI_SR),
DW_SPI_DBGFS_REG("IMR", DW_SPI_IMR),
DW_SPI_DBGFS_REG("ISR", DW_SPI_ISR),
DW_SPI_DBGFS_REG("DMACR", DW_SPI_DMACR),
DW_SPI_DBGFS_REG("DMATDLR", DW_SPI_DMATDLR),
DW_SPI_DBGFS_REG("DMARDLR", DW_SPI_DMARDLR),
DW_SPI_DBGFS_REG("RX_SAMPLE_DLY", DW_SPI_RX_SAMPLE_DLY),
};
static void dw_spi_debugfs_init(struct dw_spi *dws)
{
char name[32];
snprintf(name, 32, "dw_spi%d", dws->ctlr->bus_num);
dws->debugfs = debugfs_create_dir(name, NULL);
dws->regset.regs = dw_spi_dbgfs_regs;
dws->regset.nregs = ARRAY_SIZE(dw_spi_dbgfs_regs);
dws->regset.base = dws->regs;
debugfs_create_regset32("registers", 0400, dws->debugfs, &dws->regset);
}
static void dw_spi_debugfs_remove(struct dw_spi *dws)
{
debugfs_remove_recursive(dws->debugfs);
}
#else
static inline void dw_spi_debugfs_init(struct dw_spi *dws)
{
}
static inline void dw_spi_debugfs_remove(struct dw_spi *dws)
{
}
#endif /* CONFIG_DEBUG_FS */
void dw_spi_set_cs(struct spi_device *spi, bool enable)
{
struct dw_spi *dws = spi_controller_get_devdata(spi->controller);
bool cs_high = !!(spi->mode & SPI_CS_HIGH);
/*
* DW SPI controller demands any native CS being set in order to
* proceed with data transfer. So in order to activate the SPI
* communications we must set a corresponding bit in the Slave
* Enable register no matter whether the SPI core is configured to
* support active-high or active-low CS level.
*/
if (cs_high == enable)
dw_writel(dws, DW_SPI_SER, BIT(spi_get_chipselect(spi, 0)));
else
dw_writel(dws, DW_SPI_SER, 0);
}
EXPORT_SYMBOL_NS_GPL(dw_spi_set_cs, "SPI_DW_CORE");
/* Return the max entries we can fill into tx fifo */
static inline u32 dw_spi_tx_max(struct dw_spi *dws)
{
u32 tx_room, rxtx_gap;
tx_room = dws->fifo_len - dw_readl(dws, DW_SPI_TXFLR);
/*
* Another concern is about the tx/rx mismatch, we
* though to use (dws->fifo_len - rxflr - txflr) as
* one maximum value for tx, but it doesn't cover the
Annotation
- Immediate include surface: `linux/bitfield.h`, `linux/bitops.h`, `linux/dma-mapping.h`, `linux/interrupt.h`, `linux/module.h`, `linux/preempt.h`, `linux/highmem.h`, `linux/delay.h`.
- Detected declarations: `struct dw_spi_chip_data`, `function dw_spi_debugfs_init`, `function dw_spi_debugfs_remove`, `function dw_spi_debugfs_init`, `function dw_spi_tx_max`, `function dw_spi_rx_max`, `function dw_writer`, `function dw_reader`, `function dw_spi_check_status`, `function dw_spi_transfer_handler`.
- Atlas domain: Driver Families / drivers/spi.
- Implementation status: integration implementation candidate.
- 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.