The SPI message validation code in __spi_validate() is too restrictive on 3WIRE transfers: the core bitbanging code, for example, will gladly switch direction of the line inbetween transfers. Allow 3WIRE messages even if there is both TX and RX transfers in the message. Transfers with TX and RX at the same time will not work however (just one wire after all), so be sure to disallow those. Cc: Andrzej Hajda <a.hajda@xxxxxxxxxxx> Cc: Lorenzo Bianconi <lorenzo.bianconi@xxxxxxxxxx> Signed-off-by: Linus Walleij <linus.walleij@xxxxxxxxxx> --- drivers/spi/spi.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index ec395a6baf9c..f6f9314e9a18 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -2841,10 +2841,17 @@ static int __spi_validate(struct spi_device *spi, struct spi_message *message) list_for_each_entry(xfer, &message->transfers, transfer_list) { if (xfer->rx_buf && xfer->tx_buf) return -EINVAL; - if ((flags & SPI_CONTROLLER_NO_TX) && xfer->tx_buf) - return -EINVAL; - if ((flags & SPI_CONTROLLER_NO_RX) && xfer->rx_buf) - return -EINVAL; + /* + * 3WIRE can indeed do a write message followed by a + * read message, the direction of the line will be + * switched between the two messages. + */ + if (spi->mode & SPI_CONTROLLER_HALF_DUPLEX) { + if ((flags & SPI_CONTROLLER_NO_TX) && xfer->tx_buf) + return -EINVAL; + if ((flags & SPI_CONTROLLER_NO_RX) && xfer->rx_buf) + return -EINVAL; + } } } -- 2.17.1