Blob Blame History Raw
From 95c07247399536f83b89dc60cfe7b279d17e69f6 Mon Sep 17 00:00:00 2001
From: Hector Martin <marcan@marcan.st>
Date: Sat, 11 Dec 2021 02:05:34 +0900
Subject: [PATCH] spi: Fix incorrect cs_setup delay handling
Git-commit: 95c07247399536f83b89dc60cfe7b279d17e69f6
Patch-mainline: v5.17-rc1
References: git-fixes

Move the cs_setup delay to the end of spi_set_cs.

From include/linux/spi/spi.h:

 * @cs_setup: delay to be introduced by the controller after CS is
   asserted

The cs_setup delay needs to happen *after* CS is asserted, that is, at
the end of spi_set_cs, not at the beginning. Otherwise we're just
delaying before the SPI transaction starts at all, which isn't very
useful.

No drivers use this right now, but that is likely to change soon with an
upcoming Apple SPI HID transport driver.

Fixes: 25093bdeb6bc ("spi: implement SW control for CS times")
Signed-off-by: Hector Martin <marcan@marcan.st>
Link: https://lore.kernel.org/r/20211210170534.177139-1-marcan@marcan.st
Signed-off-by: Mark Brown <broonie@kernel.org>
Acked-by: Takashi Iwai <tiwai@suse.de>

---
 drivers/spi/spi.c |   13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -868,12 +868,9 @@ static void spi_set_cs(struct spi_device
 	spi->controller->last_cs_enable = enable;
 	spi->controller->last_cs_mode_high = spi->mode & SPI_CS_HIGH;
 
-	if (spi->cs_gpiod || gpio_is_valid(spi->cs_gpio) ||
-	    !spi->controller->set_cs_timing) {
-		if (activate)
-			spi_delay_exec(&spi->controller->cs_setup, NULL);
-		else
-			spi_delay_exec(&spi->controller->cs_hold, NULL);
+	if ((spi->cs_gpiod || gpio_is_valid(spi->cs_gpio) ||
+	    !spi->controller->set_cs_timing) && !activate) {
+		spi_delay_exec(&spi->controller->cs_hold, NULL);
 	}
 
 	if (spi->mode & SPI_CS_HIGH)
@@ -915,7 +912,9 @@ static void spi_set_cs(struct spi_device
 
 	if (spi->cs_gpiod || gpio_is_valid(spi->cs_gpio) ||
 	    !spi->controller->set_cs_timing) {
-		if (!activate)
+		if (activate)
+			spi_delay_exec(&spi->controller->cs_setup, NULL);
+		else
 			spi_delay_exec(&spi->controller->cs_inactive, NULL);
 	}
 }