Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    3)  *  linux/drivers/spi/spi-loopback-test.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  *  (c) Martin Sperl <kernel@martin.sperl.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7)  *  Loopback test driver to test several typical spi_message conditions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8)  *  that a spi_master driver may encounter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9)  *  this can also get used for regression testing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14) #include <linux/ktime.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15) #include <linux/list.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16) #include <linux/list_sort.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18) #include <linux/of_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19) #include <linux/printk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20) #include <linux/vmalloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21) #include <linux/spi/spi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) #include "spi-test.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25) /* flag to only simulate transfers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26) static int simulate_only;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27) module_param(simulate_only, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) MODULE_PARM_DESC(simulate_only, "if not 0 do not execute the spi message");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) /* dump spi messages */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) static int dump_messages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) module_param(dump_messages, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) MODULE_PARM_DESC(dump_messages,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) 		 "=1 dump the basic spi_message_structure, " \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) 		 "=2 dump the spi_message_structure including data, " \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) 		 "=3 dump the spi_message structure before and after execution");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) /* the device is jumpered for loopback - enabling some rx_buf tests */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) static int loopback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) module_param(loopback, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) MODULE_PARM_DESC(loopback,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) 		 "if set enable loopback mode, where the rx_buf "	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) 		 "is checked to match tx_buf after the spi_message "	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) 		 "is executed");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) static int loop_req;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) module_param(loop_req, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) MODULE_PARM_DESC(loop_req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) 		 "if set controller will be asked to enable test loop mode. " \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) 		 "If controller supported it, MISO and MOSI will be connected");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) static int no_cs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) module_param(no_cs, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) MODULE_PARM_DESC(no_cs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) 		 "if set Chip Select (CS) will not be used");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) /* run only a specific test */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) static int run_only_test = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) module_param(run_only_test, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) MODULE_PARM_DESC(run_only_test,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) 		 "only run the test with this number (0-based !)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) /* use vmalloc'ed buffers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) static int use_vmalloc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) module_param(use_vmalloc, int, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) MODULE_PARM_DESC(use_vmalloc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) 		 "use vmalloc'ed buffers instead of kmalloc'ed");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) /* check rx ranges */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) static int check_ranges = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) module_param(check_ranges, int, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) MODULE_PARM_DESC(check_ranges,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) 		 "checks rx_buffer pattern are valid");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) /* the actual tests to execute */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) static struct spi_test spi_tests[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) 		.description	= "tx/rx-transfer - start of page",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) 		.fill_option	= FILL_COUNT_8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) 		.iterate_len    = { ITERATE_MAX_LEN },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) 		.iterate_tx_align = ITERATE_ALIGN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) 		.iterate_rx_align = ITERATE_ALIGN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) 		.transfer_count = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) 		.transfers		= {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) 			{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) 				.tx_buf = TX(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) 				.rx_buf = RX(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) 			},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) 		},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) 		.description	= "tx/rx-transfer - crossing PAGE_SIZE",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) 		.fill_option	= FILL_COUNT_8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) 		.iterate_len    = { ITERATE_LEN },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) 		.iterate_tx_align = ITERATE_ALIGN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) 		.iterate_rx_align = ITERATE_ALIGN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) 		.transfer_count = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) 		.transfers		= {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) 			{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) 				.tx_buf = TX(PAGE_SIZE - 4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) 				.rx_buf = RX(PAGE_SIZE - 4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) 			},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) 		},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) 		.description	= "tx-transfer - only",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) 		.fill_option	= FILL_COUNT_8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) 		.iterate_len    = { ITERATE_MAX_LEN },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) 		.iterate_tx_align = ITERATE_ALIGN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) 		.transfer_count = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) 		.transfers		= {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) 			{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) 				.tx_buf = TX(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) 			},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) 		},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) 		.description	= "rx-transfer - only",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) 		.fill_option	= FILL_COUNT_8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) 		.iterate_len    = { ITERATE_MAX_LEN },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) 		.iterate_rx_align = ITERATE_ALIGN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) 		.transfer_count = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) 		.transfers		= {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) 			{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) 				.rx_buf = RX(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) 			},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) 		},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) 		.description	= "two tx-transfers - alter both",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) 		.fill_option	= FILL_COUNT_8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) 		.iterate_len    = { ITERATE_LEN },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) 		.iterate_tx_align = ITERATE_ALIGN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) 		.iterate_transfer_mask = BIT(0) | BIT(1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) 		.transfer_count = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) 		.transfers		= {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) 			{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) 				.tx_buf = TX(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) 			},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) 			{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) 				/* this is why we cant use ITERATE_MAX_LEN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) 				.tx_buf = TX(SPI_TEST_MAX_SIZE_HALF),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) 			},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) 		},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) 		.description	= "two tx-transfers - alter first",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) 		.fill_option	= FILL_COUNT_8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) 		.iterate_len    = { ITERATE_MAX_LEN },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) 		.iterate_tx_align = ITERATE_ALIGN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) 		.iterate_transfer_mask = BIT(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) 		.transfer_count = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) 		.transfers		= {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) 			{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) 				.tx_buf = TX(64),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) 			},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) 			{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) 				.len = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) 				.tx_buf = TX(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) 			},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) 		},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) 		.description	= "two tx-transfers - alter second",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) 		.fill_option	= FILL_COUNT_8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) 		.iterate_len    = { ITERATE_MAX_LEN },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) 		.iterate_tx_align = ITERATE_ALIGN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) 		.iterate_transfer_mask = BIT(1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) 		.transfer_count = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) 		.transfers		= {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) 			{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) 				.len = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) 				.tx_buf = TX(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) 			},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) 			{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) 				.tx_buf = TX(64),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) 			},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) 		},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) 		.description	= "two transfers tx then rx - alter both",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) 		.fill_option	= FILL_COUNT_8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) 		.iterate_len    = { ITERATE_MAX_LEN },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) 		.iterate_tx_align = ITERATE_ALIGN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 		.iterate_transfer_mask = BIT(0) | BIT(1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) 		.transfer_count = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) 		.transfers		= {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) 			{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) 				.tx_buf = TX(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) 			},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) 			{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) 				.rx_buf = RX(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) 			},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) 		},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) 		.description	= "two transfers tx then rx - alter tx",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) 		.fill_option	= FILL_COUNT_8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) 		.iterate_len    = { ITERATE_MAX_LEN },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) 		.iterate_tx_align = ITERATE_ALIGN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) 		.iterate_transfer_mask = BIT(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) 		.transfer_count = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) 		.transfers		= {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) 			{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) 				.tx_buf = TX(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) 			},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) 			{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 				.len = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 				.rx_buf = RX(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) 			},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) 		},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) 		.description	= "two transfers tx then rx - alter rx",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) 		.fill_option	= FILL_COUNT_8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 		.iterate_len    = { ITERATE_MAX_LEN },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) 		.iterate_tx_align = ITERATE_ALIGN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) 		.iterate_transfer_mask = BIT(1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) 		.transfer_count = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) 		.transfers		= {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) 			{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) 				.len = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) 				.tx_buf = TX(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 			},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) 			{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) 				.rx_buf = RX(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) 			},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) 		},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 		.description	= "two tx+rx transfers - alter both",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) 		.fill_option	= FILL_COUNT_8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) 		.iterate_len    = { ITERATE_LEN },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) 		.iterate_tx_align = ITERATE_ALIGN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) 		.iterate_transfer_mask = BIT(0) | BIT(1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 		.transfer_count = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) 		.transfers		= {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) 			{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 				.tx_buf = TX(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 				.rx_buf = RX(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 			},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) 			{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) 				/* making sure we align without overwrite
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) 				 * the reason we can not use ITERATE_MAX_LEN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) 				 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) 				.tx_buf = TX(SPI_TEST_MAX_SIZE_HALF),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) 				.rx_buf = RX(SPI_TEST_MAX_SIZE_HALF),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 			},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) 		},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) 		.description	= "two tx+rx transfers - alter first",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) 		.fill_option	= FILL_COUNT_8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) 		.iterate_len    = { ITERATE_MAX_LEN },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) 		.iterate_tx_align = ITERATE_ALIGN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) 		.iterate_transfer_mask = BIT(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 		.transfer_count = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 		.transfers		= {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) 			{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) 				/* making sure we align without overwrite */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) 				.tx_buf = TX(1024),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) 				.rx_buf = RX(1024),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) 			},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) 			{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) 				.len = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) 				/* making sure we align without overwrite */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) 				.tx_buf = TX(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) 				.rx_buf = RX(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) 			},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) 		},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 		.description	= "two tx+rx transfers - alter second",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 		.fill_option	= FILL_COUNT_8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 		.iterate_len    = { ITERATE_MAX_LEN },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) 		.iterate_tx_align = ITERATE_ALIGN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) 		.iterate_transfer_mask = BIT(1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) 		.transfer_count = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) 		.transfers		= {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 			{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) 				.len = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) 				.tx_buf = TX(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) 				.rx_buf = RX(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) 			},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) 			{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) 				/* making sure we align without overwrite */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) 				.tx_buf = TX(1024),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) 				.rx_buf = RX(1024),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) 			},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) 		},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) 		.description	= "two tx+rx transfers - delay after transfer",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) 		.fill_option	= FILL_COUNT_8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) 		.iterate_len    = { ITERATE_MAX_LEN },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) 		.iterate_transfer_mask = BIT(0) | BIT(1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) 		.transfer_count = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) 		.transfers		= {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) 			{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) 				.tx_buf = TX(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) 				.rx_buf = RX(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) 				.delay = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) 					.value = 1000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) 					.unit = SPI_DELAY_UNIT_USECS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) 				},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) 			},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) 			{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) 				.tx_buf = TX(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) 				.rx_buf = RX(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) 				.delay = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 					.value = 1000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) 					.unit = SPI_DELAY_UNIT_USECS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 				},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) 			},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) 		},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) 	{ /* end of tests sequence */ }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) static int spi_loopback_test_probe(struct spi_device *spi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 	if (loop_req || no_cs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) 		spi->mode |= loop_req ? SPI_LOOP : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) 		spi->mode |= no_cs ? SPI_NO_CS : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) 		ret = spi_setup(spi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) 		if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 			dev_err(&spi->dev, "SPI setup with SPI_LOOP or SPI_NO_CS failed (%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) 				ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 	dev_info(&spi->dev, "Executing spi-loopback-tests\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 	ret = spi_test_run_tests(spi, spi_tests);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) 	dev_info(&spi->dev, "Finished spi-loopback-tests with return: %i\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 		 ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) /* non const match table to permit to change via a module parameter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) static struct of_device_id spi_loopback_test_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) 	{ .compatible	= "linux,spi-loopback-test", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) 	{ }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) /* allow to override the compatible string via a module_parameter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) module_param_string(compatible, spi_loopback_test_of_match[0].compatible,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 		    sizeof(spi_loopback_test_of_match[0].compatible),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) 		    0000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) MODULE_DEVICE_TABLE(of, spi_loopback_test_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) static struct spi_driver spi_loopback_test_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) 	.driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) 		.name = "spi-loopback-test",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) 		.owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) 		.of_match_table = spi_loopback_test_of_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) 	.probe = spi_loopback_test_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) module_spi_driver(spi_loopback_test_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) MODULE_AUTHOR("Martin Sperl <kernel@martin.sperl.org>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) MODULE_DESCRIPTION("test spi_driver to check core functionality");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) /*-------------------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) /* spi_test implementation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) #define RANGE_CHECK(ptr, plen, start, slen) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) 	((ptr >= start) && (ptr + plen <= start + slen))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) /* we allocate one page more, to allow for offsets */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) #define SPI_TEST_MAX_SIZE_PLUS (SPI_TEST_MAX_SIZE + PAGE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) static void spi_test_print_hex_dump(char *pre, const void *ptr, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) 	/* limit the hex_dump */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) 	if (len < 1024) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) 		print_hex_dump(KERN_INFO, pre,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) 			       DUMP_PREFIX_OFFSET, 16, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) 			       ptr, len, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) 	/* print head */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) 	print_hex_dump(KERN_INFO, pre,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 		       DUMP_PREFIX_OFFSET, 16, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) 		       ptr, 512, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 	/* print tail */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) 	pr_info("%s truncated - continuing at offset %04zx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) 		pre, len - 512);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 	print_hex_dump(KERN_INFO, pre,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 		       DUMP_PREFIX_OFFSET, 16, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 		       ptr + (len - 512), 512, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) static void spi_test_dump_message(struct spi_device *spi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 				  struct spi_message *msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 				  bool dump_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) 	struct spi_transfer *xfer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) 	u8 b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) 	dev_info(&spi->dev, "  spi_msg@%pK\n", msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 	if (msg->status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 		dev_info(&spi->dev, "    status:        %i\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) 			 msg->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 	dev_info(&spi->dev, "    frame_length:  %i\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) 		 msg->frame_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) 	dev_info(&spi->dev, "    actual_length: %i\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 		 msg->actual_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 	list_for_each_entry(xfer, &msg->transfers, transfer_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 		dev_info(&spi->dev, "    spi_transfer@%pK\n", xfer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 		dev_info(&spi->dev, "      len:    %i\n", xfer->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) 		dev_info(&spi->dev, "      tx_buf: %pK\n", xfer->tx_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 		if (dump_data && xfer->tx_buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) 			spi_test_print_hex_dump("          TX: ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) 						xfer->tx_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) 						xfer->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) 		dev_info(&spi->dev, "      rx_buf: %pK\n", xfer->rx_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) 		if (dump_data && xfer->rx_buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 			spi_test_print_hex_dump("          RX: ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) 						xfer->rx_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) 						xfer->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) 		/* check for unwritten test pattern on rx_buf */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) 		if (xfer->rx_buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) 			for (i = 0 ; i < xfer->len ; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) 				b = ((u8 *)xfer->rx_buf)[xfer->len - 1 - i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) 				if (b != SPI_TEST_PATTERN_UNWRITTEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 			if (i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 				dev_info(&spi->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) 					 "      rx_buf filled with %02x starts at offset: %i\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) 					 SPI_TEST_PATTERN_UNWRITTEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) 					 xfer->len - i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) struct rx_ranges {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 	struct list_head list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 	u8 *start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) 	u8 *end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) static int rx_ranges_cmp(void *priv, struct list_head *a, struct list_head *b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) 	struct rx_ranges *rx_a = list_entry(a, struct rx_ranges, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) 	struct rx_ranges *rx_b = list_entry(b, struct rx_ranges, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) 	if (rx_a->start > rx_b->start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) 	if (rx_a->start < rx_b->start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) static int spi_check_rx_ranges(struct spi_device *spi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 			       struct spi_message *msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 			       void *rx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 	struct spi_transfer *xfer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 	struct rx_ranges ranges[SPI_TEST_MAX_TRANSFERS], *r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) 	int i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 	LIST_HEAD(ranges_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) 	u8 *addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 	/* loop over all transfers to fill in the rx_ranges */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 	list_for_each_entry(xfer, &msg->transfers, transfer_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 		/* if there is no rx, then no check is needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) 		if (!xfer->rx_buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 		/* fill in the rx_range */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) 		if (RANGE_CHECK(xfer->rx_buf, xfer->len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) 				rx, SPI_TEST_MAX_SIZE_PLUS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) 			ranges[i].start = xfer->rx_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) 			ranges[i].end = xfer->rx_buf + xfer->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) 			list_add(&ranges[i].list, &ranges_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) 			i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) 	/* if no ranges, then we can return and avoid the checks...*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) 	if (!i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) 	/* sort the list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) 	list_sort(NULL, &ranges_list, rx_ranges_cmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) 	/* and iterate over all the rx addresses */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) 	for (addr = rx; addr < (u8 *)rx + SPI_TEST_MAX_SIZE_PLUS; addr++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) 		/* if we are the DO not write pattern,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 		 * then continue with the loop...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) 		if (*addr == SPI_TEST_PATTERN_DO_NOT_WRITE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) 		/* check if we are inside a range */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) 		list_for_each_entry(r, &ranges_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) 			/* if so then set to end... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) 			if ((addr >= r->start) && (addr < r->end))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) 				addr = r->end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) 		/* second test after a (hopefull) translation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) 		if (*addr == SPI_TEST_PATTERN_DO_NOT_WRITE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) 		/* if still not found then something has modified too much */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) 		/* we could list the "closest" transfer here... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) 		dev_err(&spi->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) 			"loopback strangeness - rx changed outside of allowed range at: %pK\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 			addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) 		/* do not return, only set ret,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 		 * so that we list all addresses
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 		ret = -ERANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) static int spi_test_check_elapsed_time(struct spi_device *spi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) 				       struct spi_test *test)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) 	unsigned long long estimated_time = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) 	unsigned long long delay_usecs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 	for (i = 0; i < test->transfer_count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) 		struct spi_transfer *xfer = test->transfers + i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) 		unsigned long long nbits = (unsigned long long)BITS_PER_BYTE *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 					   xfer->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) 		delay_usecs += xfer->delay.value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) 		if (!xfer->speed_hz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) 		estimated_time += div_u64(nbits * NSEC_PER_SEC, xfer->speed_hz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 	estimated_time += delay_usecs * NSEC_PER_USEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 	if (test->elapsed_time < estimated_time) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 		dev_err(&spi->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) 			"elapsed time %lld ns is shorter than minimum estimated time %lld ns\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) 			test->elapsed_time, estimated_time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) static int spi_test_check_loopback_result(struct spi_device *spi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) 					  struct spi_message *msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) 					  void *tx, void *rx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) 	struct spi_transfer *xfer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) 	u8 rxb, txb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) 	size_t i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) 	/* checks rx_buffer pattern are valid with loopback or without */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) 	if (check_ranges) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) 		ret = spi_check_rx_ranges(spi, msg, rx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) 	/* if we run without loopback, then return now */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) 	if (!loopback)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) 	/* if applicable to transfer check that rx_buf is equal to tx_buf */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 	list_for_each_entry(xfer, &msg->transfers, transfer_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) 		/* if there is no rx, then no check is needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 		if (!xfer->len || !xfer->rx_buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 		/* so depending on tx_buf we need to handle things */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 		if (xfer->tx_buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) 			for (i = 0; i < xfer->len; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 				txb = ((u8 *)xfer->tx_buf)[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) 				rxb = ((u8 *)xfer->rx_buf)[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 				if (txb != rxb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) 					goto mismatch_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) 			/* first byte received */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) 			txb = ((u8 *)xfer->rx_buf)[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) 			/* first byte may be 0 or xff */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) 			if (!((txb == 0) || (txb == 0xff))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 				dev_err(&spi->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) 					"loopback strangeness - we expect 0x00 or 0xff, but not 0x%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) 					txb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) 				return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) 			/* check that all bytes are identical */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) 			for (i = 1; i < xfer->len; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 				rxb = ((u8 *)xfer->rx_buf)[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) 				if (rxb != txb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 					goto mismatch_error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) mismatch_error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) 	dev_err(&spi->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) 		"loopback strangeness - transfer mismatch on byte %04zx - expected 0x%02x, but got 0x%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) 		i, txb, rxb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 	return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) static int spi_test_translate(struct spi_device *spi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) 			      void **ptr, size_t len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 			      void *tx, void *rx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) 	size_t off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) 	/* return on null */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) 	if (!*ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) 	/* in the MAX_SIZE_HALF case modify the pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) 	if (((size_t)*ptr) & SPI_TEST_MAX_SIZE_HALF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 		/* move the pointer to the correct range */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 		*ptr += (SPI_TEST_MAX_SIZE_PLUS / 2) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) 			SPI_TEST_MAX_SIZE_HALF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) 	/* RX range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 	 * - we check against MAX_SIZE_PLUS to allow for automated alignment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 	if (RANGE_CHECK(*ptr, len,  RX(0), SPI_TEST_MAX_SIZE_PLUS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) 		off = *ptr - RX(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 		*ptr = rx + off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 	/* TX range */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) 	if (RANGE_CHECK(*ptr, len,  TX(0), SPI_TEST_MAX_SIZE_PLUS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 		off = *ptr - TX(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) 		*ptr = tx + off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) 	dev_err(&spi->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) 		"PointerRange [%pK:%pK[ not in range [%pK:%pK[ or [%pK:%pK[\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) 		*ptr, *ptr + len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) 		RX(0), RX(SPI_TEST_MAX_SIZE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 		TX(0), TX(SPI_TEST_MAX_SIZE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) 	return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) static int spi_test_fill_pattern(struct spi_device *spi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) 				 struct spi_test *test)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 	struct spi_transfer *xfers = test->transfers;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) 	u8 *tx_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 	size_t count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) 	int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) #ifdef __BIG_ENDIAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) #define GET_VALUE_BYTE(value, index, bytes) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 	(value >> (8 * (bytes - 1 - count % bytes)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) #define GET_VALUE_BYTE(value, index, bytes) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) 	(value >> (8 * (count % bytes)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 	/* fill all transfers with the pattern requested */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 	for (i = 0; i < test->transfer_count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 		/* fill rx_buf with SPI_TEST_PATTERN_UNWRITTEN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 		if (xfers[i].rx_buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 			memset(xfers[i].rx_buf, SPI_TEST_PATTERN_UNWRITTEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) 			       xfers[i].len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 		/* if tx_buf is NULL then skip */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 		tx_buf = (u8 *)xfers[i].tx_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) 		if (!tx_buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 		/* modify all the transfers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 		for (j = 0; j < xfers[i].len; j++, tx_buf++, count++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) 			/* fill tx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 			switch (test->fill_option) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) 			case FILL_MEMSET_8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 				*tx_buf = test->fill_pattern;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 			case FILL_MEMSET_16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 				*tx_buf = GET_VALUE_BYTE(test->fill_pattern,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 							 count, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 			case FILL_MEMSET_24:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 				*tx_buf = GET_VALUE_BYTE(test->fill_pattern,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) 							 count, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) 			case FILL_MEMSET_32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 				*tx_buf = GET_VALUE_BYTE(test->fill_pattern,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) 							 count, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) 			case FILL_COUNT_8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) 				*tx_buf = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) 			case FILL_COUNT_16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) 				*tx_buf = GET_VALUE_BYTE(count, count, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) 			case FILL_COUNT_24:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 				*tx_buf = GET_VALUE_BYTE(count, count, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 			case FILL_COUNT_32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 				*tx_buf = GET_VALUE_BYTE(count, count, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 			case FILL_TRANSFER_BYTE_8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 				*tx_buf = j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 			case FILL_TRANSFER_BYTE_16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 				*tx_buf = GET_VALUE_BYTE(j, j, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 			case FILL_TRANSFER_BYTE_24:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 				*tx_buf = GET_VALUE_BYTE(j, j, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 			case FILL_TRANSFER_BYTE_32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 				*tx_buf = GET_VALUE_BYTE(j, j, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 			case FILL_TRANSFER_NUM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 				*tx_buf = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 			default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 				dev_err(&spi->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 					"unsupported fill_option: %i\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 					test->fill_option);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 				return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) static int _spi_test_run_iter(struct spi_device *spi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 			      struct spi_test *test,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 			      void *tx, void *rx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 	struct spi_message *msg = &test->msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) 	struct spi_transfer *x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 	int i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) 	/* initialize message - zero-filled via static initialization */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 	spi_message_init_no_memset(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 	/* fill rx with the DO_NOT_WRITE pattern */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 	memset(rx, SPI_TEST_PATTERN_DO_NOT_WRITE, SPI_TEST_MAX_SIZE_PLUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 	/* add the individual transfers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 	for (i = 0; i < test->transfer_count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 		x = &test->transfers[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) 		/* patch the values of tx_buf */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 		ret = spi_test_translate(spi, (void **)&x->tx_buf, x->len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 					 (void *)tx, rx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 		/* patch the values of rx_buf */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 		ret = spi_test_translate(spi, &x->rx_buf, x->len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 					 (void *)tx, rx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 		/* and add it to the list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 		spi_message_add_tail(x, msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 	/* fill in the transfer buffers with pattern */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 	ret = spi_test_fill_pattern(spi, test);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 	/* and execute */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 	if (test->execute_msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 		ret = test->execute_msg(spi, test, tx, rx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 		ret = spi_test_execute_msg(spi, test, tx, rx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) 	/* handle result */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 	if (ret == test->expected_return)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) 	dev_err(&spi->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 		"test failed - test returned %i, but we expect %i\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) 		ret, test->expected_return);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) 	/* if it is 0, as we expected something else,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 	 * then return something special
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 	return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) static int spi_test_run_iter(struct spi_device *spi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) 			     const struct spi_test *testtemplate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 			     void *tx, void *rx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 			     size_t len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 			     size_t tx_off,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) 			     size_t rx_off
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) 	)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 	struct spi_test test;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 	int i, tx_count, rx_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 	/* copy the test template to test */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 	memcpy(&test, testtemplate, sizeof(test));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 	/* if iterate_transfer_mask is not set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 	 * then set it to first transfer only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) 	if (!(test.iterate_transfer_mask & (BIT(test.transfer_count) - 1)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 		test.iterate_transfer_mask = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 	/* count number of transfers with tx/rx_buf != NULL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 	rx_count = tx_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) 	for (i = 0; i < test.transfer_count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) 		if (test.transfers[i].tx_buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 			tx_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 		if (test.transfers[i].rx_buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) 			rx_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 	/* in some iteration cases warn and exit early,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 	 * as there is nothing to do, that has not been tested already...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) 	if (tx_off && (!tx_count)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 		dev_warn_once(&spi->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 			      "%s: iterate_tx_off configured with tx_buf==NULL - ignoring\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) 			      test.description);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 	if (rx_off && (!rx_count)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 		dev_warn_once(&spi->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 			      "%s: iterate_rx_off configured with rx_buf==NULL - ignoring\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 			      test.description);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 	/* write out info */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 	if (!(len || tx_off || rx_off)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 		dev_info(&spi->dev, "Running test %s\n", test.description);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 		dev_info(&spi->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 			 "  with iteration values: len = %zu, tx_off = %zu, rx_off = %zu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) 			 len, tx_off, rx_off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 	/* update in the values from iteration values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 	for (i = 0; i < test.transfer_count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 		/* only when bit in transfer mask is set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 		if (!(test.iterate_transfer_mask & BIT(i)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 		test.transfers[i].len = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 		if (test.transfers[i].tx_buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 			test.transfers[i].tx_buf += tx_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 		if (test.transfers[i].rx_buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 			test.transfers[i].rx_buf += rx_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 	/* and execute */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 	return _spi_test_run_iter(spi, &test, tx, rx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886)  * spi_test_execute_msg - default implementation to run a test
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888)  * @spi: @spi_device on which to run the @spi_message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889)  * @test: the test to execute, which already contains @msg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890)  * @tx:   the tx buffer allocated for the test sequence
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891)  * @rx:   the rx buffer allocated for the test sequence
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893)  * Returns: error code of spi_sync as well as basic error checking
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) int spi_test_execute_msg(struct spi_device *spi, struct spi_test *test,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 			 void *tx, void *rx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 	struct spi_message *msg = &test->msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) 	/* only if we do not simulate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) 	if (!simulate_only) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) 		ktime_t start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) 		/* dump the complete message before and after the transfer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) 		if (dump_messages == 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 			spi_test_dump_message(spi, msg, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) 		start = ktime_get();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 		/* run spi message */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) 		ret = spi_sync(spi, msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) 		test->elapsed_time = ktime_to_ns(ktime_sub(ktime_get(), start));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) 		if (ret == -ETIMEDOUT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) 			dev_info(&spi->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 				 "spi-message timed out - rerunning...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) 			/* rerun after a few explicit schedules */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 			for (i = 0; i < 16; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) 				schedule();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) 			ret = spi_sync(spi, msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 		if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 			dev_err(&spi->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 				"Failed to execute spi_message: %i\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 				ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 			goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 		/* do some extra error checks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 		if (msg->frame_length != msg->actual_length) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 			dev_err(&spi->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 				"actual length differs from expected\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 			ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 			goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 		/* run rx-buffer tests */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 		ret = spi_test_check_loopback_result(spi, msg, tx, rx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 			goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) 		ret = spi_test_check_elapsed_time(spi, test);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 	/* if requested or on error dump message (including data) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 	if (dump_messages || ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 		spi_test_dump_message(spi, msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 				      (dump_messages >= 2) || (ret));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) EXPORT_SYMBOL_GPL(spi_test_execute_msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956)  * spi_test_run_test - run an individual spi_test
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957)  *                     including all the relevant iterations on:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958)  *                     length and buffer alignment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960)  * @spi:  the spi_device to send the messages to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961)  * @test: the test which we need to execute
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962)  * @tx:   the tx buffer allocated for the test sequence
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963)  * @rx:   the rx buffer allocated for the test sequence
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965)  * Returns: status code of spi_sync or other failures
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) int spi_test_run_test(struct spi_device *spi, const struct spi_test *test,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) 		      void *tx, void *rx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) 	int idx_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) 	size_t len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) 	size_t tx_align, rx_align;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) 	/* test for transfer limits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) 	if (test->transfer_count >= SPI_TEST_MAX_TRANSFERS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 		dev_err(&spi->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 			"%s: Exceeded max number of transfers with %i\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 			test->description, test->transfer_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 		return -E2BIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 	/* setting up some values in spi_message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 	 * based on some settings in spi_master
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 	 * some of this can also get done in the run() method
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 	/* iterate over all the iterable values using macros
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 	 * (to make it a bit more readable...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) #define FOR_EACH_ALIGNMENT(var)						\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 	for (var = 0;							\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 	    var < (test->iterate_##var ?				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 			(spi->master->dma_alignment ?			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 			 spi->master->dma_alignment :			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 			 test->iterate_##var) :				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 			1);						\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 	    var++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) 	for (idx_len = 0; idx_len < SPI_TEST_MAX_ITERATE &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) 	     (len = test->iterate_len[idx_len]) != -1; idx_len++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) 		FOR_EACH_ALIGNMENT(tx_align) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) 			FOR_EACH_ALIGNMENT(rx_align) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) 				/* and run the iteration */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 				ret = spi_test_run_iter(spi, test,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 							tx, rx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) 							len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 							tx_align,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 							rx_align);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 				if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 					return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) EXPORT_SYMBOL_GPL(spi_test_run_test);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022)  * spi_test_run_tests - run an array of spi_messages tests
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023)  * @spi: the spi device on which to run the tests
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024)  * @tests: NULL-terminated array of @spi_test
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026)  * Returns: status errors as per @spi_test_run_test()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) int spi_test_run_tests(struct spi_device *spi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) 		       struct spi_test *tests)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) 	char *rx = NULL, *tx = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 	int ret = 0, count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 	struct spi_test *test;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) 	/* allocate rx/tx buffers of 128kB size without devm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 	 * in the hope that is on a page boundary
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) 	if (use_vmalloc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) 		rx = vmalloc(SPI_TEST_MAX_SIZE_PLUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 		rx = kzalloc(SPI_TEST_MAX_SIZE_PLUS, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) 	if (!rx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) 	if (use_vmalloc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) 		tx = vmalloc(SPI_TEST_MAX_SIZE_PLUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) 		tx = kzalloc(SPI_TEST_MAX_SIZE_PLUS, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) 	if (!tx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) 		ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) 		goto err_tx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) 	/* now run the individual tests in the table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) 	for (test = tests, count = 0; test->description[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) 	     test++, count++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) 		/* only run test if requested */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) 		if ((run_only_test > -1) && (count != run_only_test))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 		/* run custom implementation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 		if (test->run_test)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 			ret = test->run_test(spi, test, tx, rx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 			ret = spi_test_run_test(spi, test, tx, rx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 		/* add some delays so that we can easily
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 		 * detect the individual tests when using a logic analyzer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 		 * we also add scheduling to avoid potential spi_timeouts...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 		mdelay(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 		schedule();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 	kvfree(tx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) err_tx:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 	kvfree(rx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) EXPORT_SYMBOL_GPL(spi_test_run_tests);