drivers/spi/spi-nxp-xspi.c

Source file repositories/reference/linux-study-clean/drivers/spi/spi-nxp-xspi.c

File Facts

System
Linux kernel
Corpus path
drivers/spi/spi-nxp-xspi.c
Extension
.c
Size
37038 bytes
Lines
1382
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.

Dependency Surface

Detected Declarations

Annotated Snippet

struct nxp_xspi_devtype_data {
	unsigned int rxfifo;
	unsigned int txfifo;
	unsigned int ahb_buf_size;
	unsigned int quirks;
};

static struct nxp_xspi_devtype_data imx94_data = {
	.rxfifo = SZ_512,       /* (128 * 4 bytes)  */
	.txfifo = SZ_1K,        /* (256 * 4 bytes)  */
	.ahb_buf_size = SZ_4K,  /* (1024 * 4 bytes)  */
};

struct nxp_xspi {
	void __iomem *iobase;
	void __iomem *ahb_addr;
	u32 memmap_phy;
	u32 memmap_phy_size;
	u32 memmap_start;
	u32 memmap_len;
	struct clk *clk;
	struct device *dev;
	struct completion c;
	const struct nxp_xspi_devtype_data *devtype_data;
	/* mutex lock for each operation */
	struct mutex lock;
	int selected;
#define XSPI_DTR_PROTO		BIT(0)
	int flags;
	/* Save the previous operation clock rate */
	unsigned long pre_op_rate;
	/* The max clock rate xspi supported output to device */
	unsigned long support_max_rate;
};

static inline int needs_ip_only(struct nxp_xspi *xspi)
{
	return xspi->devtype_data->quirks & XSPI_QUIRK_USE_IP_ONLY;
}

static irqreturn_t nxp_xspi_irq_handler(int irq, void *dev_id)
{
	struct nxp_xspi *xspi = dev_id;
	u32 reg;

	reg = readl(xspi->iobase + XSPI_FR);
	if (reg & XSPI_FR_TFF) {
		/* Clear interrupt */
		writel(XSPI_FR_TFF, xspi->iobase + XSPI_FR);
		complete(&xspi->c);
		return IRQ_HANDLED;
	}

	return IRQ_NONE;
}

static int nxp_xspi_check_buswidth(struct nxp_xspi *xspi, u8 width)
{
	return (is_power_of_2(width) && width <= 8) ? 0 : -EOPNOTSUPP;
}

static bool nxp_xspi_supports_op(struct spi_mem *mem,
				 const struct spi_mem_op *op)
{
	struct nxp_xspi *xspi = spi_controller_get_devdata(mem->spi->controller);
	int ret;

	ret = nxp_xspi_check_buswidth(xspi, op->cmd.buswidth);

	if (op->addr.nbytes)
		ret |= nxp_xspi_check_buswidth(xspi, op->addr.buswidth);

	if (op->dummy.nbytes)
		ret |= nxp_xspi_check_buswidth(xspi, op->dummy.buswidth);

	if (op->data.nbytes)
		ret |= nxp_xspi_check_buswidth(xspi, op->data.buswidth);

	if (ret)
		return false;

	/*
	 * The number of address bytes should be equal to or less than 4 bytes.
	 */
	if (op->addr.nbytes > 4)
		return false;

	/* Max 32 dummy clock cycles supported */
	if (op->dummy.buswidth &&
	    (op->dummy.nbytes * 8 / op->dummy.buswidth > 64))

Annotation

Implementation Notes