/*
 *  linux/drivers/spi/spi-loopback-test.c
 *
 *  (c) Martin Sperl <kernel@martin.sperl.org>
 *
 *  Loopback test driver to test several typical spi_message conditions
 *  that a spi_master driver may encounter
 *  this can also get used for regression testing
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 */

#include <linux/delay.h>
#include <linux/kernel.h>
#include <linux/ktime.h>
#include <linux/list.h>
#include <linux/list_sort.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/printk.h>
#include <linux/vmalloc.h>
#include <linux/spi/spi.h>

#include "spi-test.h"

/* flag to only simulate transfers */
static int simulate_only;
module_param(simulate_only, int, 0);
MODULE_PARM_DESC(simulate_only, "if not 0 do not execute the spi message");

/* dump spi messages */
static int dump_messages;
module_param(dump_messages, int, 0);
MODULE_PARM_DESC(dump_messages,
		 "=1 dump the basic spi_message_structure, " \
		 "=2 dump the spi_message_structure including data, " \
		 "=3 dump the spi_message structure before and after execution");
/* the device is jumpered for loopback - enabling some rx_buf tests */
static int loopback;
module_param(loopback, int, 0);
MODULE_PARM_DESC(loopback,
		 "if set enable loopback mode, where the rx_buf "	\
		 "is checked to match tx_buf after the spi_message "	\
		 "is executed");

static int loop_req;
module_param(loop_req, int, 0);
MODULE_PARM_DESC(loop_req,
		 "if set controller will be asked to enable test loop mode. " \
		 "If controller supported it, MISO and MOSI will be connected");

static int no_cs;
module_param(no_cs, int, 0);
MODULE_PARM_DESC(no_cs,
		 "if set Chip Select (CS) will not be used");

/* run only a specific test */
static int run_only_test = -1;
module_param(run_only_test, int, 0);
MODULE_PARM_DESC(run_only_test,
		 "only run the test with this number (0-based !)");

/* use vmalloc'ed buffers */
static int use_vmalloc;
module_param(use_vmalloc, int, 0644);
MODULE_PARM_DESC(use_vmalloc,
		 "use vmalloc'ed buffers instead of kmalloc'ed");

/* check rx ranges */
static int check_ranges = 1;
module_param(check_ranges, int, 0644);
MODULE_PARM_DESC(check_ranges,
		 "checks rx_buffer pattern are valid");

