Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d1d67714 authored by Rui Miguel Silva's avatar Rui Miguel Silva Committed by Greg Kroah-Hartman
Browse files

greybus: spi: use timeout request send operation



When transfer speed is too slow (less than 17Khz) the operation can take
longer than the default greybus timeout. Because of this we need to use
the request_send_sync_timeout and calculate the correct timeout for each
operation.

Signed-off-by: default avatarRui Miguel Silva <rui.silva@linaro.org>
Tested-by: default avatarPhilip Yang <philipy@bsquare.com>
Tested-by: default avatarAxel Haslam <ahaslam@baylibre.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@google.com>
parent 0928b2e4
Loading
Loading
Loading
Loading
+15 −1
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ struct gb_spi {
	u32			rx_xfer_offset;
	u32			tx_xfer_offset;
	u32			last_xfer_size;
	unsigned int		op_timeout;
	u16			mode;
	u16			flags;
	u32			bits_per_word_mask;
@@ -38,6 +39,8 @@ struct gb_spi {
#define GB_SPI_STATE_OP_DONE		((void *)4)
#define GB_SPI_STATE_MSG_ERROR		((void *)-1)

#define XFER_TIMEOUT_TOLERANCE		200

static struct spi_master *get_master_from_spi(struct gb_spi *spi)
{
	return gb_connection_get_data(spi->connection);
@@ -95,6 +98,7 @@ static void clean_xfer_state(struct gb_spi *spi)
	spi->rx_xfer_offset = 0;
	spi->tx_xfer_offset = 0;
	spi->last_xfer_size = 0;
	spi->op_timeout = 0;
}

static int setup_next_xfer(struct gb_spi *spi, struct spi_message *msg)
@@ -112,6 +116,7 @@ static int setup_next_xfer(struct gb_spi *spi, struct spi_message *msg)
	    (spi->rx_xfer_offset + spi->last_xfer_size == last_xfer->len)) {
		spi->tx_xfer_offset = 0;
		spi->rx_xfer_offset = 0;
		spi->op_timeout = 0;
		if (last_xfer == list_last_entry(&msg->transfers,
						 struct spi_transfer,
						 transfer_list))
@@ -155,6 +160,7 @@ gb_spi_operation_create(struct gb_spi *spi, struct gb_connection *connection,
	u32 tx_size = 0, rx_size = 0, count = 0, xfer_len = 0, request_size;
	u32 tx_xfer_size = 0, rx_xfer_size = 0, len;
	u32 total_len = 0;
	unsigned int xfer_timeout;
	size_t data_max;
	void *tx_data;

@@ -234,6 +240,13 @@ gb_spi_operation_create(struct gb_spi *spi, struct gb_connection *connection,
		else
			xfer_len = xfer->len;

		/* make sure we do not timeout in a slow transfer */
		xfer_timeout = xfer_len * 8 * MSEC_PER_SEC / xfer->speed_hz;
		xfer_timeout += GB_OPERATION_TIMEOUT_DEFAULT;

		if (xfer_timeout > spi->op_timeout)
			spi->op_timeout = xfer_timeout;

		gb_xfer->speed_hz = cpu_to_le32(xfer->speed_hz);
		gb_xfer->len = cpu_to_le32(xfer_len);
		gb_xfer->delay_usecs = cpu_to_le16(xfer->delay_usecs);
@@ -322,7 +335,8 @@ static int gb_spi_transfer_one_message(struct spi_master *master,
			continue;
		}

		ret = gb_operation_request_send_sync(operation);
		ret = gb_operation_request_send_sync_timeout(operation,
							     spi->op_timeout);
		if (!ret) {
			response = operation->response->payload;
			if (response)