All of lore.kernel.org
 help / color / mirror / Atom feed
From: Boris Brezillon <boris.brezillon@collabora.com>
To: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
Cc: Richard Weinberger <richard@nod.at>,
	Miquel Raynal <miquel.raynal@bootlin.com>,
	linux-mtd@lists.infradead.org,
	Vignesh Raghavendra <vigneshr@ti.com>,
	Tudor Ambarus <tudor.ambarus@microchip.com>
Subject: Re: [PATCH v4 1/2] mtd: spi-nor: split spi_nor_spimem_xfer_data()
Date: Tue, 28 Jan 2020 07:50:17 +0100	[thread overview]
Message-ID: <20200128075017.4014e1f5@collabora.com> (raw)
In-Reply-To: <002acfc3-39d7-68e7-aa00-fbb449c3bc71@cogentembedded.com>

On Mon, 27 Jan 2020 23:28:05 +0300
Sergei Shtylyov <sergei.shtylyov@cogentembedded.com> wrote:

> spi_nor_spimem_xfer_data() being a helper function for the data reads/
> writes contains 3 fragments that depend on the data direction; and I'm
> going to add another one to call the SPI dirmap API...
> I think this function should be split so that the common fragments are
> put into 2 functions, spi_nor_spimem_bounce() and spi_nor_spimem_exec_op()
> called from spi_nor_spimem_{read|write}_data(), and the data direction
> dependent bits moved back into those read/write functions -- that way we
> would be able to avoid *goto*s otherwise needed in the next patch adding
> the  SPI dirmap support...
> 
> Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>

Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>

