On 2021/9/17 下午9:14, Jon Lin wrote:
Using read_poll logic.

Tested-by: Chris Morgan <macromor...@hotmail.com>
Signed-off-by: Jon Lin <jon....@rock-chips.com>

Reviewed-by: Kever Yang <kever.y...@rock-chips.com>


Thanks,
- Kever
---

(no changes since v2)

Changes in v2:
- Fix assigned but never used return error codes

  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 94222df5ce..e098addddc 100644
--- a/drivers/spi/rockchip_sfc.c
+++ b/drivers/spi/rockchip_sfc.c
@@ -285,33 +285,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");
+
+               return -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");
+
+               return -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)
@@ -429,7 +434,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);
@@ -440,7 +445,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);
@@ -461,7 +466,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);
@@ -472,7 +477,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);
@@ -533,19 +538,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;


Reply via email to