On Mon, 2024-02-19 at 16:33 -0600, David Lechner wrote: > This modifies the ad7380 ADC driver to use spi_optimize_message() to > optimize the SPI message for the buffered read operation. Since buffered > reads reuse the same SPI message for each read, this can improve > performance by reducing the overhead of setting up some parts the SPI > message in each spi_sync() call. > > Signed-off-by: David Lechner <dlechner@xxxxxxxxxxxx> > --- > Reviewed-by: Nuno Sa <nuno.sa@xxxxxxxxxx> > v2 changes: > - Removed dynamic allocation of spi xfer/msg > - Moved spi message optimization to probe function > - Dropped buffer pre/post callbacks > > drivers/iio/adc/ad7380.c | 36 ++++++++++++++++++++++++++++++------ > 1 file changed, 30 insertions(+), 6 deletions(-) > > diff --git a/drivers/iio/adc/ad7380.c b/drivers/iio/adc/ad7380.c > index abd746aef868..6b3fd20c8f1f 100644 > --- a/drivers/iio/adc/ad7380.c > +++ b/drivers/iio/adc/ad7380.c > @@ -133,6 +133,9 @@ struct ad7380_state { > struct spi_device *spi; > struct regulator *vref; > struct regmap *regmap; > + /* xfer and msg for buffer reads */ > + struct spi_transfer xfer; > + struct spi_message msg; > /* > * DMA (thus cache coherency maintenance) requires the > * transfer buffers to live in their own cache lines. > @@ -236,14 +239,9 @@ static irqreturn_t ad7380_trigger_handler(int irq, void *p) > struct iio_poll_func *pf = p; > struct iio_dev *indio_dev = pf->indio_dev; > struct ad7380_state *st = iio_priv(indio_dev); > - struct spi_transfer xfer = { > - .bits_per_word = st->chip_info->channels[0].scan_type.realbits, > - .len = 4, > - .rx_buf = st->scan_data.raw, > - }; > int ret; > > - ret = spi_sync_transfer(st->spi, &xfer, 1); > + ret = spi_sync(st->spi, &st->msg); > if (ret) > goto out; > > @@ -335,6 +333,28 @@ static const struct iio_info ad7380_info = { > .debugfs_reg_access = &ad7380_debugfs_reg_access, > }; > > +static void ad7380_unoptimize_spi_msg(void *msg) > +{ > + spi_unoptimize_message(msg); > +} > + > +static int devm_ad7380_setup_spi_msg(struct device *dev, struct ad7380_state *st) > +{ > + int ret; > + > + st->xfer.bits_per_word = st->chip_info->channels[0].scan_type.realbits; > + st->xfer.len = 4; > + st->xfer.rx_buf = st->scan_data.raw; > + > + spi_message_init_with_transfers(&st->msg, &st->xfer, 1); > + > + ret = spi_optimize_message(st->spi, &st->msg); > + if (ret) > + return dev_err_probe(dev, ret, "failed to optimize message\n"); > + > + return devm_add_action_or_reset(dev, ad7380_unoptimize_spi_msg, &st->msg); > +} > + > static int ad7380_init(struct ad7380_state *st) > { > int ret; > @@ -411,6 +431,10 @@ static int ad7380_probe(struct spi_device *spi) > return dev_err_probe(&spi->dev, PTR_ERR(st->regmap), > "failed to allocate register map\n"); > > + ret = devm_ad7380_setup_spi_msg(&spi->dev, st); > + if (ret) > + return ret; > + > indio_dev->channels = st->chip_info->channels; > indio_dev->num_channels = st->chip_info->num_channels; > indio_dev->name = st->chip_info->name; >