/* the actual tests to execute */
static struct spi_test spi_tests[] = {
	{
		.description	= "tx/rx-transfer - start of page",
		.fill_option	= FILL_COUNT_8,
		.iterate_len    = { ITERATE_MAX_LEN },
		.iterate_tx_align = ITERATE_ALIGN,
		.iterate_rx_align = ITERATE_ALIGN,
		.transfer_count = 1,
		.transfers		= {
			{
				.tx_buf = TX(0),
				.rx_buf = RX(0),
			},
		},
	},
	{
		.description	= "tx/rx-transfer - crossing PAGE_SIZE",
		.fill_option	= FILL_COUNT_8,
		.iterate_len    = { ITERATE_MAX_LEN },
		.iterate_tx_align = ITERATE_ALIGN,
		.iterate_rx_align = ITERATE_ALIGN,
		.transfer_count = 1,
		.transfers		= {
			{
				.tx_buf = TX(PAGE_SIZE - 4),
				.rx_buf = RX(PAGE_SIZE - 4),
			},
		},
	},
	{
		.description	= "tx-transfer - only",
		.fill_option	= FILL_COUNT_8,
		.iterate_len    = { ITERATE_MAX_LEN },
		.iterate_tx_align = ITERATE_ALIGN,
		.transfer_count = 1,
		.transfers		= {
			{
				.tx_buf = TX(0),
			},
		},
	},
	{
		.description	= "rx-transfer - only",
		.fill_option	= FILL_COUNT_8,
		.iterate_len    = { ITERATE_MAX_LEN },
		.iterate_rx_align = ITERATE_ALIGN,
		.transfer_count = 1,
		.transfers		= {
			{
				.rx_buf = RX(0),
			},
		},
	},
	{
		.description	= "two tx-transfers - alter both",
		.fill_option	= FILL_COUNT_8,
		.iterate_len    = { ITERATE_LEN },
		.iterate_tx_align = ITERATE_ALIGN,
		.iterate_transfer_mask = BIT(0) | BIT(1),
		.transfer_count = 2,
		.transfers		= {
			{
				.tx_buf = TX(0),
			},
			{
				/* this is why we cant use ITERATE_MAX_LEN */
				.tx_buf = TX(SPI_TEST_MAX_SIZE_HALF),
			},
		},
	},
	{
		.description	= "two tx-transfers - alter first",
		.fill_option	= FILL_COUNT_8,
		.iterate_len    = { ITERATE_MAX_LEN },
		.iterate_tx_align = ITERATE_ALIGN,
		.iterate_transfer_mask = BIT(0),
		.transfer_count = 2,
		.transfers		= {
			{
				.tx_buf = TX(64),
			},
			{
				.len = 1,
				.tx_buf = TX(0),
			},
		},
	},
	{
		.description	= "two tx-transfers - alter second",
		.fill_option	= FILL_COUNT_8,
		.iterate_len    = { ITERATE_MAX_LEN },
		.iterate_tx_align = ITERATE_ALIGN,
		.iterate_transfer_mask = BIT(1),
		.transfer_count = 2,
		.transfers		= {
			{
				.len = 16,
				.tx_buf = TX(0),
			},
			{
				.tx_buf = TX(64),
			},
		},
	},
	{
		.description	= "two transfers tx then rx - alter both",
		.fill_option	= FILL_COUNT_8,
		.iterate_len    = { ITERATE_MAX_LEN },
		.iterate_tx_align = ITERATE_ALIGN,
		.iterate_transfer_mask = BIT(0) | BIT(1),
		.transfer_count = 2,
		.transfers		= {
			{
				.tx_buf = TX(0),
			},
			{
				.rx_buf = RX(0),
			},
		},
	},
	{
		.description	= "two transfers tx then rx - alter tx",
		.fill_option	= FILL_COUNT_8,
		.iterate_len    = { ITERATE_MAX_LEN },
		.iterate_tx_align = ITERATE_ALIGN,
		.iterate_transfer_mask = BIT(0),
		.transfer_count = 2,
		.transfers		= {
			{
				.tx_buf = TX(0),
			},
			{
				.len = 1,
				.rx_buf = RX(0),
			},
		},
	},
	{
		.description	= "two transfers tx then rx - alter rx",
		.fill_option	= FILL_COUNT_8,
		.iterate_len    = { ITERATE_MAX_LEN },
		.iterate_tx_align = ITERATE_ALIGN,
		.iterate_transfer_mask = BIT(1),
		.transfer_count = 2,
		.transfers		= {
			{
				.len = 1,
				.tx_buf = TX(0),
			},
			{
				.rx_buf = RX(0),
			},
		},
	},
	{
		.description	= "two tx+rx transfers - alter both",
		.fill_option	= FILL_COUNT_8,
		.iterate_len    = { ITERATE_LEN },
		.iterate_tx_align = ITERATE_ALIGN,
		.iterate_transfer_mask = BIT(0) | BIT(1),
		.transfer_count = 2,
		.transfers		= {
			{
				.tx_buf = TX(0),
				.rx_buf = RX(0),
			},
			{
				/* making sure we align without overwrite
				 * the reason we can not use ITERATE_MAX_LEN
				 */
				.tx_buf = TX(SPI_TEST_MAX_SIZE_HALF),
				.rx_buf = RX(SPI_TEST_MAX_SIZE_HALF),
			},
		},
	},
	{
		.description	= "two tx+rx transfers - alter first",
		.fill_option	= FILL_COUNT_8,
		.iterate_len    = { ITERATE_MAX_LEN },
		.iterate_tx_align = ITERATE_ALIGN,
		.iterate_transfer_mask = BIT(0),
		.transfer_count = 2,
		.transfers		= {
			{
				/* making sure we align without overwrite */
				.tx_buf = TX(1024),
				.rx_buf = RX(1024),
			},
			{
				.len = 1,
				/* making sure we align without overwrite */
				.tx_buf = TX(0),
				.rx_buf = RX(0),
			},
		},
	},
	{
		.description	= "two tx+rx transfers - alter second",
		.fill_option	= FILL_COUNT_8,
		.iterate_len    = { ITERATE_MAX_LEN },
		.iterate_tx_align = ITERATE_ALIGN,
		.iterate_transfer_mask = BIT(1),
		.transfer_count = 2,
		.transfers		= {
			{
				.len = 1,
				.tx_buf = TX(0),
				.rx_buf = RX(0),
			},
			{
				/* making sure we align without overwrite */
				.tx_buf = TX(1024),
				.rx_buf = RX(1024),
			},
		},
	},
	{
		.description	= "two tx+rx transfers - delay after transfer",
		.fill_option	= FILL_COUNT_8,
		.iterate_len    = { ITERATE_MAX_LEN },
		.iterate_transfer_mask = BIT(0) | BIT(1),
		.transfer_count = 2,
		.transfers		= {
			{
				.tx_buf = TX(0),
				.rx_buf = RX(0),
				.delay_usecs = 1000,
			},
			{
				.tx_buf = TX(0),
				.rx_buf = RX(0),
				.delay_usecs = 1000,
			},
		},
	},

