]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
iio: adc: ti-ads7950: use spi_optimize_message()
authorDavid Lechner <dlechner@baylibre.com>
Sat, 11 Apr 2026 22:13:33 +0000 (17:13 -0500)
committerJonathan Cameron <jic23@kernel.org>
Mon, 27 Apr 2026 08:58:21 +0000 (09:58 +0100)
Use spi_optimize_message() to reduce CPU usage during buffered reads.

On hardware with support for SPI_CS_WORD, this reduced the CPU usage
of the threaded interrupt by about 5%. On hardware without support, this
should reduce CPU usage even more since it won't have to split the SPI
transfers each time the interrupt handler is called.

The .update_scan_mode() callback hand to be moved to the buffer preenable
callback since the SPI transfer mode can't be changed after
spi_optimize_message() has been called. (The buffer postenable callback
can't be used because it happens after the trigger is enabled, so the
SPI message needs to be optimized before that.)

The indent of the pointer to ti_ads7950_read_raw() in the assignment
is changed since there is no longer anything else in the struct to
align with since removal of use of the pointer to
ti_ads7950_update_scan_mode().

Signed-off-by: David Lechner <dlechner@baylibre.com>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>
drivers/iio/adc/ti-ads7950.c

index 882b280d9e0b96cd8e1af099459d94c67537758b..39a074bce6d55d54f1ce588bd5bcb8c8a3346eea 100644 (file)
@@ -267,31 +267,6 @@ static const struct ti_ads7950_chip_info ti_ads7961_chip_info = {
        .num_channels   = ARRAY_SIZE(ti_ads7961_channels),
 };
 
-/*
- * ti_ads7950_update_scan_mode() setup the spi transfer buffer for the new
- * scan mask
- */
-static int ti_ads7950_update_scan_mode(struct iio_dev *indio_dev,
-                                      const unsigned long *active_scan_mask)
-{
-       struct ti_ads7950_state *st = iio_priv(indio_dev);
-       int i, cmd, len;
-
-       len = 0;
-       for_each_set_bit(i, active_scan_mask, indio_dev->num_channels) {
-               cmd = TI_ADS7950_MAN_CMD(TI_ADS7950_CR_CHAN(i));
-               st->tx_buf[len++] = cmd;
-       }
-
-       /* Data for the 1st channel is not returned until the 3rd transfer */
-       st->tx_buf[len++] = 0;
-       st->tx_buf[len++] = 0;
-
-       st->ring_xfer.len = len * 2;
-
-       return 0;
-}
-
 static irqreturn_t ti_ads7950_trigger_handler(int irq, void *p)
 {
        struct iio_poll_func *pf = p;
@@ -375,8 +350,42 @@ static int ti_ads7950_read_raw(struct iio_dev *indio_dev,
 }
 
 static const struct iio_info ti_ads7950_info = {
-       .read_raw               = &ti_ads7950_read_raw,
-       .update_scan_mode       = ti_ads7950_update_scan_mode,
+       .read_raw = &ti_ads7950_read_raw,
+};
+
+static int ti_ads7950_buffer_preenable(struct iio_dev *indio_dev)
+{
+       struct ti_ads7950_state *st = iio_priv(indio_dev);
+       u32 len = 0;
+       u32 i;
+       u16 cmd;
+
+       for_each_set_bit(i, indio_dev->active_scan_mask, indio_dev->num_channels) {
+               cmd = TI_ADS7950_MAN_CMD(TI_ADS7950_CR_CHAN(i));
+               st->tx_buf[len++] = cmd;
+       }
+
+       /* Data for the 1st channel is not returned until the 3rd transfer */
+       st->tx_buf[len++] = 0;
+       st->tx_buf[len++] = 0;
+
+       st->ring_xfer.len = len * 2;
+
+       return spi_optimize_message(st->spi, &st->ring_msg);
+}
+
+static int ti_ads7950_buffer_postdisable(struct iio_dev *indio_dev)
+{
+       struct ti_ads7950_state *st = iio_priv(indio_dev);
+
+       spi_unoptimize_message(&st->ring_msg);
+
+       return 0;
+}
+
+static const struct iio_buffer_setup_ops ti_ads7950_buffer_setup_ops = {
+       .preenable = ti_ads7950_buffer_preenable,
+       .postdisable = ti_ads7950_buffer_postdisable,
 };
 
 static int ti_ads7950_set(struct gpio_chip *chip, unsigned int offset,
@@ -573,7 +582,7 @@ static int ti_ads7950_probe(struct spi_device *spi)
 
        ret = devm_iio_triggered_buffer_setup(&spi->dev, indio_dev, NULL,
                                              &ti_ads7950_trigger_handler,
-                                             NULL);
+                                             &ti_ads7950_buffer_setup_ops);
        if (ret)
                return dev_err_probe(&spi->dev, ret,
                                     "Failed to setup triggered buffer\n");