Just a hack. Someone probably has an idea about how this should be done. Signed-off-by: Noralf Trønnes <noralf@xxxxxxxxxxx> --- drivers/spi/spi.c | 24 +++++++++++++++++------- include/linux/spi/spi.h | 4 ++++ 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 838783c..b2958be 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -808,23 +808,28 @@ static int __spi_map_msg(struct spi_master *master, struct spi_message *msg) if (!master->can_dma(master, msg->spi, xfer)) continue; - if (xfer->tx_buf != NULL) { + if (xfer->tx_buf != NULL && !xfer->tx_sg.nents) { ret = spi_map_buf(master, tx_dev, &xfer->tx_sg, (void *)xfer->tx_buf, xfer->len, DMA_TO_DEVICE); if (ret != 0) return ret; + + xfer->tx_sg_core_mapped = true; } - if (xfer->rx_buf != NULL) { + if (xfer->rx_buf != NULL && !xfer->rx_sg.nents) { ret = spi_map_buf(master, rx_dev, &xfer->rx_sg, xfer->rx_buf, xfer->len, DMA_FROM_DEVICE); if (ret != 0) { spi_unmap_buf(master, tx_dev, &xfer->tx_sg, DMA_TO_DEVICE); + xfer->tx_sg_core_mapped = false; return ret; } + + xfer->rx_sg_core_mapped = true; } } @@ -852,11 +857,16 @@ static int __spi_unmap_msg(struct spi_master *master, struct spi_message *msg) rx_dev = &master->dev; list_for_each_entry(xfer, &msg->transfers, transfer_list) { - if (!master->can_dma(master, msg->spi, xfer)) - continue; - - spi_unmap_buf(master, rx_dev, &xfer->rx_sg, DMA_FROM_DEVICE); - spi_unmap_buf(master, tx_dev, &xfer->tx_sg, DMA_TO_DEVICE); + if (xfer->rx_sg_core_mapped) { + spi_unmap_buf(master, rx_dev, &xfer->rx_sg, + DMA_FROM_DEVICE); + xfer->rx_sg.nents = 0; + } + if (xfer->tx_sg_core_mapped) { + spi_unmap_buf(master, tx_dev, &xfer->tx_sg, + DMA_TO_DEVICE); + xfer->tx_sg.nents = 0; + } } return 0; diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index 4b743ac..f27fda6 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h @@ -682,6 +682,8 @@ extern void spi_res_release(struct spi_master *master, * @transfer_list: transfers are sequenced through @spi_message.transfers * @tx_sg: Scatterlist for transmit, currently not for client use * @rx_sg: Scatterlist for receive, currently not for client use + * @tx_sg_core_mapped: Scatterlist has been mapped by spi core + * @rx_sg_core_mapped: Scatterlist has been mapped by spi core * * SPI transfers always write the same number of bytes as they read. * Protocol drivers should always provide @rx_buf and/or @tx_buf. @@ -751,6 +753,8 @@ struct spi_transfer { dma_addr_t rx_dma; struct sg_table tx_sg; struct sg_table rx_sg; + bool tx_sg_core_mapped; + bool rx_sg_core_mapped; unsigned cs_change:1; unsigned tx_nbits:3; -- 2.10.2 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/dri-devel