	{ /* end of tests sequence */ }
};

static int spi_loopback_test_probe(struct spi_device *spi)
{
	int ret;

	if (loop_req || no_cs) {
		spi->mode |= loop_req ? SPI_LOOP : 0;
		spi->mode |= no_cs ? SPI_NO_CS : 0;
		ret = spi_setup(spi);
		if (ret) {
			dev_err(&spi->dev, "SPI setup with SPI_LOOP or SPI_NO_CS failed (%d)\n",
				ret);
			return ret;
		}
	}

	dev_info(&spi->dev, "Executing spi-loopback-tests\n");

	ret = spi_test_run_tests(spi, spi_tests);

	dev_info(&spi->dev, "Finished spi-loopback-tests with return: %i\n",
		 ret);

	return ret;
}

/* non const match table to permit to change via a module parameter */
static struct of_device_id spi_loopback_test_of_match[] = {
	{ .compatible	= "linux,spi-loopback-test", },
	{ }
};

/* allow to override the compatible string via a module_parameter */
module_param_string(compatible, spi_loopback_test_of_match[0].compatible,
		    sizeof(spi_loopback_test_of_match[0].compatible),
		    0000);

MODULE_DEVICE_TABLE(of, spi_loopback_test_of_match);

static struct spi_driver spi_loopback_test_driver = {
	.driver = {
		.name = "spi-loopback-test",
		.owner = THIS_MODULE,
		.of_match_table = spi_loopback_test_of_match,
	},
	.probe = spi_loopback_test_probe,
};

module_spi_driver(spi_loopback_test_driver);

MODULE_AUTHOR("Martin Sperl <kernel@martin.sperl.org>");
MODULE_DESCRIPTION("test spi_driver to check core functionality");
MODULE_LICENSE("GPL");

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

/* spi_test implementation */

#define RANGE_CHECK(ptr, plen, start, slen) \
	((ptr >= start) && (ptr + plen <= start + slen))

/* we allocate one page more, to allow for offsets */
#define SPI_TEST_MAX_SIZE_PLUS (SPI_TEST_MAX_SIZE + PAGE_SIZE)

static void spi_test_print_hex_dump(char *pre, const void *ptr, size_t len)
{
	/* limit the hex_dump */
	if (len < 1024) {
		print_hex_dump(KERN_INFO, pre,
			       DUMP_PREFIX_OFFSET, 16, 1,
			       ptr, len, 0);
		return;
	}
	/* print head */
	print_hex_dump(KERN_INFO, pre,
		       DUMP_PREFIX_OFFSET, 16, 1,
		       ptr, 512, 0);
	/* print tail */
	pr_info("%s truncated - continuing at offset %04zx\n",
		pre, len - 512);
	print_hex_dump(KERN_INFO, pre,
		       DUMP_PREFIX_OFFSET, 16, 1,
		       ptr + (len - 512), 512, 0);
}

