drivers/spi/spi-falcon.c
Source file repositories/reference/linux-study-clean/drivers/spi/spi-falcon.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/spi/spi-falcon.c- Extension
.c- Size
- 10383 bytes
- Lines
- 429
- 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/module.hlinux/device.hlinux/platform_device.hlinux/spi/spi.hlinux/delay.hlinux/of.hlinux/of_platform.hlantiq_soc.h
Detected Declarations
struct falcon_sflashfunction falcon_sflash_xferfunction falcon_sflash_setupfunction falcon_sflash_xfer_onefunction falcon_sflash_probe
Annotated Snippet
struct falcon_sflash {
u32 sfcmd; /* for caching of opcode, direction, ... */
struct spi_controller *host;
};
static int
falcon_sflash_xfer(struct spi_device *spi, struct spi_transfer *t,
unsigned long flags)
{
struct device *dev = &spi->dev;
struct falcon_sflash *priv = spi_controller_get_devdata(spi->controller);
const u8 *txp = t->tx_buf;
u8 *rxp = t->rx_buf;
unsigned int bytelen = ((8 * t->len + 7) / 8);
unsigned int len, alen, dumlen;
u32 val;
enum {
state_init,
state_command_prepare,
state_write,
state_read,
state_disable_cs,
state_end
} state = state_init;
do {
switch (state) {
case state_init: /* detect phase of upper layer sequence */
{
/* initial write ? */
if (flags & FALCON_SPI_XFER_BEGIN) {
if (!txp) {
dev_err(dev,
"BEGIN without tx data!\n");
return -ENODATA;
}
/*
* Prepare the parts of the sfcmd register,
* which should not change during a sequence!
* Only exception are the length fields,
* especially alen and dumlen.
*/
priv->sfcmd = ((spi_get_chipselect(spi, 0)
<< SFCMD_CS_OFFSET)
& SFCMD_CS_MASK);
priv->sfcmd |= SFCMD_KEEP_CS_KEEP_SELECTED;
priv->sfcmd |= *txp;
txp++;
bytelen--;
if (bytelen) {
/*
* more data:
* maybe address and/or dummy
*/
state = state_command_prepare;
break;
} else {
dev_dbg(dev, "write cmd %02X\n",
priv->sfcmd & SFCMD_OPC_MASK);
}
}
/* continued write ? */
if (txp && bytelen) {
state = state_write;
break;
}
/* read data? */
if (rxp && bytelen) {
state = state_read;
break;
}
/* end of sequence? */
if (flags & FALCON_SPI_XFER_END)
state = state_disable_cs;
else
state = state_end;
break;
}
/* collect tx data for address and dummy phase */
case state_command_prepare:
{
/* txp is valid, already checked */
val = 0;
alen = 0;
dumlen = 0;
while (bytelen > 0) {
if (alen < 3) {
val = (val << 8) | (*txp++);
alen++;
Annotation
- Immediate include surface: `linux/module.h`, `linux/device.h`, `linux/platform_device.h`, `linux/spi/spi.h`, `linux/delay.h`, `linux/of.h`, `linux/of_platform.h`, `lantiq_soc.h`.
- Detected declarations: `struct falcon_sflash`, `function falcon_sflash_xfer`, `function falcon_sflash_setup`, `function falcon_sflash_xfer_one`, `function falcon_sflash_probe`.
- 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.
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.