
Using read_poll logic.
Signed-off-by: Jon Lin jon.lin@rock-chips.com ---
drivers/spi/rockchip_sfc.c | 67 ++++++++++++++++++++------------------ 1 file changed, 35 insertions(+), 32 deletions(-)
diff --git a/drivers/spi/rockchip_sfc.c b/drivers/spi/rockchip_sfc.c index 2028b28e26..33c5344c70 100644 --- a/drivers/spi/rockchip_sfc.c +++ b/drivers/spi/rockchip_sfc.c @@ -286,33 +286,38 @@ err_init: return ret; }
-static inline int rockchip_sfc_get_fifo_level(struct rockchip_sfc *sfc, int wr) +static int rockchip_sfc_wait_txfifo_ready(struct rockchip_sfc *sfc, u32 timeout_us) { - u32 fsr = readl(sfc->regbase + SFC_FSR); - int level; + int ret = 0; + u32 status;
- if (wr) - level = (fsr & SFC_FSR_TXLV_MASK) >> SFC_FSR_TXLV_SHIFT; - else - level = (fsr & SFC_FSR_RXLV_MASK) >> SFC_FSR_RXLV_SHIFT; + ret = readl_poll_timeout(sfc->regbase + SFC_FSR, status, + status & SFC_FSR_TXLV_MASK, + timeout_us); + if (ret) { + dev_dbg(sfc->dev, "sfc wait tx fifo timeout\n"); + + ret = -ETIMEDOUT; + }
- return level; + return (status & SFC_FSR_TXLV_MASK) >> SFC_FSR_TXLV_SHIFT; }
-static int rockchip_sfc_wait_fifo_ready(struct rockchip_sfc *sfc, int wr, u32 timeout) +static int rockchip_sfc_wait_rxfifo_ready(struct rockchip_sfc *sfc, u32 timeout_us) { - unsigned long tbase = get_timer(0); - int level; + int ret = 0; + u32 status;
- while (!(level = rockchip_sfc_get_fifo_level(sfc, wr))) { - if (get_timer(tbase) > timeout) { - debug("%s fifo timeout\n", wr ? "write" : "read"); - return -ETIMEDOUT; - } - udelay(1); + ret = readl_poll_timeout(sfc->regbase + SFC_FSR, status, + status & SFC_FSR_RXLV_MASK, + timeout_us); + if (ret) { + dev_dbg(sfc->dev, "sfc wait rx fifo timeout\n"); + + ret = -ETIMEDOUT; }
- return level; + return (status & SFC_FSR_RXLV_MASK) >> SFC_FSR_RXLV_SHIFT; }
static void rockchip_sfc_adjust_op_work(struct spi_mem_op *op) @@ -430,7 +435,7 @@ static int rockchip_sfc_write_fifo(struct rockchip_sfc *sfc, const u8 *buf, int
dwords = len >> 2; while (dwords) { - tx_level = rockchip_sfc_wait_fifo_ready(sfc, SFC_CMD_DIR_WR, 1000); + tx_level = rockchip_sfc_wait_txfifo_ready(sfc, 1000); if (tx_level < 0) return tx_level; write_words = min_t(u32, tx_level, dwords); @@ -441,7 +446,7 @@ static int rockchip_sfc_write_fifo(struct rockchip_sfc *sfc, const u8 *buf, int
/* write the rest non word aligned bytes */ if (bytes) { - tx_level = rockchip_sfc_wait_fifo_ready(sfc, SFC_CMD_DIR_WR, 1000); + tx_level = rockchip_sfc_wait_txfifo_ready(sfc, 1000); if (tx_level < 0) return tx_level; memcpy(&tmp, buf, bytes); @@ -462,7 +467,7 @@ static int rockchip_sfc_read_fifo(struct rockchip_sfc *sfc, u8 *buf, int len) /* word aligned access only */ dwords = len >> 2; while (dwords) { - rx_level = rockchip_sfc_wait_fifo_ready(sfc, SFC_CMD_DIR_RD, 1000); + rx_level = rockchip_sfc_wait_rxfifo_ready(sfc, 1000); if (rx_level < 0) return rx_level; read_words = min_t(u32, rx_level, dwords); @@ -473,7 +478,7 @@ static int rockchip_sfc_read_fifo(struct rockchip_sfc *sfc, u8 *buf, int len)
/* read the rest non word aligned bytes */ if (bytes) { - rx_level = rockchip_sfc_wait_fifo_ready(sfc, SFC_CMD_DIR_RD, 1000); + rx_level = rockchip_sfc_wait_rxfifo_ready(sfc, 1000); if (rx_level < 0) return rx_level; tmp = readl(sfc->regbase + SFC_DATA); @@ -534,19 +539,17 @@ static int rockchip_sfc_xfer_data_dma(struct rockchip_sfc *sfc,
static int rockchip_sfc_xfer_done(struct rockchip_sfc *sfc, u32 timeout_us) { - unsigned long tbase = get_timer(0); int ret = 0; - u32 timeout = timeout_us; - - while (readl(sfc->regbase + SFC_SR) & SFC_SR_IS_BUSY) { - if (get_timer(tbase) > timeout) { - printf("wait sfc idle timeout\n"); - rockchip_sfc_reset(sfc); + u32 status;
- return -ETIMEDOUT; - } + ret = readl_poll_timeout(sfc->regbase + SFC_SR, status, + !(status & SFC_SR_IS_BUSY), + timeout_us); + if (ret) { + dev_err(sfc->dev, "wait sfc idle timeout\n"); + rockchip_sfc_reset(sfc);
- udelay(1); + ret = -EIO; }
return ret;