spi: Fix incorrect cs_setup delay handling
authorHector Martin <marcan@marcan.st>
Fri, 10 Dec 2021 17:05:34 +0000 (02:05 +0900)
committerMark Brown <broonie@kernel.org>
Mon, 13 Dec 2021 19:35:45 +0000 (19:35 +0000)
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>
drivers/spi/spi.c

index 8726309b3eaf2844180cc0fadda0f47cedd11d55..7c790858547cf43a2053f98e92e55df935e6ef57 100644 (file)
@@ -944,12 +944,9 @@ static void spi_set_cs(struct spi_device *spi, bool enable, bool force)
        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->cs_setup, NULL);
-               else
-                       spi_delay_exec(&spi->cs_hold, NULL);
+       if ((spi->cs_gpiod || gpio_is_valid(spi->cs_gpio) ||
+           !spi->controller->set_cs_timing) && !activate) {
+               spi_delay_exec(&spi->cs_hold, NULL);
        }
 
        if (spi->mode & SPI_CS_HIGH)
@@ -991,7 +988,9 @@ static void spi_set_cs(struct spi_device *spi, bool enable, bool force)
 
        if (spi->cs_gpiod || gpio_is_valid(spi->cs_gpio) ||
            !spi->controller->set_cs_timing) {
-               if (!activate)
+               if (activate)
+                       spi_delay_exec(&spi->cs_setup, NULL);
+               else
                        spi_delay_exec(&spi->cs_inactive, NULL);
        }
 }