drivers/spi/spi-sh-msiof.c

Source file repositories/reference/linux-study-clean/drivers/spi/spi-sh-msiof.c

File Facts

System
Linux kernel
Corpus path
drivers/spi/spi-sh-msiof.c
Extension
.c
Size
34205 bytes
Lines
1350
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 sh_msiof_chipdata {
	u32 bits_per_word_mask;
	u16 tx_fifo_size;
	u16 rx_fifo_size;
	u16 ctlr_flags;
	u16 min_div_pow;
	u32 flags;
};

struct sh_msiof_spi_priv {
	struct spi_controller *ctlr;
	void __iomem *mapbase;
	struct clk *clk;
	struct platform_device *pdev;
	struct sh_msiof_spi_info *info;
	struct completion done;
	struct completion done_txdma;
	unsigned int tx_fifo_size;
	unsigned int rx_fifo_size;
	unsigned int min_div_pow;
	void *tx_dma_page;
	void *rx_dma_page;
	dma_addr_t tx_dma_addr;
	dma_addr_t rx_dma_addr;
	bool native_cs_inited;
	bool native_cs_high;
	bool target_aborted;
};

#define MAX_SS	3	/* Maximum number of native chip selects */

static u32 sh_msiof_read(struct sh_msiof_spi_priv *p, int reg_offs)
{
	switch (reg_offs) {
	case SITSCR:
	case SIRSCR:
		return ioread16(p->mapbase + reg_offs);
	default:
		return ioread32(p->mapbase + reg_offs);
	}
}

static void sh_msiof_write(struct sh_msiof_spi_priv *p, int reg_offs,
			   u32 value)
{
	switch (reg_offs) {
	case SITSCR:
	case SIRSCR:
		iowrite16(value, p->mapbase + reg_offs);
		break;
	default:
		iowrite32(value, p->mapbase + reg_offs);
		break;
	}
}

static int sh_msiof_modify_ctr_wait(struct sh_msiof_spi_priv *p,
				    u32 clr, u32 set)
{
	u32 mask = clr | set;
	u32 data;

	data = sh_msiof_read(p, SICTR);
	data &= ~clr;
	data |= set;
	sh_msiof_write(p, SICTR, data);

	return readl_poll_timeout_atomic(p->mapbase + SICTR, data,
					 (data & mask) == set, 1, 100);
}

static irqreturn_t sh_msiof_spi_irq(int irq, void *data)
{
	struct sh_msiof_spi_priv *p = data;

	/* just disable the interrupt and wake up */
	sh_msiof_write(p, SIIER, 0);
	complete(&p->done);

	return IRQ_HANDLED;
}

static void sh_msiof_spi_reset_regs(struct sh_msiof_spi_priv *p)
{
	u32 mask = SICTR_TXRST | SICTR_RXRST;
	u32 data;

	data = sh_msiof_read(p, SICTR);
	data |= mask;
	sh_msiof_write(p, SICTR, data);

Annotation

Implementation Notes