drivers/spi/spi-sh.c

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

File Facts

System
Linux kernel
Corpus path
drivers/spi/spi-sh.c
Extension
.c
Size
10425 bytes
Lines
473
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 spi_sh_data {
	void __iomem *addr;
	int irq;
	struct spi_controller *host;
	unsigned long cr1;
	wait_queue_head_t wait;
	int width;
};

static void spi_sh_write(struct spi_sh_data *ss, unsigned long data,
			     unsigned long offset)
{
	if (ss->width == 8)
		iowrite8(data, ss->addr + (offset >> 2));
	else if (ss->width == 32)
		iowrite32(data, ss->addr + offset);
}

static unsigned long spi_sh_read(struct spi_sh_data *ss, unsigned long offset)
{
	if (ss->width == 8)
		return ioread8(ss->addr + (offset >> 2));
	else if (ss->width == 32)
		return ioread32(ss->addr + offset);
	else
		return 0;
}

static void spi_sh_set_bit(struct spi_sh_data *ss, unsigned long val,
				unsigned long offset)
{
	unsigned long tmp;

	tmp = spi_sh_read(ss, offset);
	tmp |= val;
	spi_sh_write(ss, tmp, offset);
}

static void spi_sh_clear_bit(struct spi_sh_data *ss, unsigned long val,
				unsigned long offset)
{
	unsigned long tmp;

	tmp = spi_sh_read(ss, offset);
	tmp &= ~val;
	spi_sh_write(ss, tmp, offset);
}

static void clear_fifo(struct spi_sh_data *ss)
{
	spi_sh_set_bit(ss, SPI_SH_RSTF, SPI_SH_CR2);
	spi_sh_clear_bit(ss, SPI_SH_RSTF, SPI_SH_CR2);
}

static int spi_sh_wait_receive_buffer(struct spi_sh_data *ss)
{
	int timeout = 100000;

	while (spi_sh_read(ss, SPI_SH_CR1) & SPI_SH_RBE) {
		udelay(10);
		if (timeout-- < 0)
			return -ETIMEDOUT;
	}
	return 0;
}

static int spi_sh_wait_write_buffer_empty(struct spi_sh_data *ss)
{
	int timeout = 100000;

	while (!(spi_sh_read(ss, SPI_SH_CR1) & SPI_SH_TBE)) {
		udelay(10);
		if (timeout-- < 0)
			return -ETIMEDOUT;
	}
	return 0;
}

static int spi_sh_send(struct spi_sh_data *ss, struct spi_message *mesg,
			struct spi_transfer *t)
{
	int i, retval = 0;
	int remain = t->len;
	int cur_len;
	unsigned char *data;
	long ret;

	if (t->len)
		spi_sh_set_bit(ss, SPI_SH_SSA, SPI_SH_CR1);

Annotation

Implementation Notes