static void spi_test_dump_message(struct spi_device *spi,
				  struct spi_message *msg,
				  bool dump_data)
{
	struct spi_transfer *xfer;
	int i;
	u8 b;

	dev_info(&spi->dev, "  spi_msg@%pK\n", msg);
	if (msg->status)
		dev_info(&spi->dev, "    status:        %i\n",
			 msg->status);
	dev_info(&spi->dev, "    frame_length:  %i\n",
		 msg->frame_length);
	dev_info(&spi->dev, "    actual_length: %i\n",
		 msg->actual_length);

	list_for_each_entry(xfer, &msg->transfers, transfer_list) {
		dev_info(&spi->dev, "    spi_transfer@%pK\n", xfer);
		dev_info(&spi->dev, "      len:    %i\n", xfer->len);
		dev_info(&spi->dev, "      tx_buf: %pK\n", xfer->tx_buf);
		if (dump_data && xfer->tx_buf)
			spi_test_print_hex_dump("          TX: ",
						xfer->tx_buf,
						xfer->len);

		dev_info(&spi->dev, "      rx_buf: %pK\n", xfer->rx_buf);
		if (dump_data && xfer->rx_buf)
			spi_test_print_hex_dump("          RX: ",
						xfer->rx_buf,
						xfer->len);
		/* check for unwritten test pattern on rx_buf */
		if (xfer->rx_buf) {
			for (i = 0 ; i < xfer->len ; i++) {
				b = ((u8 *)xfer->rx_buf)[xfer->len - 1 - i];
				if (b != SPI_TEST_PATTERN_UNWRITTEN)
					break;
			}
			if (i)
				dev_info(&spi->dev,
					 "      rx_buf filled with %02x starts at offset: %i\n",
					 SPI_TEST_PATTERN_UNWRITTEN,
					 xfer->len - i);
		}
	}
}

struct rx_ranges {
	struct list_head list;
	u8 *start;
	u8 *end;
};

static int rx_ranges_cmp(void *priv, struct list_head *a, struct list_head *b)
{
	struct rx_ranges *rx_a = list_entry(a, struct rx_ranges, list);
	struct rx_ranges *rx_b = list_entry(b, struct rx_ranges, list);

	if (rx_a->start > rx_b->start)
		return 1;
	if (rx_a->start < rx_b->start)
		return -1;
	return 0;
}

static int spi_check_rx_ranges(struct spi_device *spi,
			       struct spi_message *msg,
			       void *rx)
{
	struct spi_transfer *xfer;
	struct rx_ranges ranges[SPI_TEST_MAX_TRANSFERS], *r;
	int i = 0;
	LIST_HEAD(ranges_list);
	u8 *addr;
	int ret = 0;

	/* loop over all transfers to fill in the rx_ranges */
	list_for_each_entry(xfer, &msg->transfers, transfer_list) {
		/* if there is no rx, then no check is needed */
		if (!xfer->rx_buf)
			continue;
		/* fill in the rx_range */
		if (RANGE_CHECK(xfer->rx_buf, xfer->len,
				rx, SPI_TEST_MAX_SIZE_PLUS)) {
			ranges[i].start = xfer->rx_buf;
			ranges[i].end = xfer->rx_buf + xfer->len;
			list_add(&ranges[i].list, &ranges_list);
			i++;
		}
	}

	/* if no ranges, then we can return and avoid the checks...*/
	if (!i)
		return 0;

	/* sort the list */
	list_sort(NULL, &ranges_list, rx_ranges_cmp);

	/* and iterate over all the rx addresses */
	for (addr = rx; addr < (u8 *)rx + SPI_TEST_MAX_SIZE_PLUS; addr++) {
		/* if we are the DO not write pattern,
		 * then continue with the loop...
		 */
		if (*addr == SPI_TEST_PATTERN_DO_NOT_WRITE)
			continue;

		/* check if we are inside a range */
		list_for_each_entry(r, &ranges_list, list) {
			/* if so then set to end... */
			if ((addr >= r->start) && (addr < r->end))
				addr = r->end;
		}
		/* second test after a (hopefull) translation */
		if (*addr == SPI_TEST_PATTERN_DO_NOT_WRITE)
			continue;

		/* if still not found then something has modified too much */
		/* we could list the "closest" transfer here... */
		dev_err(&spi->dev,
			"loopback strangeness - rx changed outside of allowed range at: %pK\n",
			addr);
		/* do not return, only set ret,
		 * so that we list all addresses
		 */
		ret = -ERANGE;
	}

	return ret;
}

static int spi_test_check_elapsed_time(struct spi_device *spi,
				       struct spi_test *test)
{
	int i;
	unsigned long long estimated_time = 0;
	unsigned long long delay_usecs = 0;