> 
> ---
> Changes in version 4:
> - new patch.
> 
>  drivers/mtd/spi-nor/spi-nor.c |   91 +++++++++++++++++++++++-------------------
>  1 file changed, 51 insertions(+), 40 deletions(-)
> 
> Index: linux/drivers/mtd/spi-nor/spi-nor.c
> ===================================================================
> --- linux.orig/drivers/mtd/spi-nor/spi-nor.c
> +++ linux/drivers/mtd/spi-nor/spi-nor.c
> @@ -246,55 +246,45 @@ struct flash_info {
>  #define JEDEC_MFR(info)	((info)->id[0])
>  
>  /**
> - * spi_nor_spimem_xfer_data() - helper function to read/write data to
> - *                              flash's memory region
> + * spi_nor_spimem_bounce() - check if a bounce buffer is needed for the data
> + *                           transfer
>   * @nor:        pointer to 'struct spi_nor'
>   * @op:         pointer to 'struct spi_mem_op' template for transfer
>   *
> - * Return: number of bytes transferred on success, -errno otherwise
> + * If we have to use the bounce buffer, the data field in @op will be updated.
> + *
> + * Return: true if the bounce buffer is needed, false if not
>   */
> -static ssize_t spi_nor_spimem_xfer_data(struct spi_nor *nor,
> -					struct spi_mem_op *op)
> +static bool spi_nor_spimem_bounce(struct spi_nor *nor, struct spi_mem_op *op)
>  {
> -	bool usebouncebuf = false;
> -	void *rdbuf = NULL;
> -	const void *buf;
> -	int ret;
> -
> -	if (op->data.dir == SPI_MEM_DATA_IN)
> -		buf = op->data.buf.in;
> -	else
> -		buf = op->data.buf.out;
> -
> -	if (object_is_on_stack(buf) || !virt_addr_valid(buf))
> -		usebouncebuf = true;
> -
> -	if (usebouncebuf) {
> +	/* op->data.buf.in occupies the same memory as op->data.buf.out */
> +	if (object_is_on_stack(op->data.buf.in) ||
> +	    !virt_addr_valid(op->data.buf.in)) {
>  		if (op->data.nbytes > nor->bouncebuf_size)
>  			op->data.nbytes = nor->bouncebuf_size;
> -
> -		if (op->data.dir == SPI_MEM_DATA_IN) {
> -			rdbuf = op->data.buf.in;
> -			op->data.buf.in = nor->bouncebuf;
> -		} else {
> -			op->data.buf.out = nor->bouncebuf;
> -			memcpy(nor->bouncebuf, buf,
> -			       op->data.nbytes);
> -		}
> +		op->data.buf.in = nor->bouncebuf;
> +		return true;
>  	}
>  
> -	ret = spi_mem_adjust_op_size(nor->spimem, op);
> -	if (ret)
> -		return ret;
> -
> -	ret = spi_mem_exec_op(nor->spimem, op);
> -	if (ret)
> -		return ret;
> +	return false;
> +}
> +
> +/**
> + * spi_nor_spimem_exec_op() - execute a memory operation
> + * @nor:        pointer to 'struct spi_nor'
> + * @op:         pointer to 'struct spi_mem_op' template for transfer
> + *
> + * Return: 0 on success, -error otherwise.
> + */
> +static int spi_nor_spimem_exec_op(struct spi_nor *nor, struct spi_mem_op *op)
> +{
> +	int error;
>  
> -	if (usebouncebuf && op->data.dir == SPI_MEM_DATA_IN)
> -		memcpy(rdbuf, nor->bouncebuf, op->data.nbytes);
> +	error = spi_mem_adjust_op_size(nor->spimem, op);
> +	if (error)
> +		return error;
>  
> -	return op->data.nbytes;
> +	return spi_mem_exec_op(nor->spimem, op);
>  }
>  
>  /**
> @@ -315,6 +305,8 @@ static ssize_t spi_nor_spimem_read_data(
>  			   SPI_MEM_OP_ADDR(nor->addr_width, from, 1),
>  			   SPI_MEM_OP_DUMMY(nor->read_dummy, 1),
>  			   SPI_MEM_OP_DATA_IN(len, buf, 1));
> +	bool usebouncebuf;
> +	int error;
>  
>  	/* get transfer protocols. */
>  	op.cmd.buswidth = spi_nor_get_protocol_inst_nbits(nor->read_proto);
> @@ -325,7 +317,16 @@ static ssize_t spi_nor_spimem_read_data(
>  	/* convert the dummy cycles to the number of bytes */
>  	op.dummy.nbytes = (nor->read_dummy * op.dummy.buswidth) / 8;
>  
> -	return spi_nor_spimem_xfer_data(nor, &op);
> +	usebouncebuf = spi_nor_spimem_bounce(nor, &op);
> +
> +	error = spi_nor_spimem_exec_op(nor, &op);
> +	if (error)
> +		return error;
> +
> +	if (usebouncebuf)
> +		memcpy(buf, op.data.buf.in, op.data.nbytes);
> +
> +	return op.data.nbytes;
>  }
>  
>  /**
> @@ -364,6 +365,8 @@ static ssize_t spi_nor_spimem_write_data
>  			   SPI_MEM_OP_ADDR(nor->addr_width, to, 1),
>  			   SPI_MEM_OP_NO_DUMMY,
>  			   SPI_MEM_OP_DATA_OUT(len, buf, 1));
> +	bool usebouncebuf;
> +	int error;
>  
>  	op.cmd.buswidth = spi_nor_get_protocol_inst_nbits(nor->write_proto);
>  	op.addr.buswidth = spi_nor_get_protocol_addr_nbits(nor->write_proto);
> @@ -372,7 +375,15 @@ static ssize_t spi_nor_spimem_write_data
>  	if (nor->program_opcode == SPINOR_OP_AAI_WP && nor->sst_write_second)
>  		op.addr.nbytes = 0;
>  
> -	return spi_nor_spimem_xfer_data(nor, &op);
> +	usebouncebuf = spi_nor_spimem_bounce(nor, &op);
> +	if (usebouncebuf)
> +		memcpy(nor->bouncebuf, buf, op.data.nbytes);
> +
> +	error = spi_nor_spimem_exec_op(nor, &op);
> +	if (error)
> +		return error;
> +
> +	return op.data.nbytes;
>  }
>  
>  /**
> 
> ______________________________________________________
> Linux MTD discussion mailing list
> http://lists.infradead.org/mailman/listinfo/linux-mtd/


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

  reply	other threads:[~2020-01-28  6:50 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-01-27 20:23 [PATCH v4 0/2] mtd: spi-nor: use spi-mem dirmap API Sergei Shtylyov
2020-01-27 20:28 ` [PATCH v4 1/2] mtd: spi-nor: split spi_nor_spimem_xfer_data() Sergei Shtylyov
2020-01-28  6:50   ` Boris Brezillon [this message]
2020-02-16 22:40   ` Tudor.Ambarus
2020-02-17 17:47     ` Sergei Shtylyov
2020-01-27 20:29 ` [PATCH v4 2/2] mtd: spi-nor: use spi-mem dirmap API Sergei Shtylyov
2020-02-16 23:03   ` Tudor.Ambarus
2020-02-17 18:43     ` Sergei Shtylyov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200128075017.4014e1f5@collabora.com \
    --to=boris.brezillon@collabora.com \
    --cc=linux-mtd@lists.infradead.org \
    --cc=miquel.raynal@bootlin.com \
    --cc=richard@nod.at \
    --cc=sergei.shtylyov@cogentembedded.com \
    --cc=tudor.ambarus@microchip.com \
    --cc=vigneshr@ti.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.