On Wed, Nov 15, 2017 at 02:31:45PM +0100, Marc Kleine-Budde wrote:
> 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....

Because there are 9 registers in MPI_DAT(0..8).

> >             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.

I've not written that code, just split it for shared arm64 & mips usage
and avoided re-writing it completely on purpose :) If it turns out that
we need to change this code I might consider making changes like this.

Adding David who might know more about this driver.

--Jan

Reply via email to