drivers/spi/spi-xlp.c
Source file repositories/reference/linux-study-clean/drivers/spi/spi-xlp.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/spi/spi-xlp.c- Extension
.c- Size
- 11229 bytes
- Lines
- 448
- 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.
- 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/acpi.hlinux/clk.hlinux/kernel.hlinux/module.hlinux/platform_device.hlinux/spi/spi.hlinux/interrupt.h
Detected Declarations
struct xlp_spi_privfunction xlp_spi_reg_readfunction xlp_spi_reg_writefunction xlp_spi_sysctl_writefunction xlp_spi_sysctl_setupfunction xlp_spi_setupfunction xlp_spi_read_rxfifofunction xlp_spi_fill_txfifofunction xlp_spi_interruptfunction xlp_spi_send_cmdfunction xlp_spi_xfer_blockfunction xlp_spi_txrx_bufsfunction xlp_spi_transfer_onefunction xlp_spi_probe
Annotated Snippet
struct xlp_spi_priv {
struct device dev; /* device structure */
void __iomem *base; /* spi registers base address */
const u8 *tx_buf; /* tx data buffer */
u8 *rx_buf; /* rx data buffer */
int tx_len; /* tx xfer length */
int rx_len; /* rx xfer length */
int txerrors; /* TXFIFO underflow count */
int rxerrors; /* RXFIFO overflow count */
int cs; /* target device chip select */
u32 spi_clk; /* spi clock frequency */
bool cmd_cont; /* cs active */
struct completion done; /* completion notification */
};
static inline u32 xlp_spi_reg_read(struct xlp_spi_priv *priv,
int cs, int regoff)
{
return readl(priv->base + regoff + cs * SPI_CS_OFFSET);
}
static inline void xlp_spi_reg_write(struct xlp_spi_priv *priv, int cs,
int regoff, u32 val)
{
writel(val, priv->base + regoff + cs * SPI_CS_OFFSET);
}
static inline void xlp_spi_sysctl_write(struct xlp_spi_priv *priv,
int regoff, u32 val)
{
writel(val, priv->base + regoff);
}
/*
* Setup global SPI_SYSCTRL register for all SPI channels.
*/
static void xlp_spi_sysctl_setup(struct xlp_spi_priv *xspi)
{
int cs;
for (cs = 0; cs < XLP_SPI_MAX_CS; cs++)
xlp_spi_sysctl_write(xspi, XLP_SPI_SYSCTRL,
XLP_SPI_SYS_RESET << cs);
xlp_spi_sysctl_write(xspi, XLP_SPI_SYSCTRL, XLP_SPI_SYS_PMEN);
}
static int xlp_spi_setup(struct spi_device *spi)
{
struct xlp_spi_priv *xspi;
u32 fdiv, cfg;
int cs;
xspi = spi_controller_get_devdata(spi->controller);
cs = spi_get_chipselect(spi, 0);
/*
* The value of fdiv must be between 4 and 65535.
*/
fdiv = DIV_ROUND_UP(xspi->spi_clk, spi->max_speed_hz);
if (fdiv > XLP_SPI_FDIV_MAX)
fdiv = XLP_SPI_FDIV_MAX;
else if (fdiv < XLP_SPI_FDIV_MIN)
fdiv = XLP_SPI_FDIV_MIN;
xlp_spi_reg_write(xspi, cs, XLP_SPI_FDIV, fdiv);
xlp_spi_reg_write(xspi, cs, XLP_SPI_FIFO_THRESH, XLP_SPI_TXRXTH);
cfg = xlp_spi_reg_read(xspi, cs, XLP_SPI_CONFIG);
if (spi->mode & SPI_CPHA)
cfg |= XLP_SPI_CPHA;
else
cfg &= ~XLP_SPI_CPHA;
if (spi->mode & SPI_CPOL)
cfg |= XLP_SPI_CPOL;
else
cfg &= ~XLP_SPI_CPOL;
if (!(spi->mode & SPI_CS_HIGH))
cfg |= XLP_SPI_CS_POL;
else
cfg &= ~XLP_SPI_CS_POL;
if (spi->mode & SPI_LSB_FIRST)
cfg |= XLP_SPI_CS_LSBFE;
else
cfg &= ~XLP_SPI_CS_LSBFE;
cfg |= XLP_SPI_TXMOSI_EN | XLP_SPI_RXMISO_EN;
if (fdiv == 4)
cfg |= XLP_SPI_RXCAP_EN;
xlp_spi_reg_write(xspi, cs, XLP_SPI_CONFIG, cfg);
return 0;
}
Annotation
- Immediate include surface: `linux/acpi.h`, `linux/clk.h`, `linux/kernel.h`, `linux/module.h`, `linux/platform_device.h`, `linux/spi/spi.h`, `linux/interrupt.h`.
- Detected declarations: `struct xlp_spi_priv`, `function xlp_spi_reg_read`, `function xlp_spi_reg_write`, `function xlp_spi_sysctl_write`, `function xlp_spi_sysctl_setup`, `function xlp_spi_setup`, `function xlp_spi_read_rxfifo`, `function xlp_spi_fill_txfifo`, `function xlp_spi_interrupt`, `function xlp_spi_send_cmd`.
- Atlas domain: Driver Families / drivers/spi.
- Implementation status: source 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.