On 11/15/2017 01:40 PM, Marc Kleine-Budde wrote:
> mcp251x_spi_trans() is called with len=3,
> priv->spi_tx_buf and priv->spi_rx_buf point to previously allocared memory
> 
> priv->spi_tx_buf has been filled before calling mcp251x_spi_trans().

> #define OCTEON_SPI_MAX_BYTES 9

> static int octeon_spi_do_transfer(struct octeon_spi *p,
>                                 struct spi_message *msg,
>                                 struct spi_transfer *xfer,
>                                 bool last_xfer)
> {
>       struct spi_device *spi = msg->spi;
>       union cvmx_mpi_cfg mpi_cfg;
>       union cvmx_mpi_tx mpi_tx;
>       unsigned int clkdiv;
>       int mode;
>       bool cpha, cpol;
>       const u8 *tx_buf;
>       u8 *rx_buf;
>       int len;
>       int i;
> 
>       mode = spi->mode;
>       cpha = mode & SPI_CPHA;
>       cpol = mode & SPI_CPOL;
> 
>       clkdiv = p->sys_freq / (2 * xfer->speed_hz);
> 
>       mpi_cfg.u64 = 0;
> 
>       mpi_cfg.s.clkdiv = clkdiv;
>       mpi_cfg.s.cshi = (mode & SPI_CS_HIGH) ? 1 : 0;
>       mpi_cfg.s.lsbfirst = (mode & SPI_LSB_FIRST) ? 1 : 0;
>       mpi_cfg.s.wireor = (mode & SPI_3WIRE) ? 1 : 0;
>       mpi_cfg.s.idlelo = cpha != cpol;
>       mpi_cfg.s.cslate = cpha ? 1 : 0;
>       mpi_cfg.s.enable = 1;
> 
>       if (spi->chip_select < 4)
>               p->cs_enax |= 1ull << (12 + spi->chip_select);
>       mpi_cfg.u64 |= p->cs_enax;
> 
>       if (mpi_cfg.u64 != p->last_cfg) {
>               p->last_cfg = mpi_cfg.u64;
>               writeq(mpi_cfg.u64, p->register_base + OCTEON_SPI_CFG(p));
>       }
>       tx_buf = xfer->tx_buf;
>       rx_buf = xfer->rx_buf;
>       len = xfer->len;
>       while (len > OCTEON_SPI_MAX_BYTES) {
>               for (i = 0; i < OCTEON_SPI_MAX_BYTES; i++) {
>                       u8 d;
>                       if (tx_buf)
>                               d = *tx_buf++;
>                       else
>                               d = 0;
>                       writeq(d, p->register_base + OCTEON_SPI_DAT0(p) + (8 * 
> i));
>               }
>               mpi_tx.u64 = 0;
>               mpi_tx.s.csid = spi->chip_select;
>               mpi_tx.s.leavecs = 1;
>               mpi_tx.s.txnum = tx_buf ? OCTEON_SPI_MAX_BYTES : 0;

This looks fishy, OCTEON_SPI_MAX_BYTES is 9....

>               mpi_tx.s.totnum = OCTEON_SPI_MAX_BYTES;
>               writeq(mpi_tx.u64, p->register_base + OCTEON_SPI_TX(p));
> 
>               octeon_spi_wait_ready(p);
>               if (rx_buf)
>                       for (i = 0; i < OCTEON_SPI_MAX_BYTES; i++) {
>                               u64 v = readq(p->register_base + 
> OCTEON_SPI_DAT0(p) + (8 * i));
>                               *rx_buf++ = (u8)v;
>                       }
>               len -= OCTEON_SPI_MAX_BYTES;
>       }
> 
>       for (i = 0; i < len; i++) {
>               u8 d;
>               if (tx_buf)
>                       d = *tx_buf++;
>               else
>                       d = 0;
>               writeq(d, p->register_base + OCTEON_SPI_DAT0(p) + (8 * i));
>       }
> 
>       mpi_tx.u64 = 0;
>       mpi_tx.s.csid = spi->chip_select;
>       if (last_xfer)
>               mpi_tx.s.leavecs = xfer->cs_change;
>       else
>               mpi_tx.s.leavecs = !xfer->cs_change;
>       mpi_tx.s.txnum = tx_buf ? len : 0;
>       mpi_tx.s.totnum = len;
>       writeq(mpi_tx.u64, p->register_base + OCTEON_SPI_TX(p));
> 
>       octeon_spi_wait_ready(p);
>       if (rx_buf)
>               for (i = 0; i < len; i++) {
>                       u64 v = readq(p->register_base + OCTEON_SPI_DAT0(p) + 
> (8 * i));
>                       *rx_buf++ = (u8)v;
>               }

Personally I'd fold this into the while loop, as there's quite some code
duplication. Of course your have to improve the "if (last_xfer)" a bit.

> 
>       if (xfer->delay_usecs)
>               udelay(xfer->delay_usecs);
> 
>       return xfer->len;
> }

Marc

-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |

Attachment: signature.asc
Description: OpenPGP digital signature

Reply via email to