diff mbox series

[v2,5/5] iio: adc: ad7380: use spi_optimize_message()

Message ID 20240219-mainline-spi-precook-message-v2-5-4a762c6701b9@baylibre.com
State New
Headers show
Series spi: add support for pre-cooking messages | expand

Commit Message

David Lechner Feb. 19, 2024, 10:33 p.m. UTC
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@baylibre.com>
---

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(-)

Comments

Nuno Sá Feb. 20, 2024, 10:41 a.m. UTC | #1
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@baylibre.com>
> ---
> 

Reviewed-by: Nuno Sa <nuno.sa@analog.com>

> 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;
>
Jonathan Cameron Feb. 24, 2024, 4:57 p.m. UTC | #2
On Mon, 19 Feb 2024 16:33:22 -0600
David Lechner <dlechner@baylibre.com> 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@baylibre.com>
Looks good to me.

As this is the driver you asked me to drop earlier this cycle,
how do we plan to merge this series?

If Mark is fine taking 1-4 with the user following along that's
fine by me, if not I guess we are in immutable tree territory for
next cycle?

Jonathan
David Lechner Feb. 27, 2024, 4:36 p.m. UTC | #3
On Sat, Feb 24, 2024 at 10:57 AM Jonathan Cameron <jic23@kernel.org> wrote:
>
> On Mon, 19 Feb 2024 16:33:22 -0600
> David Lechner <dlechner@baylibre.com> 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@baylibre.com>
> Looks good to me.
>
> As this is the driver you asked me to drop earlier this cycle,
> how do we plan to merge this series?
>
> If Mark is fine taking 1-4 with the user following along that's
> fine by me, if not I guess we are in immutable tree territory for
> next cycle?

I've been out sick for a week so trying to get back up to speed here.
It looks like Mark has picked up the spi changes, so that part is
resolved. I'll work on getting the ad7380 driver resubmitted, then we
can come back to this patch after 6.9-rc1 (assuming the SPI changes
make it in to 3.9 of course).
diff mbox series

Patch

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;