drivers/spi/spi-mxs.c
Source file repositories/reference/linux-study-clean/drivers/spi/spi-mxs.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/spi/spi-mxs.c- Extension
.c- Size
- 16352 bytes
- Lines
- 676
- 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/kernel.hlinux/ioport.hlinux/of.hlinux/of_device.hlinux/platform_device.hlinux/delay.hlinux/interrupt.hlinux/dma-mapping.hlinux/dmaengine.hlinux/highmem.hlinux/clk.hlinux/err.hlinux/completion.hlinux/pinctrl/consumer.hlinux/regulator/consumer.hlinux/pm_runtime.hlinux/module.hlinux/stmp_device.hlinux/spi/spi.hlinux/spi/mxs-spi.htrace/events/spi.hlinux/dma/mxs-dma.h
Detected Declarations
struct mxs_spifunction mxs_spi_setup_transferfunction mxs_spi_cs_to_regfunction mxs_ssp_waitfunction mxs_ssp_dma_irq_callbackfunction mxs_ssp_irq_handlerfunction mxs_spi_txrx_dmafunction mxs_spi_txrx_piofunction mxs_spi_transfer_onefunction list_for_each_entryfunction mxs_spi_runtime_suspendfunction mxs_spi_runtime_resumefunction mxs_spi_suspendfunction mxs_spi_resumefunction mxs_spi_probefunction mxs_spi_remove
Annotated Snippet
struct mxs_spi {
struct mxs_ssp ssp;
struct completion c;
unsigned int sck; /* Rate requested (vs actual) */
};
static int mxs_spi_setup_transfer(struct spi_device *dev,
const struct spi_transfer *t)
{
struct mxs_spi *spi = spi_controller_get_devdata(dev->controller);
struct mxs_ssp *ssp = &spi->ssp;
const unsigned int hz = min(dev->max_speed_hz, t->speed_hz);
if (hz == 0) {
dev_err(&dev->dev, "SPI clock rate of zero not allowed\n");
return -EINVAL;
}
if (hz != spi->sck) {
mxs_ssp_set_clk_rate(ssp, hz);
/*
* Save requested rate, hz, rather than the actual rate,
* ssp->clk_rate. Otherwise we would set the rate every transfer
* when the actual rate is not quite the same as requested rate.
*/
spi->sck = hz;
/*
* Perhaps we should return an error if the actual clock is
* nowhere close to what was requested?
*/
}
writel(BM_SSP_CTRL0_LOCK_CS,
ssp->base + HW_SSP_CTRL0 + STMP_OFFSET_REG_SET);
writel(BF_SSP_CTRL1_SSP_MODE(BV_SSP_CTRL1_SSP_MODE__SPI) |
BF_SSP_CTRL1_WORD_LENGTH(BV_SSP_CTRL1_WORD_LENGTH__EIGHT_BITS) |
((dev->mode & SPI_CPOL) ? BM_SSP_CTRL1_POLARITY : 0) |
((dev->mode & SPI_CPHA) ? BM_SSP_CTRL1_PHASE : 0),
ssp->base + HW_SSP_CTRL1(ssp));
writel(0x0, ssp->base + HW_SSP_CMD0);
writel(0x0, ssp->base + HW_SSP_CMD1);
return 0;
}
static u32 mxs_spi_cs_to_reg(unsigned cs)
{
u32 select = 0;
/*
* i.MX28 Datasheet: 17.10.1: HW_SSP_CTRL0
*
* The bits BM_SSP_CTRL0_WAIT_FOR_CMD and BM_SSP_CTRL0_WAIT_FOR_IRQ
* in HW_SSP_CTRL0 register do have multiple usage, please refer to
* the datasheet for further details. In SPI mode, they are used to
* toggle the chip-select lines (nCS pins).
*/
if (cs & 1)
select |= BM_SSP_CTRL0_WAIT_FOR_CMD;
if (cs & 2)
select |= BM_SSP_CTRL0_WAIT_FOR_IRQ;
return select;
}
static int mxs_ssp_wait(struct mxs_spi *spi, int offset, int mask, bool set)
{
const unsigned long timeout = jiffies + msecs_to_jiffies(SSP_TIMEOUT);
struct mxs_ssp *ssp = &spi->ssp;
u32 reg;
do {
reg = readl_relaxed(ssp->base + offset);
if (!set)
reg = ~reg;
reg &= mask;
if (reg == mask)
return 0;
} while (time_before(jiffies, timeout));
return -ETIMEDOUT;
}
static void mxs_ssp_dma_irq_callback(void *param)
{
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/ioport.h`, `linux/of.h`, `linux/of_device.h`, `linux/platform_device.h`, `linux/delay.h`, `linux/interrupt.h`, `linux/dma-mapping.h`.
- Detected declarations: `struct mxs_spi`, `function mxs_spi_setup_transfer`, `function mxs_spi_cs_to_reg`, `function mxs_ssp_wait`, `function mxs_ssp_dma_irq_callback`, `function mxs_ssp_irq_handler`, `function mxs_spi_txrx_dma`, `function mxs_spi_txrx_pio`, `function mxs_spi_transfer_one`, `function list_for_each_entry`.
- 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.