drivers/spi/spi-microchip-core-qspi.c
Source file repositories/reference/linux-study-clean/drivers/spi/spi-microchip-core-qspi.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/spi/spi-microchip-core-qspi.c- Extension
.c- Size
- 23751 bytes
- Lines
- 834
- 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/clk.hlinux/err.hlinux/init.hlinux/interrupt.hlinux/io.hlinux/iopoll.hlinux/module.hlinux/of.hlinux/of_irq.hlinux/platform_device.hlinux/spi/spi.hlinux/spi/spi-mem.h
Detected Declarations
struct mchp_coreqspifunction mchp_coreqspi_set_modefunction mchp_coreqspi_set_csfunction mchp_coreqspi_setupfunction mchp_coreqspi_read_opfunction mchp_coreqspi_write_opfunction mchp_coreqspi_write_read_opfunction mchp_coreqspi_enable_intsfunction mchp_coreqspi_disable_intsfunction mchp_coreqspi_isrfunction mchp_coreqspi_setup_clockfunction mchp_coreqspi_config_opfunction mchp_coreqspi_wait_for_readyfunction mchp_coreqspi_exec_opfunction mchp_coreqspi_supports_opfunction mchp_coreqspi_adjust_op_sizefunction mchp_coreqspi_unprepare_messagefunction mchp_coreqspi_prepare_messagefunction list_for_each_entryfunction mchp_coreqspi_transfer_onefunction mchp_coreqspi_probefunction mchp_coreqspi_remove
Annotated Snippet
struct mchp_coreqspi {
void __iomem *regs;
struct clk *clk;
struct completion data_completion;
struct mutex op_lock; /* lock access to the device */
u8 *txbuf;
u8 *rxbuf;
int irq;
int tx_len;
int rx_len;
};
static int mchp_coreqspi_set_mode(struct mchp_coreqspi *qspi, const struct spi_mem_op *op)
{
u32 control = readl_relaxed(qspi->regs + REG_CONTROL);
/*
* The operating mode can be configured based on the command that needs to be send.
* bits[15:14]: Sets whether multiple bit SPI operates in normal, extended or full modes.
* 00: Normal (single DQ0 TX and single DQ1 RX lines)
* 01: Extended RO (command and address bytes on DQ0 only)
* 10: Extended RW (command byte on DQ0 only)
* 11: Full. (command and address are on all DQ lines)
* bit[13]: Sets whether multiple bit SPI uses 2 or 4 bits of data
* 0: 2-bits (BSPI)
* 1: 4-bits (QSPI)
*/
if (op->data.buswidth == 4 || op->data.buswidth == 2) {
control &= ~CONTROL_MODE12_MASK;
if (op->cmd.buswidth == 1 && (op->addr.buswidth == 1 || op->addr.buswidth == 0))
control |= CONTROL_MODE12_EX_RO;
else if (op->cmd.buswidth == 1)
control |= CONTROL_MODE12_EX_RW;
else
control |= CONTROL_MODE12_FULL;
control |= CONTROL_MODE0;
} else {
control &= ~(CONTROL_MODE12_MASK |
CONTROL_MODE0);
}
writel_relaxed(control, qspi->regs + REG_CONTROL);
return 0;
}
static void mchp_coreqspi_set_cs(struct spi_device *spi, bool enable)
{
struct mchp_coreqspi *qspi = spi_controller_get_devdata(spi->controller);
u32 val;
val = readl(qspi->regs + REG_DIRECT_ACCESS);
val &= ~DIRECT_ACCESS_OP_SSEL;
val |= !enable << DIRECT_ACCESS_OP_SSEL_SHIFT;
writel(val, qspi->regs + REG_DIRECT_ACCESS);
}
static int mchp_coreqspi_setup(struct spi_device *spi)
{
struct mchp_coreqspi *qspi = spi_controller_get_devdata(spi->controller);
u32 val;
/*
* Active low devices need to be specifically set to their inactive
* states during probe.
*/
if (spi->mode & SPI_CS_HIGH)
return 0;
val = readl(qspi->regs + REG_DIRECT_ACCESS);
val |= DIRECT_ACCESS_OP_SSEL;
writel(val, qspi->regs + REG_DIRECT_ACCESS);
return 0;
}
static void mchp_coreqspi_read_op(struct mchp_coreqspi *qspi)
{
u32 control, data;
if (!qspi->rx_len)
return;
control = readl_relaxed(qspi->regs + REG_CONTROL);
/*
* Read 4-bytes from the SPI FIFO in single transaction and then read
Annotation
- Immediate include surface: `linux/clk.h`, `linux/err.h`, `linux/init.h`, `linux/interrupt.h`, `linux/io.h`, `linux/iopoll.h`, `linux/module.h`, `linux/of.h`.
- Detected declarations: `struct mchp_coreqspi`, `function mchp_coreqspi_set_mode`, `function mchp_coreqspi_set_cs`, `function mchp_coreqspi_setup`, `function mchp_coreqspi_read_op`, `function mchp_coreqspi_write_op`, `function mchp_coreqspi_write_read_op`, `function mchp_coreqspi_enable_ints`, `function mchp_coreqspi_disable_ints`, `function mchp_coreqspi_isr`.
- 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.