[PATCH v3 2/2] spi: rockchip_sfc: Using read_poll

Kever Yang kever.yang at rock-chips.com
Sat Oct 9 17:04:48 CEST 2021


On 2021/9/17 下午9:14, Jon Lin wrote:
> Using read_poll logic.
>
> Tested-by: Chris Morgan <macromorgan at hotmail.com>
> Signed-off-by: Jon Lin <jon.lin at rock-chips.com>

Reviewed-by: Kever Yang <kever.yang at 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;




More information about the U-Boot mailing list