	for (i = 0; i < test->transfer_count; i++) {
		struct spi_transfer *xfer = test->transfers + i;
		unsigned long long nbits = (unsigned long long)BITS_PER_BYTE *
					   xfer->len;

		delay_usecs += xfer->delay_usecs;
		if (!xfer->speed_hz)
			continue;
		estimated_time += div_u64(nbits * NSEC_PER_SEC, xfer->speed_hz);
	}

	estimated_time += delay_usecs * NSEC_PER_USEC;
	if (test->elapsed_time < estimated_time) {
		dev_err(&spi->dev,
			"elapsed time %lld ns is shorter than minimum estimated time %lld ns\n",
			test->elapsed_time, estimated_time);

		return -EINVAL;
	}

	return 0;
}

static int spi_test_check_loopback_result(struct spi_device *spi,
					  struct spi_message *msg,
					  void *tx, void *rx)
{
	struct spi_transfer *xfer;
	u8 rxb, txb;
	size_t i;
	int ret;

	/* checks rx_buffer pattern are valid with loopback or without */
	if (check_ranges) {
		ret = spi_check_rx_ranges(spi, msg, rx);
		if (ret)
			return ret;
	}

	/* if we run without loopback, then return now */
	if (!loopback)
		return 0;

	/* if applicable to transfer check that rx_buf is equal to tx_buf */
	list_for_each_entry(xfer, &msg->transfers, transfer_list) {
		/* if there is no rx, then no check is needed */
		if (!xfer->len || !xfer->rx_buf)
			continue;
		/* so depending on tx_buf we need to handle things */
		if (xfer->tx_buf) {
			for (i = 0; i < xfer->len; i++) {
				txb = ((u8 *)xfer->tx_buf)[i];
				rxb = ((u8 *)xfer->rx_buf)[i];
				if (txb != rxb)
					goto mismatch_error;
			}
		} else {
			/* first byte received */
			txb = ((u8 *)xfer->rx_buf)[0];
			/* first byte may be 0 or xff */
			if (!((txb == 0) || (txb == 0xff))) {
				dev_err(&spi->dev,
					"loopback strangeness - we expect 0x00 or 0xff, but not 0x%02x\n",
					txb);
				return -EINVAL;
			}
			/* check that all bytes are identical */
			for (i = 1; i < xfer->len; i++) {
				rxb = ((u8 *)xfer->rx_buf)[i];
				if (rxb != txb)
					goto mismatch_error;
			}
		}
	}

	return 0;

mismatch_error:
	dev_err(&spi->dev,
		"loopback strangeness - transfer mismatch on byte %04zx - expected 0x%02x, but got 0x%02x\n",
		i, txb, rxb);

	return -EINVAL;
}

static int spi_test_translate(struct spi_device *spi,
			      void **ptr, size_t len,
			      void *tx, void *rx)
{
	size_t off;

	/* return on null */
	if (!*ptr)
		return 0;

	/* in the MAX_SIZE_HALF case modify the pointer */
	if (((size_t)*ptr) & SPI_TEST_MAX_SIZE_HALF)
		/* move the pointer to the correct range */
		*ptr += (SPI_TEST_MAX_SIZE_PLUS / 2) -
			SPI_TEST_MAX_SIZE_HALF;

	/* RX range
	 * - we check against MAX_SIZE_PLUS to allow for automated alignment
	 */
	if (RANGE_CHECK(*ptr, len,  RX(0), SPI_TEST_MAX_SIZE_PLUS)) {
		off = *ptr - RX(0);
		*ptr = rx + off;

		return 0;
	}

	/* TX range */
	if (RANGE_CHECK(*ptr, len,  TX(0), SPI_TEST_MAX_SIZE_PLUS)) {
		off = *ptr - TX(0);
		*ptr = tx + off;

		return 0;
	}

	dev_err(&spi->dev,
		"PointerRange [%pK:%pK[ not in range [%pK:%pK[ or [%pK:%pK[\n",
		*ptr, *ptr + len,
		RX(0), RX(SPI_TEST_MAX_SIZE),
		TX(0), TX(SPI_TEST_MAX_SIZE));

	return -EINVAL;
}

