Skip to content

Commit

Permalink
spi: imx: correct wml as the last sg length
Browse files Browse the repository at this point in the history
Correct wml as the last rx sg length instead of the whole transfer
length. Otherwise, mtd_stresstest will be failed as below:

insmod mtd_stresstest.ko dev=0
=================================================
mtd_stresstest: MTD device: 0
mtd_stresstest: not NAND flash, assume page size is 512 bytes.
mtd_stresstest: MTD device size 4194304, eraseblock size 65536, page size 512, count of eraseblocks 64, pa0
mtd_stresstest: doing operations
mtd_stresstest: 0 operations done
mtd_test: mtd_read from 1ff532, size 880
mtd_test: mtd_read from 20c267, size 64998
spi_master spi0: I/O Error in DMA RX
m25p80 spi0.0: SPI transfer failed: -110
spi_master spi0: failed to transfer one message from queue
mtd_test: error: read failed at 0x20c267
mtd_stresstest: error -110 occurred
=================================================
insmod: ERROR: could not insert module mtd_stresstest.ko: Connection timed out

Signed-off-by: Robin Gong <yibin.gong@nxp.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
  • Loading branch information
Robin Gong authored and Mark Brown committed Oct 12, 2018
1 parent 987a2df commit 5ba5a37
Showing 1 changed file with 19 additions and 10 deletions.
29 changes: 19 additions & 10 deletions drivers/spi/spi-imx.c
Original file line number Diff line number Diff line change
Expand Up @@ -217,22 +217,13 @@ static bool spi_imx_can_dma(struct spi_master *master, struct spi_device *spi,
struct spi_transfer *transfer)
{
struct spi_imx_data *spi_imx = spi_master_get_devdata(master);
unsigned int bytes_per_word, i;

if (!master->dma_rx)
return false;

if (spi_imx->slave_mode)
return false;

bytes_per_word = spi_imx_bytes_per_word(transfer->bits_per_word);

for (i = spi_imx->devtype_data->fifo_size / 2; i > 0; i--) {
if (!(transfer->len % (i * bytes_per_word)))
break;
}

spi_imx->wml = i;
spi_imx->dynamic_burst = 0;

return true;
Expand Down Expand Up @@ -594,7 +585,7 @@ static void mx51_setup_wml(struct spi_imx_data *spi_imx)
* and enable DMA request.
*/

writel(MX51_ECSPI_DMA_RX_WML(spi_imx->wml) |
writel(MX51_ECSPI_DMA_RX_WML(spi_imx->wml - 1) |
MX51_ECSPI_DMA_TX_WML(spi_imx->wml) |
MX51_ECSPI_DMA_RXT_WML(spi_imx->wml) |
MX51_ECSPI_DMA_TEDEN | MX51_ECSPI_DMA_RXDEN |
Expand Down Expand Up @@ -1287,12 +1278,30 @@ static int spi_imx_dma_transfer(struct spi_imx_data *spi_imx,
unsigned long timeout;
struct spi_master *master = spi_imx->bitbang.master;
struct sg_table *tx = &transfer->tx_sg, *rx = &transfer->rx_sg;
struct scatterlist *last_sg = sg_last(rx->sgl, rx->nents);
unsigned int bytes_per_word, i;
int ret;

/* Get the right burst length from the last sg to ensure no tail data */
bytes_per_word = spi_imx_bytes_per_word(transfer->bits_per_word);
for (i = spi_imx->devtype_data->fifo_size / 2; i > 0; i--) {
if (!(sg_dma_len(last_sg) % (i * bytes_per_word)))
break;
}
/* Use 1 as wml in case no available burst length got */
if (i == 0)
i = 1;

spi_imx->wml = i;

ret = spi_imx_dma_configure(master);
if (ret)
return ret;

if (!spi_imx->devtype_data->setup_wml) {
dev_err(spi_imx->dev, "No setup_wml()?\n");
return -EINVAL;
}
spi_imx->devtype_data->setup_wml(spi_imx);

/*
Expand Down

0 comments on commit 5ba5a37

Please sign in to comment.