s3c64xx_spi_transfer_one() makes sure that for PIO the xfer->len is always smaller than the fifo size. Clean s3c64xx_wait_for_pio() and emphasize that it works with lengths smaller than the fifo size. Signed-off-by: Tudor Ambarus <tudor.ambarus@xxxxxxxxxx> --- drivers/spi/spi-s3c64xx.c | 75 +++++++++------------------------------ 1 file changed, 17 insertions(+), 58 deletions(-) diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c index fd0e62ff8968..f5474f3b3920 100644 --- a/drivers/spi/spi-s3c64xx.c +++ b/drivers/spi/spi-s3c64xx.c @@ -484,26 +484,6 @@ static int s3c64xx_enable_datapath(struct s3c64xx_spi_driver_data *sdd, return 0; } -static u32 s3c64xx_spi_wait_for_timeout(struct s3c64xx_spi_driver_data *sdd, - int timeout_ms) -{ - void __iomem *regs = sdd->regs; - unsigned long val = 1; - u32 status; - u32 max_fifo = FIFO_DEPTH(sdd); - - if (timeout_ms) - val = msecs_to_loops(timeout_ms); - - do { - status = readl(regs + S3C64XX_SPI_STATUS); - } while (FIELD_GET(S3C64XX_SPI_ST_RX_FIFO_LVL, status) < max_fifo && - --val); - - /* return the actual received data length */ - return FIELD_GET(S3C64XX_SPI_ST_RX_FIFO_LVL, status); -} - static int s3c64xx_wait_for_dma(struct s3c64xx_spi_driver_data *sdd, struct spi_transfer *xfer) { @@ -547,13 +527,11 @@ static int s3c64xx_wait_for_pio(struct s3c64xx_spi_driver_data *sdd, struct spi_transfer *xfer, bool use_irq) { void __iomem *regs = sdd->regs; + u8 *buf = xfer->rx_buf; + unsigned long time_us; unsigned long val; - u32 status; - int loops; - u32 cpy_len; - u8 *buf; + u32 status, len; int ms; - unsigned long time_us; /* microsecs to xfer 'len' bytes @ 'cur_speed' */ time_us = (xfer->len * 8 * 1000 * 1000) / sdd->cur_speed; @@ -576,48 +554,29 @@ static int s3c64xx_wait_for_pio(struct s3c64xx_spi_driver_data *sdd, status = readl(regs + S3C64XX_SPI_STATUS); } while (FIELD_GET(S3C64XX_SPI_ST_RX_FIFO_LVL, status) < xfer->len && --val); - if (!val) return -EIO; /* If it was only Tx */ - if (!xfer->rx_buf) { + if (!buf) { sdd->state &= ~TXBUSY; return 0; } - /* - * If the receive length is bigger than the controller fifo - * size, calculate the loops and read the fifo as many times. - * loops = length / max fifo size (calculated by using the - * fifo mask). - * For any size less than the fifo size the below code is - * executed atleast once. - */ - loops = xfer->len / FIFO_DEPTH(sdd); - buf = xfer->rx_buf; - do { - /* wait for data to be received in the fifo */ - cpy_len = s3c64xx_spi_wait_for_timeout(sdd, - (loops ? ms : 0)); - - switch (sdd->cur_bpw) { - case 32: - ioread32_rep(regs + S3C64XX_SPI_RX_DATA, - buf, cpy_len / 4); - break; - case 16: - ioread16_rep(regs + S3C64XX_SPI_RX_DATA, - buf, cpy_len / 2); - break; - default: - ioread8_rep(regs + S3C64XX_SPI_RX_DATA, - buf, cpy_len); - break; - } + len = FIELD_GET(S3C64XX_SPI_ST_RX_FIFO_LVL, status); + + switch (sdd->cur_bpw) { + case 32: + ioread32_rep(regs + S3C64XX_SPI_RX_DATA, buf, len / 4); + break; + case 16: + ioread16_rep(regs + S3C64XX_SPI_RX_DATA, buf, len / 2); + break; + default: + ioread8_rep(regs + S3C64XX_SPI_RX_DATA, buf, len); + break; + } - buf = buf + cpy_len; - } while (loops--); sdd->state &= ~RXBUSY; return 0; -- 2.43.0.429.g432eaa2c6b-goog