spi/s3c64xx: Split wait_for_xfer() into PIO and DMA versions

There is no meaningful code sharing between the PIO and DMA variants
(just the timeout calculation) so in order to make the code easier to
work with split the two cases.

Looking at the code it is not clear how the PIO version works for large
transmits, greater than FIFO size is only handled for RX.

Signed-off-by: Mark Brown <broonie@linaro.org>
This commit is contained in:
Mark Brown 2014-01-24 20:05:43 +00:00
parent 4ddc86005b
commit 3700c6eb1e

View File

@ -576,30 +576,20 @@ static u32 s3c64xx_spi_wait_for_timeout(struct s3c64xx_spi_driver_data *sdd,
return RX_FIFO_LVL(status, sdd);
}
static int wait_for_xfer(struct s3c64xx_spi_driver_data *sdd,
struct spi_transfer *xfer, int dma_mode)
static int wait_for_dma(struct s3c64xx_spi_driver_data *sdd,
struct spi_transfer *xfer)
{
void __iomem *regs = sdd->regs;
unsigned long val;
u32 status;
int ms;
/* millisecs to xfer 'len' bytes @ 'cur_speed' */
ms = xfer->len * 8 * 1000 / sdd->cur_speed;
ms += 10; /* some tolerance */
if (dma_mode) {
val = msecs_to_jiffies(ms) + 10;
val = wait_for_completion_timeout(&sdd->xfer_completion, val);
} else {
u32 status;
val = msecs_to_loops(ms);
do {
status = readl(regs + S3C64XX_SPI_STATUS);
} while (RX_FIFO_LVL(status, sdd) < xfer->len && --val);
}
if (dma_mode) {
u32 status;
/*
* If the previous xfer was completed within timeout, then
@ -625,10 +615,30 @@ static int wait_for_xfer(struct s3c64xx_spi_driver_data *sdd,
/* If timed out while checking rx/tx status return error */
if (!val)
return -EIO;
} else {
return 0;
}
static int wait_for_pio(struct s3c64xx_spi_driver_data *sdd,
struct spi_transfer *xfer)
{
void __iomem *regs = sdd->regs;
unsigned long val;
u32 status;
int loops;
u32 cpy_len;
u8 *buf;
int ms;
/* millisecs to xfer 'len' bytes @ 'cur_speed' */
ms = xfer->len * 8 * 1000 / sdd->cur_speed;
ms += 10; /* some tolerance */
val = msecs_to_loops(ms);
do {
status = readl(regs + S3C64XX_SPI_STATUS);
} while (RX_FIFO_LVL(status, sdd) < xfer->len && --val);
/* If it was only Tx */
if (!xfer->rx_buf) {
@ -669,7 +679,6 @@ static int wait_for_xfer(struct s3c64xx_spi_driver_data *sdd,
buf = buf + cpy_len;
} while (loops--);
sdd->state &= ~RXBUSY;
}
return 0;
}
@ -902,7 +911,10 @@ static int s3c64xx_spi_transfer_one(struct spi_master *master,
spin_unlock_irqrestore(&sdd->lock, flags);
status = wait_for_xfer(sdd, xfer, use_dma);
if (use_dma)
status = wait_for_dma(sdd, xfer);
else
status = wait_for_pio(sdd, xfer);
if (status) {
dev_err(&spi->dev, "I/O Error: rx-%d tx-%d res:rx-%c tx-%c len-%d\n",