drivers/spi/spi-sprd-adi.c

Source file repositories/reference/linux-study-clean/drivers/spi/spi-sprd-adi.c

File Facts

System
Linux kernel
Corpus path
drivers/spi/spi-sprd-adi.c
Extension
.c
Size
16455 bytes
Lines
639
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 sprd_adi_wdg {
	u32 base;
	u32 rst_sts;
	u32 wdg_en;
	u32 wdg_clk;
};

struct sprd_adi_data {
	u32 slave_offset;
	u32 slave_addr_size;
	int (*read_check)(u32 val, u32 reg);
	int (*restart)(struct sys_off_data *data);
	void (*wdg_rst)(void *p);
};

struct sprd_adi {
	struct spi_controller	*ctlr;
	struct device		*dev;
	void __iomem		*base;
	struct hwspinlock	*hwlock;
	unsigned long		slave_vbase;
	unsigned long		slave_pbase;
	const struct sprd_adi_data *data;
};

static int sprd_adi_check_addr(struct sprd_adi *sadi, u32 reg)
{
	if (reg >= sadi->data->slave_addr_size) {
		dev_err(sadi->dev,
			"slave address offset is incorrect, reg = 0x%x\n",
			reg);
		return -EINVAL;
	}

	return 0;
}

static int sprd_adi_drain_fifo(struct sprd_adi *sadi)
{
	u32 timeout = ADI_FIFO_DRAIN_TIMEOUT;
	u32 sts;

	do {
		sts = readl_relaxed(sadi->base + REG_ADI_ARM_FIFO_STS);
		if (sts & BIT_FIFO_EMPTY)
			break;

		cpu_relax();
	} while (--timeout);

	if (timeout == 0) {
		dev_err(sadi->dev, "drain write fifo timeout\n");
		return -EBUSY;
	}

	return 0;
}

static int sprd_adi_fifo_is_full(struct sprd_adi *sadi)
{
	return readl_relaxed(sadi->base + REG_ADI_ARM_FIFO_STS) & BIT_FIFO_FULL;
}

static int sprd_adi_read_check(u32 val, u32 addr)
{
	u32 rd_addr;

	rd_addr = (val & RD_ADDR_MASK) >> RD_ADDR_SHIFT;

	if (rd_addr != addr) {
		pr_err("ADI read error, addr = 0x%x, val = 0x%x\n", addr, val);
		return -EIO;
	}

	return 0;
}

static int sprd_adi_read_check_r2(u32 val, u32 reg)
{
	return sprd_adi_read_check(val, reg & RDBACK_ADDR_MASK_R2);
}

static int sprd_adi_read_check_r3(u32 val, u32 reg)
{
	return sprd_adi_read_check(val, (reg & RDBACK_ADDR_MASK_R3) >> RDBACK_ADDR_SHIFT_R3);
}

static int sprd_adi_read(struct sprd_adi *sadi, u32 reg, u32 *read_val)
{
	int read_timeout = ADI_READ_TIMEOUT;

Annotation

Implementation Notes