static int spi_test_fill_pattern(struct spi_device *spi,
				 struct spi_test *test)
{
	struct spi_transfer *xfers = test->transfers;
	u8 *tx_buf;
	size_t count = 0;
	int i, j;

#ifdef __BIG_ENDIAN
#define GET_VALUE_BYTE(value, index, bytes) \
	(value >> (8 * (bytes - 1 - count % bytes)))
#else
#define GET_VALUE_BYTE(value, index, bytes) \
	(value >> (8 * (count % bytes)))
#endif

	/* fill all transfers with the pattern requested */
	for (i = 0; i < test->transfer_count; i++) {
		/* fill rx_buf with SPI_TEST_PATTERN_UNWRITTEN */
		if (xfers[i].rx_buf)
			memset(xfers[i].rx_buf, SPI_TEST_PATTERN_UNWRITTEN,
			       xfers[i].len);
		/* if tx_buf is NULL then skip */
		tx_buf = (u8 *)xfers[i].tx_buf;
		if (!tx_buf)
			continue;
		/* modify all the transfers */
		for (j = 0; j < xfers[i].len; j++, tx_buf++, count++) {
			/* fill tx */
			switch (test->fill_option) {
			case FILL_MEMSET_8:
				*tx_buf = test->fill_pattern;
				break;
			case FILL_MEMSET_16:
				*tx_buf = GET_VALUE_BYTE(test->fill_pattern,
							 count, 2);
				break;
			case FILL_MEMSET_24:
				*tx_buf = GET_VALUE_BYTE(test->fill_pattern,
							 count, 3);
				break;
			case FILL_MEMSET_32:
				*tx_buf = GET_VALUE_BYTE(test->fill_pattern,
							 count, 4);
				break;
			case FILL_COUNT_8:
				*tx_buf = count;
				break;
			case FILL_COUNT_16:
				*tx_buf = GET_VALUE_BYTE(count, count, 2);
				break;
			case FILL_COUNT_24:
				*tx_buf = GET_VALUE_BYTE(count, count, 3);
				break;
			case FILL_COUNT_32:
				*tx_buf = GET_VALUE_BYTE(count, count, 4);
				break;
			case FILL_TRANSFER_BYTE_8:
				*tx_buf = j;
				break;
			case FILL_TRANSFER_BYTE_16:
				*tx_buf = GET_VALUE_BYTE(j, j, 2);
				break;
			case FILL_TRANSFER_BYTE_24:
				*tx_buf = GET_VALUE_BYTE(j, j, 3);
				break;
			case FILL_TRANSFER_BYTE_32:
				*tx_buf = GET_VALUE_BYTE(j, j, 4);
				break;
			case FILL_TRANSFER_NUM:
				*tx_buf = i;
				break;
			default:
				dev_err(&spi->dev,
					"unsupported fill_option: %i\n",
					test->fill_option);
				return -EINVAL;
			}
		}
	}

	return 0;
}

static int _spi_test_run_iter(struct spi_device *spi,
			      struct spi_test *test,
			      void *tx, void *rx)
{
	struct spi_message *msg = &test->msg;
	struct spi_transfer *x;
	int i, ret;

	/* initialize message - zero-filled via static initialization */
	spi_message_init_no_memset(msg);

	/* fill rx with the DO_NOT_WRITE pattern */
	memset(rx, SPI_TEST_PATTERN_DO_NOT_WRITE, SPI_TEST_MAX_SIZE_PLUS);

	/* add the individual transfers */
	for (i = 0; i < test->transfer_count; i++) {
		x = &test->transfers[i];

		/* patch the values of tx_buf */
		ret = spi_test_translate(spi, (void **)&x->tx_buf, x->len,
					 (void *)tx, rx);
		if (ret)
			return ret;

		/* patch the values of rx_buf */
		ret = spi_test_translate(spi, &x->rx_buf, x->len,
					 (void *)tx, rx);
		if (ret)
			return ret;

		/* and add it to the list */
		spi_message_add_tail(x, msg);
	}

	/* fill in the transfer buffers with pattern */
	ret = spi_test_fill_pattern(spi, test);
	if (ret)
		return ret;

	/* and execute */
	if (test->execute_msg)
		ret = test->execute_msg(spi, test, tx, rx);
	else
		ret = spi_test_execute_msg(spi, test, tx, rx);

	/* handle result */
	if (ret == test->expected_return)
		return 0;

	dev_err(&spi->dev,
		"test failed - test returned %i, but we expect %i\n",
		ret, test->expected_return);

	if (ret)
		return ret;

	/* if it is 0, as we expected something else,
	 * then return something special
	 */
	return -EFAULT;
}

