[U-Boot] [PATCH RESEND-WITH-JUSTIFICATION] spi: soft_spi: Support NULL din/dout buffers

Jagan Teki jagannadh.teki at gmail.com
Thu Apr 10 20:54:20 CEST 2014


On Thu, Apr 10, 2014 at 9:49 PM, Andrew Ruder
<andrew.ruder at elecsyscorp.com> wrote:
> This mirrors the conventions used in other SPI drivers (kirkwood,
> davinci, atmel, et al) where the din/dout buffer can be NULL when the
> received/transmitted data isn't important.  This reduces the need for
> allocating additional buffers when write-only/read-only functionality is
> needed.
>
> In the din == NULL case, the received data is simply not stored.  In the
> dout == NULL case, zeroes are transmitted.
>
> Signed-off-by: Andrew Ruder <andrew.ruder at elecsyscorp.com>
> Cc: Jean-Christophe PLAGNIOL-VILLARD <plagnioj at jcrosoft.com>
> Cc: Jagan Teki <jagannadh.teki at gmail.com>
> ---
> So going through and cleaning up some of my trees and determining which
> patches have not been taken.  A little more justification for this
> patch - I've gone through all of the current SPI implementations and
> have determined what (if any) support the driver has for half duplex
> operation by giving NULL for one of the two buffers (din/dout).  This
> greatly reduces the need for temporary buffers for writing or reading
> large amounts of half-duplex data to devices over SPI.  Here's the list:
>
> altera_spi.c          - SUPPORTS NULL din or dout
> andes_spi.c           - REQUIRES NULL din or dout
> armada100_spi.c       - SUPPORTS NULL din or dout
> atmel_spi.c           - SUPPORTS NULL din or dout
> bfin_spi6xx.c         - SUPPORTS NULL din or dout
> bfin_spi.c            - SUPPORTS NULL din or dout
> cf_qspi.c             - SUPPORTS NULL din or dout
> cf_spi.c              - SUPPORTS NULL din or dout
> davinci_spi.c         - SUPPORTS NULL din or dout
> exynos_spi.c          - SUPPORTS NULL din or dout
> fdt_spi.c-tegra20_sf  - SUPPORTS NULL din or dout
> fdt_spi.c-tegra20_sl  - SUPPORTS NULL din or dout
> fdt_spi.c-tegra114    - SUPPORTS NULL din or dout
> fsl_espi.c            - SUPPORTS NULL din (NOT dout)
> ftssp010_spi.c        - SUPPORTS NULL din or dout
> ich.c                 - SUPPORTS NULL din or dout
> kirkwood_spi.c        - SUPPORTS NULL din or dout
> mpc52xx_spi.c         - NO SUPPORT
> mpc8xxx_spi.c         - NO SUPPORT
> mxc_spi.c             - NO SUPPORT
> mxs_spi.c             - REQUIRES NULL din or dout
> oc_tiny_spi.c         - SUPPORTS NULL din or dout
> omap3_spi.c           - SUPPORTS NULL din or dout
> sandbox_spi.c         - SUPPORTS NULL din or dout
> sh_qspi.c             - SUPPORTS NULL din or dout
> sh_spi.c              - SUPPORTS NULL din or dout
> soft_spi.c            - NO SUPPORT
> ti_qspi.c             - SUPPORTS NULL din or dout
> xilinx_spi.c          - SUPPORTS NULL din or dout
> zynq_spi.c            - SUPPORTS NULL din or dout
>
> Furthermore, this would not affect any board already using temporary
> buffers and it would continue to work as usual.  The *only* obscure
> corner case that this will not work is if NULL (0x0) is a valid buffer
> address in your system and you are transferring SPI to/from it.  This
> seems very unlikely and would probably break in other ways from library
> functions that check their arguments.

At-least from zynq_spi.c case - I wouldn't find that obscure case as you pointed
and even with dout NULL which is status poll from (sf_ops.c).

Let me come back again and will show my results for zynq_spi.c

It would be great if you mentioned issue scenario for status poll case
drivers/mtd/spi/sf_ops.c:               ret = spi_xfer(spi, 8, NULL,
&status, 0);

>
>  drivers/spi/soft_spi.c | 18 +++++++++++++-----
>  1 file changed, 13 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/spi/soft_spi.c b/drivers/spi/soft_spi.c
> index 5d22351..5fdd091 100644
> --- a/drivers/spi/soft_spi.c
> +++ b/drivers/spi/soft_spi.c
> @@ -137,9 +137,15 @@ int  spi_xfer(struct spi_slave *slave, unsigned int bitlen,
>                  * Check if it is time to work on a new byte.
>                  */
>                 if((j % 8) == 0) {
> -                       tmpdout = *txd++;
> +                       if (txd) {
> +                               tmpdout = *txd++;
> +                       } else {
> +                               tmpdout = 0;
> +                       }
>                         if(j != 0) {
> -                               *rxd++ = tmpdin;
> +                               if (rxd) {
> +                                       *rxd++ = tmpdin;
> +                               }
>                         }
>                         tmpdin  = 0;
>                 }
> @@ -164,9 +170,11 @@ int  spi_xfer(struct spi_slave *slave, unsigned int bitlen,
>          * bits over to left-justify them.  Then store the last byte
>          * read in.
>          */
> -       if((bitlen % 8) != 0)
> -               tmpdin <<= 8 - (bitlen % 8);
> -       *rxd++ = tmpdin;
> +       if (rxd) {
> +               if((bitlen % 8) != 0)
> +                       tmpdin <<= 8 - (bitlen % 8);
> +               *rxd++ = tmpdin;
> +       }
>
>         if (flags & SPI_XFER_END)
>                 spi_cs_deactivate(slave);
> --
> 1.9.0.rc3.12.gbc97e2d
>

thanks!
-- 
Jagan.


More information about the U-Boot mailing list