[PATCH 17/25] spi: atcspi200: add optional interrupt support

Mark Brown broonie at kernel.org
Sun Nov 8 02:35:28 PST 2026


> For PIO transfers, the driver busy-polls the FIFO empty/full flags and
> the SPI active bit for completion. When the controller's interrupt is
> available, use it instead of polling to keep the FIFO serviced and to
> detect the end of transfer.

> +static irqreturn_t atcspi_irq(int irq, void *dev_id)
> +{

> +	if (st & ATCSPI_TX_FIFO_INT) {
> +		n = min(atcspi_tx_fifo_avail(spi, status), spi->tx_words);
> +		atcspi_fifo_write(spi, spi->tx_ptr, n);
> +		spi->tx_words -= n;
> +		spi->tx_ptr = (unsigned char *)spi->tx_ptr + n * num_byte;

You're casting away const here for some reason...

> +	regmap_read(spi->regmap, ATCSPI_CTRL, &ctrl);
> +	ctrl &= ~(CTRL_TX_THRES | CTRL_RX_THRES);
> +	ctrl |= FIELD_PREP(CTRL_TX_THRES, spi->txfifo_size / 2) |
> +	FIELD_PREP(CTRL_RX_THRES, spi->rxfifo_size / 2);

Weird indentation of the continuation.

> +	if (spi->tx_words) {
> +		unsigned int status, nb_words;
> +
> +		regmap_read(spi->regmap, ATCSPI_STATUS, &status);
> +		nb_words = min(atcspi_tx_fifo_avail(spi, status), spi->tx_words);
> +		atcspi_fifo_write(spi, spi->tx_ptr, nb_words);
> +		spi->tx_words -= nb_words;
> +		spi->tx_ptr = (unsigned char *)spi->tx_ptr + nb_words * num_byte;
> +	}
> +
> +	regmap_write(spi->regmap, ATCSPI_INTR_ST, ATCSPI_INTR_ALL);
> +	regmap_write(spi->regmap, ATCSPI_INTR_EN, en);

Do we need the TX interrupt if everything fit into the FIFO?

> +	regmap_write(spi->regmap, ATCSPI_INTR_EN, 0);
> +	regmap_write(spi->regmap, ATCSPI_INTR_ST, ATCSPI_INTR_ALL);

This just blindly clears all the interrupts, including the under/overrun
interrupts but we didn't handle them all.

-- 
Mark Brown <broonie at kernel.org>



More information about the linux-riscv mailing list