static int spi_test_run_iter(struct spi_device *spi,
			     const struct spi_test *testtemplate,
			     void *tx, void *rx,
			     size_t len,
			     size_t tx_off,
			     size_t rx_off
	)
{
	struct spi_test test;
	int i, tx_count, rx_count;

	/* copy the test template to test */
	memcpy(&test, testtemplate, sizeof(test));

	/* if iterate_transfer_mask is not set,
	 * then set it to first transfer only
	 */
	if (!(test.iterate_transfer_mask & (BIT(test.transfer_count) - 1)))
		test.iterate_transfer_mask = 1;

	/* count number of transfers with tx/rx_buf != NULL */
	rx_count = tx_count = 0;
	for (i = 0; i < test.transfer_count; i++) {
		if (test.transfers[i].tx_buf)
			tx_count++;
		if (test.transfers[i].rx_buf)
			rx_count++;
	}

	/* in some iteration cases warn and exit early,
	 * as there is nothing to do, that has not been tested already...
	 */
	if (tx_off && (!tx_count)) {
		dev_warn_once(&spi->dev,
			      "%s: iterate_tx_off configured with tx_buf==NULL - ignoring\n",
			      test.description);
		return 0;
	}
	if (rx_off && (!rx_count)) {
		dev_warn_once(&spi->dev,
			      "%s: iterate_rx_off configured with rx_buf==NULL - ignoring\n",
			      test.description);
		return 0;
	}

	/* write out info */
	if (!(len || tx_off || rx_off)) {
		dev_info(&spi->dev, "Running test %s\n", test.description);
	} else {
		dev_info(&spi->dev,
			 "  with iteration values: len = %zu, tx_off = %zu, rx_off = %zu\n",
			 len, tx_off, rx_off);
	}

	/* update in the values from iteration values */
	for (i = 0; i < test.transfer_count; i++) {
		/* only when bit in transfer mask is set */
		if (!(test.iterate_transfer_mask & BIT(i)))
			continue;
		test.transfers[i].len = len;
		if (test.transfers[i].tx_buf)
			test.transfers[i].tx_buf += tx_off;
		if (test.transfers[i].tx_buf)
			test.transfers[i].rx_buf += rx_off;
	}

	/* and execute */
	return _spi_test_run_iter(spi, &test, tx, rx);
}

/**
 * spi_test_execute_msg - default implementation to run a test
 *
 * spi: @spi_device on which to run the @spi_message
 * test: the test to execute, which already contains @msg
 * tx:   the tx buffer allocated for the test sequence
 * rx:   the rx buffer allocated for the test sequence
 *
 * Returns: error code of spi_sync as well as basic error checking
 */
int spi_test_execute_msg(struct spi_device *spi, struct spi_test *test,
			 void *tx, void *rx)
{
	struct spi_message *msg = &test->msg;
	int ret = 0;
	int i;

	/* only if we do not simulate */
	if (!simulate_only) {
		ktime_t start;

		/* dump the complete message before and after the transfer */
		if (dump_messages == 3)
			spi_test_dump_message(spi, msg, true);

		start = ktime_get();
		/* run spi message */
		ret = spi_sync(spi, msg);
		test->elapsed_time = ktime_to_ns(ktime_sub(ktime_get(), start));
		if (ret == -ETIMEDOUT) {
			dev_info(&spi->dev,
				 "spi-message timed out - rerunning...\n");
			/* rerun after a few explicit schedules */
			for (i = 0; i < 16; i++)
				schedule();
			ret = spi_sync(spi, msg);
		}
		if (ret) {
			dev_err(&spi->dev,
				"Failed to execute spi_message: %i\n",
				ret);
			goto exit;
		}

		/* do some extra error checks */
		if (msg->frame_length != msg->actual_length) {
			dev_err(&spi->dev,
				"actual length differs from expected\n");
			ret = -EIO;
			goto exit;
		}

		/* run rx-buffer tests */
		ret = spi_test_check_loopback_result(spi, msg, tx, rx);
		if (ret)
			goto exit;

		ret = spi_test_check_elapsed_time(spi, test);
	}

	/* if requested or on error dump message (including data) */
exit:
	if (dump_messages || ret)
		spi_test_dump_message(spi, msg,
				      (dump_messages >= 2) || (ret));

	return ret;
}
EXPORT_SYMBOL_GPL(spi_test_execute_msg);

