spi_qsd: Support delay per transfer if requested by the client

Client has ability to request delay per transfer through SPI
framework. SPI controller driver needs to put this delay after every
transfer. However, this also means that multiple transfers per message
cannot be combined to be able to insert this delay per transfer.
CS will be de-asserted after completion of each transfer
on older version of QUP/SPI core.

CRs-fixed: 416186
Change-Id: Id9266ce7043e020fa7e1233c66baba30ba3d496c
Signed-off-by: Gilad Avidov <gavidov@codeaurora.org>
Signed-off-by: Sagar Dharia <sdharia@codeaurora.org>
Signed-off-by: Alok Chauhan <alokc@codeaurora.org>
(cherry picked from commit 525593d47c425c666bdbe73c592fd5ff37cf622e)

Signed-off-by: Sudhir Sharma <sudsha@codeaurora.org>
diff --git a/drivers/spi/spi_qsd.c b/drivers/spi/spi_qsd.c
index c26da60..fd98925 100644
--- a/drivers/spi/spi_qsd.c
+++ b/drivers/spi/spi_qsd.c
@@ -284,6 +284,18 @@
 	return spi_op & SPI_OP_STATE_VALID;
 }
 
+static inline void msm_spi_udelay(unsigned long delay_usecs)
+{
+	/*
+	 * For smaller values of delay, context switch time
+	 * would negate the usage of usleep
+	 */
+	if (delay_usecs > 20)
+		usleep_range(delay_usecs, delay_usecs);
+	else if (delay_usecs)
+		udelay(delay_usecs);
+}
+
 static inline int msm_spi_wait_valid(struct msm_spi *dd)
 {
 	unsigned long delay = 0;
@@ -317,14 +329,7 @@
 			} else
 				return 0;
 		}
-		/*
-		 * For smaller values of delay, context switch time
-		 * would negate the usage of usleep
-		 */
-		if (delay > 20)
-			usleep(delay);
-		else if (delay)
-			udelay(delay);
+		msm_spi_udelay(delay);
 	}
 	return 0;
 }
@@ -1101,6 +1106,7 @@
 		}
 	} while (msm_spi_dm_send_next(dd));
 
+	msm_spi_udelay(dd->cur_transfer->delay_usecs);
 transfer_end:
 	if (dd->mode == SPI_DMOV_MODE)
 		msm_spi_unmap_dma_buffers(dd);
@@ -1194,6 +1200,8 @@
 	int xfrs_grped = 0;
 	int cs_num;
 	int rc;
+	bool xfer_delay = false;
+	struct spi_transfer *tr;
 
 	dd->write_xfr_cnt = dd->read_xfr_cnt = 0;
 	cs_num = dd->cur_msg->spi->chip_select;
@@ -1211,8 +1219,21 @@
 		dd->cs_gpios[cs_num].valid = 1;
 	}
 
-	if (dd->qup_ver) {
-		write_force_cs(dd, 0);
+	list_for_each_entry(tr,
+				&dd->cur_msg->transfers,
+				transfer_list) {
+		if (tr->delay_usecs) {
+			dev_info(dd->dev, "SPI slave requests delay per txn :%d",
+					tr->delay_usecs);
+			xfer_delay = true;
+			break;
+		}
+	}
+
+	/* Don't combine xfers if delay is needed after every xfer */
+	if (dd->qup_ver || xfer_delay) {
+		if (dd->qup_ver)
+			write_force_cs(dd, 0);
 		list_for_each_entry(dd->cur_transfer,
 				&dd->cur_msg->transfers,
 				transfer_list) {
@@ -1224,9 +1245,10 @@
 						struct spi_transfer,
 						transfer_list);
 
-				if (t->cs_change == nxt->cs_change)
+				if (dd->qup_ver &&
+					t->cs_change == nxt->cs_change)
 					write_force_cs(dd, 1);
-				else
+				else if (dd->qup_ver)
 					write_force_cs(dd, 0);
 			}