soc: qcom: glink_spi_xprt: Remove extra SPI transactions

The TX FIFO write reg and the RX FIFO read reg are controlled
by this processor. Keep track of the state of these two indexes
to reduce the amount of SPI reads.

CRs-Fixed: 2093123
Change-Id: I4ffa0e08bce6dabd57f33a13fef8107211ce3f09
Signed-off-by: Chris Lew <clew@codeaurora.org>
diff --git a/drivers/soc/qcom/glink_spi_xprt.c b/drivers/soc/qcom/glink_spi_xprt.c
index c44aa93..a08c4bf 100644
--- a/drivers/soc/qcom/glink_spi_xprt.c
+++ b/drivers/soc/qcom/glink_spi_xprt.c
@@ -121,6 +121,8 @@
  * @tx_fifo_write_reg_addr:	Address of the TX FIFO Write Index Register.
  * @rx_fifo_read_reg_addr:	Address of the RX FIFO Read Index Register.
  * @rx_fifo_write_reg_addr:	Address of the RX FIFO Write Index Register.
+ * @tx_fifo_write:		Internal write index for TX FIFO.
+ * @rx_fifo_read:		Internal read index for RX FIFO.
  * @kwork:			Work to be executed when receiving data.
  * @kworker:			Handle to the entity processing @kwork.
  * @task:			Handle to the task context that runs @kworker.
@@ -158,6 +160,8 @@
 	unsigned int tx_fifo_write_reg_addr;
 	unsigned int rx_fifo_read_reg_addr;
 	unsigned int rx_fifo_write_reg_addr;
+	uint32_t tx_fifo_write;
+	uint32_t rx_fifo_read;
 
 	struct kthread_work kwork;
 	struct kthread_worker kworker;
@@ -374,6 +378,19 @@
 	int write_avail;
 	int ret;
 
+	if (unlikely(!einfo->tx_fifo_start)) {
+		ret = glink_spi_xprt_reg_read(einfo,
+			einfo->tx_fifo_write_reg_addr, &einfo->tx_fifo_write);
+		if (ret < 0) {
+			pr_err("%s: Error %d reading %s tx_fifo_write_reg_addr %d\n",
+				__func__, ret, einfo->xprt_cfg.edge,
+				einfo->tx_fifo_write_reg_addr);
+			return 0;
+		}
+		einfo->tx_fifo_start = einfo->tx_fifo_write;
+	}
+	write_id = einfo->tx_fifo_write;
+
 	ret = glink_spi_xprt_reg_read(einfo, einfo->tx_fifo_read_reg_addr,
 				   &read_id);
 	if (ret < 0) {
@@ -383,21 +400,9 @@
 		return 0;
 	}
 
-	ret = glink_spi_xprt_reg_read(einfo, einfo->tx_fifo_write_reg_addr,
-				&write_id);
-	if (ret < 0) {
-		pr_err("%s: Error %d reading %s tx_fifo_write_reg_addr %d\n",
-			__func__, ret, einfo->xprt_cfg.edge,
-			einfo->tx_fifo_write_reg_addr);
-		return 0;
-	}
-
 	if (!read_id || !write_id)
 		return 0;
 
-	if (unlikely(!einfo->tx_fifo_start))
-		einfo->tx_fifo_start = write_id;
-
 	if (read_id > write_id)
 		write_avail = read_id - write_id;
 	else
@@ -427,14 +432,18 @@
 	int read_avail;
 	int ret;
 
-	ret = glink_spi_xprt_reg_read(einfo, einfo->rx_fifo_read_reg_addr,
-				   &read_id);
-	if (ret < 0) {
-		pr_err("%s: Error %d reading %s rx_fifo_read_reg_addr %d\n",
-			__func__, ret, einfo->xprt_cfg.edge,
-			einfo->rx_fifo_read_reg_addr);
-		return 0;
+	if (unlikely(!einfo->rx_fifo_start)) {
+		ret = glink_spi_xprt_reg_read(einfo,
+			einfo->rx_fifo_read_reg_addr, &einfo->rx_fifo_read);
+		if (ret < 0) {
+			pr_err("%s: Error %d reading %s rx_fifo_read_reg_addr %d\n",
+				__func__, ret, einfo->xprt_cfg.edge,
+				einfo->rx_fifo_read_reg_addr);
+			return 0;
+		}
+		einfo->rx_fifo_start = einfo->rx_fifo_read;
 	}
+	read_id = einfo->rx_fifo_read;
 
 	ret = glink_spi_xprt_reg_read(einfo, einfo->rx_fifo_write_reg_addr,
 				&write_id);
@@ -448,9 +457,6 @@
 	if (!read_id || !write_id)
 		return 0;
 
-	if (unlikely(!einfo->rx_fifo_start))
-		einfo->rx_fifo_start = read_id;
-
 	if (read_id <= write_id)
 		read_avail = write_id - read_id;
 	else
@@ -477,15 +483,7 @@
 	uint32_t offset = 0;
 	int ret;
 
-	ret = glink_spi_xprt_reg_read(einfo, einfo->rx_fifo_read_reg_addr,
-				   &read_id);
-	if (ret < 0) {
-		pr_err("%s: Error %d reading %s rx_fifo_read_reg_addr %d\n",
-			__func__, ret, einfo->xprt_cfg.edge,
-			einfo->rx_fifo_read_reg_addr);
-		return ret;
-	}
-
+	read_id = einfo->rx_fifo_read;
 	do {
 		if ((read_id + size_to_read) >=
 		    (einfo->rx_fifo_start + einfo->fifo_size))
@@ -510,6 +508,9 @@
 		pr_err("%s: Error %d writing %s rx_fifo_read_reg_addr %d\n",
 			__func__, ret, einfo->xprt_cfg.edge,
 			einfo->rx_fifo_read_reg_addr);
+	else
+		einfo->rx_fifo_read = read_id;
+
 	return ret;
 }
 
@@ -532,15 +533,7 @@
 	uint32_t offset = 0;
 	int ret;
 
-	ret = glink_spi_xprt_reg_read(einfo, einfo->tx_fifo_write_reg_addr,
-				&write_id);
-	if (ret < 0) {
-		pr_err("%s: Error %d reading %s tx_fifo_write_reg_addr %d\n",
-			__func__, ret, einfo->xprt_cfg.edge,
-			einfo->tx_fifo_write_reg_addr);
-		return ret;
-	}
-
+	write_id = einfo->tx_fifo_write;
 	do {
 		if ((write_id + size_to_write) >=
 		    (einfo->tx_fifo_start + einfo->fifo_size))
@@ -565,6 +558,9 @@
 		pr_err("%s: Error %d writing %s tx_fifo_write_reg_addr %d\n",
 			__func__, ret, einfo->xprt_cfg.edge,
 			einfo->tx_fifo_write_reg_addr);
+	else
+		einfo->tx_fifo_write = write_id;
+
 	return ret;
 }
 
@@ -1242,6 +1238,8 @@
 	einfo->tx_blocked_signal_sent = false;
 	einfo->tx_fifo_start = 0;
 	einfo->rx_fifo_start = 0;
+	einfo->tx_fifo_write = 0;
+	einfo->rx_fifo_read = 0;
 	einfo->fifo_size = DEFAULT_FIFO_SIZE;
 	einfo->xprt_if.glink_core_if_ptr->link_down(&einfo->xprt_if);