Refactor the SPI transfer function to allow support for parallel IO. Use transfer_one_message() instead of the generic transfer_one() for the necessary HW control for the transfer. Signed-off-by: Birger Koblitz <mail@xxxxxxxxxxxxxxxxx> --- drivers/spi/spi-realtek-rtl.c | 84 ++++++++++++++++++++++------------- 1 file changed, 54 insertions(+), 30 deletions(-) diff --git a/drivers/spi/spi-realtek-rtl.c b/drivers/spi/spi-realtek-rtl.c index 25a90493bf6e..21c0dc16c8cc 100644 --- a/drivers/spi/spi-realtek-rtl.c +++ b/drivers/spi/spi-realtek-rtl.c @@ -140,42 +140,66 @@ static void set_mode(struct rtspi *rtspi, unsigned int mode) writel(value, REG(RTL_SPI_SFCSR)); } -static int transfer_one(struct spi_controller *ctrl, struct spi_device *spi, - struct spi_transfer *xfer) +static void raw_write(struct rtspi *rtspi, const void *tx_buf, int cnt) +{ + while (cnt >= 4) { + send4(rtspi, tx_buf); + tx_buf += 4; + cnt -= 4; + } + while (cnt) { + send1(rtspi, tx_buf); + tx_buf++; + cnt--; + } +} + +static void raw_read(struct rtspi *rtspi, void *rx_buf, int cnt) +{ + while (cnt >= 4) { + rcv4(rtspi, rx_buf); + rx_buf += 4; + cnt -= 4; + } + while (cnt) { + rcv1(rtspi, rx_buf); + rx_buf++; + cnt--; + } +} + +static int transfer_one_message(struct spi_controller *ctrl, struct spi_message *m) { struct rtspi *rtspi = spi_controller_get_devdata(ctrl); - void *rx_buf; - const void *tx_buf; + struct spi_device *spi = m->spi; + struct spi_transfer *xfer = NULL; + int status = 0; int cnt; - tx_buf = xfer->tx_buf; - rx_buf = xfer->rx_buf; - cnt = xfer->len; - if (tx_buf) { - while (cnt >= 4) { - send4(rtspi, tx_buf); - tx_buf += 4; - cnt -= 4; - } - while (cnt) { - send1(rtspi, tx_buf); - tx_buf++; - cnt--; - } - } else if (rx_buf) { - while (cnt >= 4) { - rcv4(rtspi, rx_buf); - rx_buf += 4; - cnt -= 4; - } - while (cnt) { - rcv1(rtspi, rx_buf); - rx_buf++; - cnt--; + wait_ready(rtspi); + + /* Assert CS */ + rt_set_cs(spi, false); + + m->actual_length = 0; + list_for_each_entry(xfer, &m->transfers, transfer_list) { + cnt = xfer->len; + if (xfer->rx_buf) { + set_mode(rtspi, xfer->rx_nbits); + raw_read(rtspi, xfer->rx_buf, cnt); + } else if (xfer->tx_buf) { + set_mode(rtspi, xfer->tx_nbits); + raw_write(rtspi, xfer->tx_buf, cnt); } + m->actual_length += xfer->len; } - spi_finalize_current_transfer(ctrl); + /* Wait until transfer finished and de-assert CS */ + wait_ready(rtspi); + rt_set_cs(spi, true); + + m->status = status; + spi_finalize_current_message(ctrl); return 0; } @@ -223,7 +247,7 @@ static int realtek_rtl_spi_probe(struct platform_device *pdev) if (rtspi->dev_flags & SPI_QUAD_SUPPORTED) ctrl->flags |= SPI_TX_QUAD | SPI_RX_QUAD; ctrl->set_cs = rt_set_cs; - ctrl->transfer_one = transfer_one; + ctrl->transfer_one_message = transfer_one_message; ctrl->num_chipselect = rtspi->dev_flags & SPI_CSMAX_3?4:2; rtspi->cs_all = RTL_SPI_SFCSR_CSB0 | RTL_SPI_SFCSR_CSB1; if (rtspi->dev_flags & SPI_CSMAX_3) -- 2.25.1