spi: make `cs_change_delay` the first user of the `spi_delay` logic
authorAlexandru Ardelean <alexandru.ardelean@analog.com>
Thu, 26 Sep 2019 10:51:31 +0000 (13:51 +0300)
committerMark Brown <broonie@kernel.org>
Tue, 15 Oct 2019 10:41:47 +0000 (11:41 +0100)
Since the logic for `spi_delay` struct + `spi_delay_exec()` has been copied
from the `cs_change_delay` logic, it's natural to make this delay, the
first user.

The `cs_change_delay` logic requires that the default remain 10 uS, in case
it is unspecified/unconfigured. So, there is some special handling needed
to do that.

The ADIS library is one of the few users of the new `cs_change_delay`
parameter for an spi_transfer.

The introduction of the `spi_delay` struct, requires that the users of of
`cs_change_delay` get an update. This change also updates the ADIS library.

Signed-off-by: Alexandru Ardelean <alexandru.ardelean@analog.com>
Link: https://lore.kernel.org/r/20190926105147.7839-4-alexandru.ardelean@analog.com
Signed-off-by: Mark Brown <broonie@kernel.org>
drivers/iio/imu/adis.c
drivers/spi/spi.c
include/linux/spi/spi.h

index 1631c255deab1a662c60dcaeff64407c46630961..2cd2cc2316c6deb8e55ed96deb4c094189c10f94 100644 (file)
@@ -39,24 +39,24 @@ int adis_write_reg(struct adis *adis, unsigned int reg,
                        .len = 2,
                        .cs_change = 1,
                        .delay_usecs = adis->data->write_delay,
-                       .cs_change_delay = adis->data->cs_change_delay,
-                       .cs_change_delay_unit = SPI_DELAY_UNIT_USECS,
+                       .cs_change_delay.value = adis->data->cs_change_delay,
+                       .cs_change_delay.unit = SPI_DELAY_UNIT_USECS,
                }, {
                        .tx_buf = adis->tx + 2,
                        .bits_per_word = 8,
                        .len = 2,
                        .cs_change = 1,
                        .delay_usecs = adis->data->write_delay,
-                       .cs_change_delay = adis->data->cs_change_delay,
-                       .cs_change_delay_unit = SPI_DELAY_UNIT_USECS,
+                       .cs_change_delay.value = adis->data->cs_change_delay,
+                       .cs_change_delay.unit = SPI_DELAY_UNIT_USECS,
                }, {
                        .tx_buf = adis->tx + 4,
                        .bits_per_word = 8,
                        .len = 2,
                        .cs_change = 1,
                        .delay_usecs = adis->data->write_delay,
-                       .cs_change_delay = adis->data->cs_change_delay,
-                       .cs_change_delay_unit = SPI_DELAY_UNIT_USECS,
+                       .cs_change_delay.value = adis->data->cs_change_delay,
+                       .cs_change_delay.unit = SPI_DELAY_UNIT_USECS,
                }, {
                        .tx_buf = adis->tx + 6,
                        .bits_per_word = 8,
@@ -139,16 +139,16 @@ int adis_read_reg(struct adis *adis, unsigned int reg,
                        .len = 2,
                        .cs_change = 1,
                        .delay_usecs = adis->data->write_delay,
-                       .cs_change_delay = adis->data->cs_change_delay,
-                       .cs_change_delay_unit = SPI_DELAY_UNIT_USECS,
+                       .cs_change_delay.value = adis->data->cs_change_delay,
+                       .cs_change_delay.unit = SPI_DELAY_UNIT_USECS,
                }, {
                        .tx_buf = adis->tx + 2,
                        .bits_per_word = 8,
                        .len = 2,
                        .cs_change = 1,
                        .delay_usecs = adis->data->read_delay,
-                       .cs_change_delay = adis->data->cs_change_delay,
-                       .cs_change_delay_unit = SPI_DELAY_UNIT_USECS,
+                       .cs_change_delay.value = adis->data->cs_change_delay,
+                       .cs_change_delay.unit = SPI_DELAY_UNIT_USECS,
                }, {
                        .tx_buf = adis->tx + 4,
                        .rx_buf = adis->rx,
@@ -156,8 +156,8 @@ int adis_read_reg(struct adis *adis, unsigned int reg,
                        .len = 2,
                        .cs_change = 1,
                        .delay_usecs = adis->data->read_delay,
-                       .cs_change_delay = adis->data->cs_change_delay,
-                       .cs_change_delay_unit = SPI_DELAY_UNIT_USECS,
+                       .cs_change_delay.value = adis->data->cs_change_delay,
+                       .cs_change_delay.unit = SPI_DELAY_UNIT_USECS,
                }, {
                        .rx_buf = adis->rx + 2,
                        .bits_per_word = 8,
index 7499a4efbaba5b24a5c62446485a2e8d56395ea9..b69c14082c52853b8bc6235e428fe441a3980872 100644 (file)
@@ -1160,9 +1160,9 @@ EXPORT_SYMBOL_GPL(spi_delay_exec);
 static void _spi_transfer_cs_change_delay(struct spi_message *msg,
                                          struct spi_transfer *xfer)
 {
-       u32 delay = xfer->cs_change_delay;
-       u32 unit = xfer->cs_change_delay_unit;
-       u32 hz;
+       u32 delay = xfer->cs_change_delay.value;
+       u32 unit = xfer->cs_change_delay.unit;
+       int ret;
 
        /* return early on "fast" mode - for everything but USECS */
        if (!delay) {
@@ -1171,27 +1171,13 @@ static void _spi_transfer_cs_change_delay(struct spi_message *msg,
                return;
        }
 
-       switch (unit) {
-       case SPI_DELAY_UNIT_USECS:
-               delay *= 1000;
-               break;
-       case SPI_DELAY_UNIT_NSECS: /* nothing to do here */
-               break;
-       case SPI_DELAY_UNIT_SCK:
-               /* if there is no effective speed know, then approximate
-                * by underestimating with half the requested hz
-                */
-               hz = xfer->effective_speed_hz ?: xfer->speed_hz / 2;
-               delay *= DIV_ROUND_UP(1000000000, hz);
-               break;
-       default:
+       ret = spi_delay_exec(&xfer->cs_change_delay, xfer);
+       if (ret) {
                dev_err_once(&msg->spi->dev,
                             "Use of unsupported delay unit %i, using default of 10us\n",
-                            xfer->cs_change_delay_unit);
-               delay = 10000;
+                            unit);
+               _spi_transfer_delay_ns(10000);
        }
-       /* now sleep for the requested amount of time */
-       _spi_transfer_delay_ns(delay);
 }
 
 /*
index 8f643de3197b4d78c51e42ae69606ccc4f6fab27..7670be934643535c5b3b111ba718880ec0904c01 100644 (file)
@@ -778,7 +778,6 @@ extern void spi_res_release(struct spi_controller *ctlr,
  * @cs_change: affects chipselect after this transfer completes
  * @cs_change_delay: delay between cs deassert and assert when
  *      @cs_change is set and @spi_transfer is not the last in @spi_message
- * @cs_change_delay_unit: unit of cs_change_delay
  * @delay_usecs: microseconds to delay after this transfer before
  *     (optionally) changing the chipselect status, then starting
  *     the next transfer or completing this @spi_message.
@@ -900,8 +899,7 @@ struct spi_transfer {
        u8              bits_per_word;
        u8              word_delay_usecs;
        u16             delay_usecs;
-       u16             cs_change_delay;
-       u8              cs_change_delay_unit;
+       struct spi_delay        cs_change_delay;
        u32             speed_hz;
        u16             word_delay;