Unverified Commit 027781f3 authored by Leonard Göhrs's avatar Leonard Göhrs Committed by Mark Brown
Browse files

spi: core: add spi_split_transfers_maxwords



Add spi_split_transfers_maxwords() function that splits
spi_transfers transparently into multiple transfers
that are below a given number of SPI words.

This function reuses most of its code from
spi_split_transfers_maxsize() and for transfers with
eight or less bits per word actually behaves the same.

Signed-off-by: default avatarLeonard Göhrs <l.goehrs@pengutronix.de>
Link: https://lore.kernel.org/r/20230310092053.1006459-1-l.goehrs@pengutronix.de


Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 93d20545
Loading
Loading
Loading
Loading
+49 −0
Original line number Diff line number Diff line
@@ -3622,6 +3622,55 @@ int spi_split_transfers_maxsize(struct spi_controller *ctlr,
}
EXPORT_SYMBOL_GPL(spi_split_transfers_maxsize);


/**
 * spi_split_transfers_maxwords - split spi transfers into multiple transfers
 *                                when an individual transfer exceeds a
 *                                certain number of SPI words
 * @ctlr:     the @spi_controller for this transfer
 * @msg:      the @spi_message to transform
 * @maxwords: the number of words to limit each transfer to
 * @gfp:      GFP allocation flags
 *
 * Return: status of transformation
 */
int spi_split_transfers_maxwords(struct spi_controller *ctlr,
				 struct spi_message *msg,
				 size_t maxwords,
				 gfp_t gfp)
{
	struct spi_transfer *xfer;

	/*
	 * Iterate over the transfer_list,
	 * but note that xfer is advanced to the last transfer inserted
	 * to avoid checking sizes again unnecessarily (also xfer does
	 * potentially belong to a different list by the time the
	 * replacement has happened).
	 */
	list_for_each_entry(xfer, &msg->transfers, transfer_list) {
		size_t maxsize;
		int ret;

		if (xfer->bits_per_word <= 8)
			maxsize = maxwords;
		else if (xfer->bits_per_word <= 16)
			maxsize = 2 * maxwords;
		else
			maxsize = 4 * maxwords;

		if (xfer->len > maxsize) {
			ret = __spi_split_transfer_maxsize(ctlr, msg, &xfer,
							   maxsize, gfp);
			if (ret)
				return ret;
		}
	}

	return 0;
}
EXPORT_SYMBOL_GPL(spi_split_transfers_maxwords);

/*-------------------------------------------------------------------------*/

/* Core methods for SPI controller protocol drivers.  Some of the
+4 −0
Original line number Diff line number Diff line
@@ -1295,6 +1295,10 @@ extern int spi_split_transfers_maxsize(struct spi_controller *ctlr,
				       struct spi_message *msg,
				       size_t maxsize,
				       gfp_t gfp);
extern int spi_split_transfers_maxwords(struct spi_controller *ctlr,
					struct spi_message *msg,
					size_t maxwords,
					gfp_t gfp);

/*---------------------------------------------------------------------------*/