/**
 * spi_test_run_test - run an individual spi_test
 *                     including all the relevant iterations on:
 *                     length and buffer alignment
 *
 * spi:  the spi_device to send the messages to
 * test: the test which we need to execute
 * tx:   the tx buffer allocated for the test sequence
 * rx:   the rx buffer allocated for the test sequence
 *
 * Returns: status code of spi_sync or other failures
 */

int spi_test_run_test(struct spi_device *spi, const struct spi_test *test,
		      void *tx, void *rx)
{
	int idx_len;
	size_t len;
	size_t tx_align, rx_align;
	int ret;

	/* test for transfer limits */
	if (test->transfer_count >= SPI_TEST_MAX_TRANSFERS) {
		dev_err(&spi->dev,
			"%s: Exceeded max number of transfers with %i\n",
			test->description, test->transfer_count);
		return -E2BIG;
	}

	/* setting up some values in spi_message
	 * based on some settings in spi_master
	 * some of this can also get done in the run() method
	 */

	/* iterate over all the iterable values using macros
	 * (to make it a bit more readable...
	 */
#define FOR_EACH_ALIGNMENT(var)						\
	for (var = 0;							\
	    var < (test->iterate_##var ?				\
			(spi->master->dma_alignment ?			\
			 spi->master->dma_alignment :			\
			 test->iterate_##var) :				\
			1);						\
	    var++)

	for (idx_len = 0; idx_len < SPI_TEST_MAX_ITERATE &&
	     (len = test->iterate_len[idx_len]) != -1; idx_len++) {
		FOR_EACH_ALIGNMENT(tx_align) {
			FOR_EACH_ALIGNMENT(rx_align) {
				/* and run the iteration */
				ret = spi_test_run_iter(spi, test,
							tx, rx,
							len,
							tx_align,
							rx_align);
				if (ret)
					return ret;
			}
		}
	}

	return 0;
}
EXPORT_SYMBOL_GPL(spi_test_run_test);

/**
 * spi_test_run_tests - run an array of spi_messages tests
 * @spi: the spi device on which to run the tests
 * @tests: NULL-terminated array of @spi_test
 *
 * Returns: status errors as per @spi_test_run_test()
 */

int spi_test_run_tests(struct spi_device *spi,
		       struct spi_test *tests)
{
	char *rx = NULL, *tx = NULL;
	int ret = 0, count = 0;
	struct spi_test *test;

	/* allocate rx/tx buffers of 128kB size without devm
	 * in the hope that is on a page boundary
	 */
	if (use_vmalloc)
		rx = vmalloc(SPI_TEST_MAX_SIZE_PLUS);
	else
		rx = kzalloc(SPI_TEST_MAX_SIZE_PLUS, GFP_KERNEL);
	if (!rx)
		return -ENOMEM;


	if (use_vmalloc)
		tx = vmalloc(SPI_TEST_MAX_SIZE_PLUS);
	else
		tx = kzalloc(SPI_TEST_MAX_SIZE_PLUS, GFP_KERNEL);
	if (!tx) {
		ret = -ENOMEM;
		goto err_tx;
	}

	/* now run the individual tests in the table */
	for (test = tests, count = 0; test->description[0];
	     test++, count++) {
		/* only run test if requested */
		if ((run_only_test > -1) && (count != run_only_test))
			continue;
		/* run custom implementation */
		if (test->run_test)
			ret = test->run_test(spi, test, tx, rx);
		else
			ret = spi_test_run_test(spi, test, tx, rx);
		if (ret)
			goto out;
		/* add some delays so that we can easily
		 * detect the individual tests when using a logic analyzer
		 * we also add scheduling to avoid potential spi_timeouts...
		 */
		mdelay(100);
		schedule();
	}

out:
	kvfree(tx);
err_tx:
	kvfree(rx);
	return ret;
}
EXPORT_SYMBOL_GPL(spi_test_run_tests);
