spi: imx: correct wml as the last sg length
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>
This commit is contained in:
parent
987a2dfe3f
commit
5ba5a37306
|
@ -217,7 +217,6 @@ 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;
|
||||
|
@ -225,14 +224,6 @@ static bool spi_imx_can_dma(struct spi_master *master, struct spi_device *spi,
|
|||
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;
|
||||
|
@ -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 |
|
||||
|
@ -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);
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in New Issue