drivers/fpga/machxo2-spi.c

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

File Facts

System
Linux kernel
Corpus path
drivers/fpga/machxo2-spi.c
Extension
.c
Size
9545 bytes
Lines
406
Domain
Driver Families
Bucket
drivers/fpga
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

if (ret) {
			dev_err(&mgr->dev, "Error loading the bitstream.\n");
			return ret;
		}
	}
	get_status(spi, &status);
	dump_status_reg(&status);

	return 0;
}

static int machxo2_write_complete(struct fpga_manager *mgr,
				  struct fpga_image_info *info)
{
	struct spi_device *spi = mgr->priv;
	struct spi_message msg;
	struct spi_transfer tx[2];
	static const u8 progdone[] = ISC_PROGRAMDONE;
	static const u8 refresh[] = LSC_REFRESH;
	unsigned long status;
	int ret, refreshloop = 0;

	memset(tx, 0, sizeof(tx));
	spi_message_init(&msg);
	tx[0].tx_buf = &progdone;
	tx[0].len = sizeof(progdone);
	spi_message_add_tail(&tx[0], &msg);
	ret = spi_sync(spi, &msg);
	if (ret)
		goto fail;
	ret = wait_until_not_busy(spi);
	if (ret)
		goto fail;

	get_status(spi, &status);
	dump_status_reg(&status);
	if (!test_bit(DONE, &status)) {
		machxo2_cleanup(mgr);
		ret = -EINVAL;
		goto fail;
	}

	do {
		spi_message_init(&msg);
		tx[1].tx_buf = &refresh;
		tx[1].len = sizeof(refresh);
		tx[1].delay.value = MACHXO2_REFRESH_USEC;
		tx[1].delay.unit = SPI_DELAY_UNIT_USECS;
		spi_message_add_tail(&tx[1], &msg);
		ret = spi_sync(spi, &msg);
		if (ret)
			goto fail;

		/* check refresh status */
		get_status(spi, &status);
		dump_status_reg(&status);
		if (!test_bit(BUSY, &status) && test_bit(DONE, &status) &&
		    get_err(&status) == ENOERR)
			break;
		if (++refreshloop == MACHXO2_MAX_REFRESH_LOOP) {
			machxo2_cleanup(mgr);
			ret = -EINVAL;
			goto fail;
		}
	} while (1);

	get_status(spi, &status);
	dump_status_reg(&status);

	return 0;
fail:
	dev_err(&mgr->dev, "Refresh failed.\n");

	return ret;
}

static const struct fpga_manager_ops machxo2_ops = {
	.state = machxo2_spi_state,
	.write_init = machxo2_write_init,
	.write = machxo2_write,
	.write_complete = machxo2_write_complete,
};

static int machxo2_spi_probe(struct spi_device *spi)
{
	struct device *dev = &spi->dev;
	struct fpga_manager *mgr;

	if (spi->max_speed_hz > MACHXO2_MAX_SPEED) {
		dev_err(dev, "Speed is too high\n");

Annotation

Implementation Notes